How to make multiple web2py apps use the same layout.html? - python

I have three applications, but I want them to use the same layout.html and css. Is there any way to achieve this?
EDIT:
I put the static folder and layout.html etc in /common/ under the web2py root.
Here's what I did in the model:
import os
global web2py_path
web2py_path = os.environ.get('web2py_path', os.getcwd())
session.layout_path = web2py_path + '/common/layout.html'
print 'session.layout_path = ' + session.layout_path
Then in the views:
{{extend session.layout_path}}
EDIT 2:
Regarding the comment below about compiling, I decided to put the 'common' folder into '/applications/' and place the static folder (css, images) inside the 'common' folder like a regular app. I then placed the layout.html into the root of 'common'. Then from another app's view, I used:
{{extend '../../common/layout.html'}}
Which referenced the layout.html from the common app. This layout.html file then referenced the files in the static folder within 'common' using:
{{=URL('common','static','css','style.css')}}
As you would for a regular application.

in the root of your web2py folder create a new folder called 'templates'
/web2py/templates
put your layout.html there.
now in your views do:
{{extend 'path/to/web2py/templates/layout.html'}}

Related

Unable to find flask template [duplicate]

I am trying to render the file home.html. The file exists in my project, but I keep getting jinja2.exceptions.TemplateNotFound: home.html when I try to render it. Why can't Flask find my template?
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def home():
return render_template('home.html')
/myproject
app.py
home.html
You must create your template files in the correct location; in the templates subdirectory next to the python module (== the module where you create your Flask app).
The error indicates that there is no home.html file in the templates/ directory. Make sure you created that directory in the same directory as your python module, and that you did in fact put a home.html file in that subdirectory. If your app is a package, the templates folder should be created inside the package.
myproject/
app.py
templates/
home.html
myproject/
mypackage/
__init__.py
templates/
home.html
Alternatively, if you named your templates folder something other than templates and don't want to rename it to the default, you can tell Flask to use that other directory.
app = Flask(__name__, template_folder='template') # still relative to module
You can ask Flask to explain how it tried to find a given template, by setting the EXPLAIN_TEMPLATE_LOADING option to True. For every template loaded, you'll get a report logged to the Flask app.logger, at level INFO.
This is what it looks like when a search is successful; in this example the foo/bar.html template extends the base.html template, so there are two searches:
[2019-06-15 16:03:39,197] INFO in debughelpers: Locating template "foo/bar.html":
1: trying loader of application "flaskpackagename"
class: jinja2.loaders.FileSystemLoader
encoding: 'utf-8'
followlinks: False
searchpath:
- /.../project/flaskpackagename/templates
-> found ('/.../project/flaskpackagename/templates/foo/bar.html')
[2019-06-15 16:03:39,203] INFO in debughelpers: Locating template "base.html":
1: trying loader of application "flaskpackagename"
class: jinja2.loaders.FileSystemLoader
encoding: 'utf-8'
followlinks: False
searchpath:
- /.../project/flaskpackagename/templates
-> found ('/.../project/flaskpackagename/templates/base.html')
Blueprints can register their own template directories too, but this is not a requirement if you are using blueprints to make it easier to split a larger project across logical units. The main Flask app template directory is always searched first even when using additional paths per blueprint.
I think Flask uses the directory template by default. So your code should be like this
suppose this is your hello.py
from flask import Flask,render_template
app=Flask(__name__,template_folder='template')
#app.route("/")
def home():
return render_template('home.html')
#app.route("/about/")
def about():
return render_template('about.html')
if __name__=="__main__":
app.run(debug=True)
And you work space structure like
project/
hello.py
template/
home.html
about.html
static/
js/
main.js
css/
main.css
also you have create two html files with name of home.html and about.html and put those files in templates folder.
If you must use a customized project directory structure (other than the accepted answer project structure),
we have the option to tell flask to look in the appropriate level of the directory hierarchy.
for example..
app = Flask(__name__, template_folder='../templates')
app = Flask(__name__, template_folder='../templates', static_folder='../static')
Starting with ../ moves one directory backwards and starts there.
Starting with ../../ moves two directories backwards and starts there (and so on...).
Within a sub-directory...
template_folder='templates/some_template'
I don't know why, but I had to use the following folder structure instead. I put "templates" one level up.
project/
app/
hello.py
static/
main.css
templates/
home.html
venv/
This probably indicates a misconfiguration elsewhere, but I couldn't figure out what that was and this worked.
If you run your code from an installed package, make sure template files are present in directory <python root>/lib/site-packages/your-package/templates.
Some details:
In my case I was trying to run examples of project flask_simple_ui and jinja would always say
jinja2.exceptions.TemplateNotFound: form.html
The trick was that sample program would import installed package flask_simple_ui. And ninja being used from inside that package is using as root directory for lookup the package path, in my case ...python/lib/site-packages/flask_simple_ui, instead of os.getcwd() as one would expect.
To my bad luck, setup.py has a bug and doesn't copy any html files, including the missing form.html. Once I fixed setup.py, the problem with TemplateNotFound vanished.
I hope it helps someone.
Check that:
the template file has the right name
the template file is in a subdirectory called templates
the name you pass to render_template is relative to the template directory (index.html would be directly in the templates directory, auth/login.html would be under the auth directory in the templates directory.)
you either do not have a subdirectory with the same name as your app, or the templates directory is inside that subdir.
If that doesn't work, turn on debugging (app.debug = True) which might help figure out what's wrong.
I had the same error turns out the only thing i did wrong was to name my 'templates' folder,'template' without 's'.
After changing that it worked fine,dont know why its a thing but it is.
You need to put all you .html files in the template folder next to your python module. And if there are any images that you are using in your html files then you need put all your files in the folder named static
In the following Structure
project/
hello.py
static/
image.jpg
style.css
templates/
homepage.html
virtual/
filename.json
When render_template() function is used it tries to search for template in the folder called templates and it throws error jinja2.exceptions.TemplateNotFound when :
the file does not exist or
the templates folder does not exist
Create a folder with name templates in the same directory where the python file is located and place the html file created in the templates folder.
Another alternative is to set the root_path which fixes the problem both for templates and static folders.
root_path = Path(sys.executable).parent if getattr(sys, 'frozen', False) else Path(__file__).parent
app = Flask(__name__.split('.')[0], root_path=root_path)
If you render templates directly via Jinja2, then you write:
ENV = jinja2.Environment(loader=jinja2.FileSystemLoader(str(root_path / 'templates')))
template = ENV.get_template(your_template_name)
After lots of work around, I got solution from this post only,
Link to the solution post
Add full path to template_folder parameter
app = Flask(__name__,
template_folder='/home/project/templates/'
)
My problem was that the file I was referencing from inside my home.html was a .j2 instead of a .html, and when I changed it back jinja could read it.
Stupid error but it might help someone.
Another explanation I've figured out for myself
When you create the Flask application, the folder where templates is looked for is the folder of the application according to name you've provided to Flask constructor:
app = Flask(__name__)
The __name__ here is the name of the module where application is running. So the appropriate folder will become the root one for folders search.
projects/
yourproject/
app/
templates/
So if you provide instead some random name the root folder for the search will be current folder.

How to get cherrypy to serve static files from the index and a static directory, with custom paths as well?

I have a directory structure that looks like this:
project/
index/
about.html
index.html
forum.html
profile.html
settings.html
apple-touch-icon.png
static/
main.css
forum.css
main.js
forum.js
load-image.min.js
server.py
metaclass.py
mailing.py
errors.log
I'd like to be able to make cherrypy serve all of these files from index/. However, I also want about.html, index.html, forum.html, profile.html, etc. to be accessible via /about, /, /forum, /profile, etc., so this is not the same as just simple static file serving. Also, I want to have some custom methods, like /login, which needs a GET and POST, and pre-templated user profile pages. How can this be done?
Cherrypy is going to recursively serve the files in the index folder. What you are trying to do has more to do with the url path.
In your server.py you can attach the handler for /about.html to achieve what you want.
#cherrypy.expose
def about_html(self):
return open('/index/about.html')
hope this helps!

Trouble adding Django-Assets / Webassets directory to look for assets.py files

Was looking for a Python package for Django to manage assets, using Sass to compile CSS, and also cache busting, and Django-Assets / Webassets was recommended. Having trouble getting it setup though with my directory structure.
By default it looks for assets.py in each installed app. I want to set it up so that it sits in the same directory as settings.py and compiles app specific assets from each app directory into /static/js and /static/css.
I have django_assets in INSTALLED_APPS. According to the docs it looks like I needed to add this to settings.py:
ASSETS_MODULES = [
'project_dir',
]
Or:
ASSETS_MODULES = [
os.path.join(BASE_DIR, 'project_dir'),
]
Or:
ASSETS_MODULES = [
PROJECT_ROOT
]
At any rate, it just returns No asset bundles were found. If you are defining assets directly within your template, you want to use the --parse-templates option.
Even moving the assets.py into one of the app directories, it is looking in BASE_DIR/scripts which is where I keep my manage.py. Again, changing ASSETS_ROOT doesn't really same to be doing anything.
~/portal-client
project_dir
apps
account
templates
account
login.html
forms.py
urls.py
views.py
home
templates
home
home.html
urls.py
views.py
results
assets.py
settings.py
urls.py
scripts
manage.py
static
templates
base.html
footer.html
title.html
Couple of quick notes, for ASSETS_MODULES, the key word is additional:
django-assets will automatically look for assets.py files in each application, where you can register your bundles. If you want additional modules to be loaded, you can define this setting. It expects a list of importable modules:
i.e., we only use ASSETS_MODULES if we have assets.py files outside of any application. In your case, we will only specify this if project_dir is not an INSTALLED_APP.
Second, when using ASSETS_MODULES, you specify a dotted module path, not a directory. In your case, this would be project_dir.assets only if project_dir is not already part of INSTALLED_APPS.

Where to locate user data in Flask application?

I have a flask application where a user's profile image is stored. I originally stored the images in the static directory like so:
application.py
templates/
static/userdata/user/icon.png
Though I don't think this is a good idea because it is not good practice to modify the static directory in production.
I tried making a new userdata folder at root like so:
application.py
templates/
static/
userdata/user/icon.png
Though when I try to access the file with Jinja and HTML,
<img src="/userdata/user/icon.png">
the image does not show. Why is this?
Thanks, in advance.
Use the url_for function
.html
<img src="{{ url_for('userdata', filename='/user/icon.png')}}">
.py
from flask import send_file
#route('/userdata/<filename:filename>')
def get_user_data_files(filename):
return send_file(app.config['USER_DATA_FOLDER'] + filename)

how to find static files with same path and same name in Django?

Now, I have a Django web site which has two projects. One is root project and another is a app.
The directory structure is below:
--root project
--static
--templates
--index.html
--app
--static
--templates
--index.html
The relative settings in setting.py is below:
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__).decode('utf-8')).replace('\\', '/')
STATICFILES_DIRS = (
os.path.join(PROJECT_ROOT, "static"),
)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
And, when I want to specify a path to "/app/static/templates/index.html", I always get index.html in root.If I change the turn in STATICFILES_FINDERS, I will face the same problem when I want to get index.html in root.
How can I accurately get one of them?
Your directory structure seems strange...
First thing, in case the index.html in the app directory is supposed to be a Django-template, it shouldn't be under the static directory.
Also, you mentioned that you used the path /app/static/templates/index.html, which actually shouldn't work at all.
Usually in Django, the /static/ path will be used to access static resources from all apps' static directories, as well as all directories specified in STATICFILES_DIRS, as if all the content from all those directories is "merged" into one /static/ directory!
So, in your example, the path /static/templates/index.html indeed refers to both the index.html from the root project directory, as well as the index.html from the app-specific static directory, which is why the actual file you get will depend on the order of static files finders specified.
The recommended layout to avoid such collisions would be:
-project root
-static
-global static resources accessible via /static/...
-app
-static
-app
-app-specific static resources accessible via /static/app/...
This is also appropriate for app-template directories:
-app1
-templates
-app1
-index.html (referred from Django view as 'app1/index.html')
-app2
-templates
-app2
-index.html (referred from Django view as 'app2/index.html')
Edit to add info on shared templates:
If you're trying to have a "base-template" that is extended by other apps, I would recommend using the "common-app" approach.
You simply create a new app (named e.g. "common", although you can name it however you want), that contains common templates (and other logic, if you'd like), and have the app-specific templates extend it.
The layout would be:
-app1
-templates
-app1
-index.html
-common
-templates
-common
-base.html
And in index.html you'll have {% extends "common/base.html" %} at the top of the file (read the Django docs on template inheritance if you're unfamiliar with it).
Of course, the common app must be enabled in the Django settings for this to work.

Categories