Generating (inline CSS) HTML templates from Flask not working - python

For a personal website I would like to randomly select a background picture (out of 4) for my starting page using flask. When try to create a HTML template (with inline CSS for formatting), the resulting HTML does not display the picture chosen at random.
So far I have tried to use url_for(), as I thought the problem might be that jinja cannot find the files, but this does not resolve my problem.
I also looked at the whitespace and delimiters, which seem to be correct in my mind.
The code from my app.py:
flask import Flask, render_template
import random
app = Flask(__name__)
#app.route('/')
def index():
intt = random.randint(1, 4)
random_number = ("../Images/artwork/{}.jpeg".format(intt))
return render_template('index.html', random_number=random_number)
The code in my HTML file:
<!DOCTYPE html>
<html>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
#font-face {
font-family: "Pretoria Gross";
src: url("../Fonts/Pretoria.ttf");
}
ge {
color: Yellow;
font-family: Pretoria Gross;
font-size:70px;
text-align: center;
display:inline-block;
position:relative;
width:100%;
background: url('../Images/artwork/{{random_number}}.jpeg') no-repeat top center;
background-position: center top;
background-size: 25% auto;
}
</style>
<a href="about.html">
<ge>Website<br/>Title<br/>here</ge>
</a>
The resulting HTML does not render the CSS. Where do I go wrong?
Many Thanks

random_number is already storing the desired path. Change url in the css:
background: url('{{random_number}}') no-repeat top center;
Or, you can simply pass intt to the template, and keep the original css templating:
return render_template('index.html', random_number=intt)

Related

Passing variable from flask to html adds "

I'm trying to pass a variable from flask to my html code. I'm adding it as a url for a button, so a user can follow it. My problem is that the buttons don't work an when inspecting the website I see that the variables have had " added to them. Removing this makes the buttons work.
HTML code:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Testing buttons">
<meta name="keywords" content="Test">
<style>
h1 {
font-family: Arial, sans-serif;
color: #2f2d2d;
text-align: Center;
}
p {
font-family: Arial, sans-serif;
font-size: 14px;
text-align: Center;
color: #2f2d2d;
}
</style>
</head>
<body>
<h1>Results</h1>
<p>Click the buttons below to go to your results: </p>
<button onclick={{ value1 }}>
Yandex.com
</body>
</html>
Value1 in my python code:
input1 = (str(""""window.location.href='""")
+ str(img_search_url) + str('''';"'''))
return render_template('results.html', value1=input1)
For testing purposes let img_search_url = https://yandex.com/images/search?cbir_id=1865182%2F7z8tGw017Oxvkl-ZRGX7jA6207&rpt=imageview&lr=123432
Thanks
You need to use the |safe filter as mentioned on other SO answers.
<button onclick={{ value1|safe }}>
This ensures that the auto unescaping is turned off. If you do it on untrusted data, it can easily lead to XSS vulnerabilities though.

How to extract specific html lines (with a flex container) using ironpython?

I am using IronPython 2.7.9.0 on Grasshopper and Rhino to web scrape data from a specific widget on this link: https://vemcount.app/embed/widget/uOCRuLPangWo5fT?locale=en
The code I am using is as follows
import urllib
import os
web = urllib.urlopen(url)
html = web.read()
web.close()
The html output contains all the html code from this link except for the parts I need. When I inspect it on chrome it has a "flex" button next to it such as the following image.
image that summarizes the issue I am facing
Anything that is rooted under the line with a "flex" button does not appear in the scraping result and comes as a blank line.
This is the output html I get:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Central Library - Duhig North & Link</title>
<meta charset="utf-8">
<meta name="google" content="notranslate">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="csrf-token" content="">
<link rel="stylesheet" href="/build/app.css?id=2fefc4f9faa59eebcb4b">
<link rel="stylesheet" href="https://vemcount.app/fonts/hamburg_serial/stylesheet.css">
<style>
#embed, #main {
height: 100vh;
}
.vue-grid-item {
margin-bottom: 0px !important;
}
.powered_by {
position: absolute;
bottom: 0px;
right: 0px;
background-color: rgba(0, 0, 0, 0.18);
color: #fff;
padding: 2px 5px;
font-size: 9px;
}
.powered_by:hover, .powered_by:link, .powered_by:visited {
text-decoration: none;
display: none;
}
.dashboard-widget .relative {
overflow: hidden !important;
}
</style>
<script>
window.App = {"socketAppKey":"eJSkWUHWpwolvjVcT2ZxUJZXnDpxtRljdZl74fKr","socketCluster":null,"socketHost":"websocket.vemcount.com","socketPort":443,"socketSecurePort":443,"socketDisableStats":true,"socketEncrypted":true,"locale":"en","settings":[{"name":"type","value":"{\"count_in\":\"column\"}"},{"name":"period","value":"[\"yesterday\"]"},{"name":"period_step","value":"hour"},{"name":"hide_datalabel","value":"0"},{"name":"currency","value":"AUD"},{"name":"show_days","value":"[0,1,2,3,4,5,6]"},{"name":"show_months","value":"[1,2,3,4,5,6,7,8,9,10,11,12]"},{"name":"show_hours_from","value":"00:00"},{"name":"show_hours_to","value":"23:45"},{"name":"data_heatmap","value":"blue"},{"name":"weather_metrics","value":"0"},{"name":"first_day_of_week","value":"1"},{"name":"time_format24","value":"time_format24"},{"name":"date_time_format","value":"2"},{"name":"number_grouping","value":","},{"name":"number_decimal","value":"."},{"name":"opening_hours_overlap","value":"0"},{"name":"data_output","value":"count_in"}],"sound":null};
</script>
<script src="/build/lang/en.js?v=2022.04.4"></script>
</head>
<body class="bg-transparent">
<main id="main">
<div id="embed" >
<div class="w-full h-full vue-grid-item cssTransforms" style="position: absolute;">
<live-inside :embedded="true" :widget="{"id":81438,"pane_id":4005,"title":"Central Library - Duhig North & Link","description":"Live occupancy \/ Seating capacity","x":0,"y":0,"w":2,"h":1,"bg_color":"red","text_color":"black","type":"live-inside","secret":"uOCRuLPangWo5fT","internal":"VRg4JTIRrtJ7Pwg","embeddable":1,"content":{"target":1100,"bidirectional":true,"target_enable":true,"prettify":false,"target_type":"donut","target_donut_hide_metric":false,"target_donut_target_hide_label":false,"target_visual_inside_text":null,"target_visual_available_text":null,"target_screen_ok_title":null,"target_screen_ok_text":null,"target_screen_ok_color":"#38A169","target_screen_ok_image":-1,"target_screen_warning_title":null,"target_screen_warning_pe</live-inside>
</div>
</div>
</main>
<a title=" Vemco Group A/S " class="powered_by" target="_blank"
href="http://vemcount.com">Powered by
<b>vemcount.com</b>
</a>
<script src="/build/manifest.js?id=7f2e9aa3431c681a4683"></script>
<script src="/build/vendor.js?id=19867aae3b960cda7d79"></script>
<script src="/build/embed.js?id=2ff0173dd78c5c1f99c6"></script>
</body>
</html>
As you can see it is missing some lines, which are the lines that have a flex button next to them. (btw I have shortended the code that is in so I dont reach the 30000 character limit).
I am interested in the number 311 which changes every 2 seconds in the live link and it can be found in the html code between
<span>311</span>
Is there a way I can get this value, as well as any other value, using IronPython?
P.S. I am a noob in actual coding, that's why I might have issues with terminologies, but have a fair background in visual scripting. Your help is much appreciated. Thanks.
Just in case you had the same query or were struggling with dynamic web scraping. You have to use CPython and install a webscraper such as Playwright or BS + Selenium
I used playwright which is far more straightforward and has a very much appreciated inner_html() function which reads straight into the dynamic flex HTML code. Here is the code for reference.
#part of the help to write the script I got from https://stackoverflow.com/questions/64303326/using-playwright-for-python-how-do-i-select-or-find-an-element
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(slow_mo=1000)
page = browser.new_page()
page.goto('https://vemcount.app/embed/widget/uOCRuLPangWo5fT')
central = page.query_selector("p.w-full span");
print({'central': central.inner_html()})
browser.close()
Afterwards I am trying to run the .py script remotely from Grasshopper through a batch file and read the output through a txt or CSV file from within Grasshopper.
If there is a better way I am more than happy to hear your suggestions.
Yours,
A Beginner in Python. :)

Flask, url_for() not linking static file

I'm having trouble linking my static "css" file. When I run the code I only get my basic html and not the css. When I use the html element all of my css code work fine. Here is my code:
h1 {
padding: 60px;
text-align: center;
background: #1abc9c;
color: white;
font-size: 30px;
}
.header {
padding: 60px;
text-align: center;
background: #1abc9c;
color: white;
font-size: 30px;
}
.sidebar {
height: 200px;
width: 150px;
position: sticky;
top: 0px;
float: right;
margin-top: 100px;
padding-top: 40px;
background-color: lightblue;
}
.sidebar div {
padding: 8px;
font-size: 24px;
display: block;
}
.body-text {
margin-right: 150px;
font-size: 18px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="UTF-8">
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<h1>Header</h1>
<div class="sidebar">
<div>Menu Item 1</div>
<div>Menu Item 2</div>
<div>Menu Item 3</div>
</div>
<div class="body-text">
<!-- body content -->
</div>
</body>
</html>
Here is my python code also in case that is causing a problem:
from flask import Flask, render_template, redirect, url_for
app = Flask(__name__)
app.config['ENV'] = 'development'
app.config['DEBUG'] = True
app.config['TESTING'] = True
app.static_folder = 'static'
#app.route('/')
def index():
return render_template('base.html')
#app.route('/<name>')
def user(name):
return f"Hello {name}!"
#app.route('/admin')
def admin():
return redirect(url_for('index', name='Admin'))
if __name__ == '__main__':
app.run()
Thanks for any help. Sorry if the code is messy, I'm a rookie :).
In addition to the answer given above, this might also occur sometimes if your browser has already cached the CSS file. You can force your browser to refresh the contents using Ctrl+f5 on your keyboard each time you add new code in your style.css file.
This may be an issue with the structure of your application. Consider this structure:
project_folder
| --- app/
| --- templates/
| --- index.html
| --- static/
| --- style.css
The templates sub-folder should be at the same location as the static sub-folder. Your link should work just with this structure.
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css') }}">

Flask static css file

I'm working on how to add value from flask into static/css file
Here's my code from static/style.css:
.color1 {
background-color: {{pickcolor}};
width: 30px;
height: 30px;
}
.color2 {
background-color: {{pickcolor}};
width: 30px;
height: 30px;
}
so the problem i got is underline error property value expectedcss(css-propertyvalueexpected)
BUT when I use internal css in html file
<style>
.color1 {
background-color: {{pickcolor}};
width: 30px;
height: 30px;
}
.color2 {
background-color: {{pickcolor}};
width: 30px;
height: 30px;
}
</style>
There is no underline problem with my {{pickcolor}}
Your style.css file is probably not templated. I do not know about your exact project config but static files are usually not templated in general.
If you want to template your CSS file, first move it to the templates folder (usually templates), you will then have to create a view for it and use the URL of that view instead of a link to a static file. e.g.
from flask import make_response, render_template
#app.route('/style.css')
def style():
pickcolor = ... # whatever
# we explicitly create the response because we need to edit its headers
response = make_response(render_template('style.css', pickcolor=pickcolor))
# required to make the browser know it is CSS
response['Content-type'] = 'text/css'
return response
Then, in your HTML template
<html>
<head>
<link rel="stylesheet" type="text/css" href="{{ url_for('style') }}">
</head>
<!-- ... -->
</html>

What is preventing me from being able to use a CSS stylesheet in the web.py framework?

I am working through Learn Python The Hard Way, and am currently working through exercise 51. In it, the student is asked to try building out some basic web applications using the web.py framework. The first study drill is to improve the quality of the HTML layouts so that the applications are built on well-formatted pages. I am looking to make a template layout that applies to all pages in the application, and leverages a CSS stylesheet to provide the formatting. I would like for the CSS formatting to be external, rather than within the HTML file. For some reason, no matter how I format the path to 'main_layout.css' I cannot get the formatting changes to take effect. I have tried the path with a leading '/' and without the leading '/'. I have tried moving the CSS file into another folder (the root folder, and the templates folder). I tried emptying my browser cache in case that was causing in issue. I tried accessing the 'static' directory and the 'main_layout.css' file itself directly through my browser, which I was able to do in both cases--the files is in there, but I can't get it to accept the formatting markup from 'main_layout.css'. I googled this issue, checked the google group for web.py, and searched stackoverflow--in all cases, the answers were related to the path to the css file, which I believe I have fully explored and attempted to fix to no avail.I have tried all suggestions I could find on the web, and I am stumped. My code is as follows:
/bin
app.py
/ex51
/static
main_layout.css
/templates
hello_form.html
index.html
layout.html
/tests
app.py is written as follows:
import web
urls = (
'/hello', 'Index'
)
app = web.application(urls, globals())
render = web.template.render('templates/', base="layout")
class Index(object):
def GET(self):
return render.hello_form()
def POST(self):
form = web.input(name="Nobody", greet="Hello")
greeting = "%s, %s" % (form.greet, form.name)
return render.index(greeting = greeting)
if __name__ == "__main__":
app.run()
index.html written as follows:
$def with (greeting)
$if greeting:
I just wanted to say <em style="color: green; font-size: 2em;">$greeting</em>
$else:
<em>Hello</em>, world!
hello_form.html written as follows:
<h1>Fill out this form</h1>
<form action="/hello" method="POST">
A Greeting: <input type="text" name="greet">
<br/>
Your Name: <input type="text" name="name">
<br/>
<input type="submit">
</form>
main_layout.css written as follows:
html, body {
height: 100%;
}
.container {
width:800px;
}
.container #body_container {
margin: 10px auto;
padding-bottom: 50px;
min-height: 100%;
text-align: center;
overflow: auto;
}
.container #footer_container {
margin-top: -50px;
height: 50px;
}
and layout.html:
$def with (content)
<html>
<head>
<link rel="stylesheet" type="text/css" href="/static/main_layout.css" />
<title>This is My Page</title>
</head>
<body>
<div class="container" id="body_container">
$:content
</div>
<div class="container" id="footer_container">
Hello World
</div>
</body>
</html>
Thanks in advance for your help.
Edit: One additional bit of information--I am running this script from the PowerShell of my Windows 7 PC, and accessing it at http://localhost:8080/hello through Google Chrome.
You are commenting out the CSS file using a octothorp (#) which is incorrect for a CSS document (but correct for Python, which is where the confusion is). Use /* to comment out your code in a CSS document. Like this:
.container /*body_container*/ {
margin: 10px auto;
padding-bottom: 50px;
min-height: 100%;
text-align: center;
overflow: auto;
}

Categories