As the title suggests, I'm using Google App Engine and Django.
I have quite a bit of identical code across my templates and would like to reduce this by including template files. So, in my main application directory I have the python handler file, the main template, and the template I want to include in my main template.
I would have thought that including {% include "fileToInclude.html" %} would work on its own but that simply doesn't include anything. I assume I have to set something up, maybe using TEMPLATE_DIRS, but can't figure it out on my own.
EDIT:
I've tried:
TEMPLATE_DIRS = (os.path.join(os.path.dirname(__file__), 'templates'), )
But to no avail. I'll try some other possibilities too.
First, you should consider using template inheritance rather than the include tag, which is often appropriate but sometimes far inferior to template inheritance.
Unfortunately, I have no experience with App Engine, but from my experience with regular Django, I can tell you that you need to set your TEMPLATE_DIRS list to include the folder from which you want to include a template, as you indicated.
I found that it works "out of the box" if I don't load Templates first and render them with a Context object. Instead, I use the standard method shown in the AppEngine tutorial.
I am having the same problem and tracked it down into the ext.webapp package. In template.py, you'll find this comment on line 33:
Django uses a global setting for the directory in which it looks for templates.
This is not natural in the context of the webapp module, so our load method
takes in a complete template path, and we set these settings on the fly
automatically. Because we have to set and use a global setting on every
method call, this module is not thread safe, though that is not an issue
for applications.
See line 92 in the same file. You can see the template dirs being squashed:
directory, file_name = os.path.split(abspath)
new_settings = {
'TEMPLATE_DIRS': (directory,),
'TEMPLATE_DEBUG': debug,
'DEBUG': debug,
}
UPDATE: Here is the workaround which worked for me - http://groups.google.com/group/google-appengine/browse_thread/thread/c3e0e4c47e4f3680/262b517a723454b6?lnk=gst&q=template_dirs#262b517a723454b6
I've done the following to get around using includes:
def render(file, map={}):
return template.render(
os.path.join(os.path.dirname(__file__), '../templates', file), map)
table = render("table.html", {"headers": headers, "rows": rows})
final = render("final.html", {"table": table})
self.response.out.write(final)
Related
I realise this question as been asked before (What's the best practice using a settings file in Python?) but seeing as this was asked 7 years ago, I feel it is valid to discuss again seeing as how technologies have evolved.
I have a python project that requires different configurations to be used based on the value of an environment variable. Since making use of the environment variable to choose a config file is simple enough, my question is as follows:
What format is seen as the best practice in the software industry for setting up a configuration file in python, when multiple configurations are needed based on the environment?
I realise that python comes with a ConfigParser module but I was wondering if it might be better to use a format such as YAML or JSON because of there raise in popularity due to their ease of use across languages. Which format is seen as easier to maintain when you have multiple configurations?
If you really want to use an environment-based YAML configuration, you could do so like this:
config.py
import yaml
import os
config = None
filename = getenv('env', 'default').lower()
script_dir = os.path.dirname(__file__)
abs_file_path = os.path.join(script_dir, filename)
with open(abs_file_path, 'r') as stream:
try:
config = yaml.load(stream)
except yaml.YAMLError as exc:
print(exc)
I think looking at the standard configuration for a Python Django settings module is a good example of this, since the Python Django web framework is extremely popular for commercial projects and therefore is representative of the software industry.
It doesn't get too fancy with JSON or YAML config files - It simply uses a python module called settings.py that can be imported into any other module that needs to access the settings. Environment variable based settings are also defined there. Here is a link to an example settings.py file for Django on Github:
https://github.com/deis/example-python-django/blob/master/helloworld/settings.py
This is really late to the party, but this is what I use and I'm pleased with it (if you're open to a pure Python solution). I like it because my configurations can be set automatically based on where this is deployed using environment variables. I haven't been using this that long so if someone sees an issue, I'm all ears.
Structure:
|--settings
|--__init__.py
|--config.py
config.py
class Common(object):
XYZ_API_KEY = 'AJSKDF234328942FJKDJ32'
XYZ_API_SECRET = 'KDJFKJ234df234fFW3424##ewrFEWF'
class Local(Common):
DB_URI = 'local/db/uri'
DEBUG = True
class Production(Common):
DB_URI = 'remote/db/uri'
DEBUG = False
class Staging(Production):
DEBUG = True
__init__.py
from settings.config import Local, Production, Staging
import os
config_space = os.getenv('CONFIG_SPACE', None)
if config_space:
if config_space == 'LOCAL':
auto_config = Local
elif config_space == 'STAGING':
auto_config = Staging
elif config_space == 'PRODUCTION':
auto_config = Production
else:
auto_config = None
raise EnvironmentError(f'CONFIG_SPACE is unexpected value: {config_space}')
else:
raise EnvironmentError('CONFIG_SPACE environment variable is not set!')
If my environment variable is set in each place where my app exists, I can bring this into my modules as needed:
from settings import auto_config as cfg
That really depends on your requirements, rather than the format's popularity. For instance, if you just need simple key-value pairs, an INI file would be more than enough. As soon as you need complex structures (e.g., arrays or dictionaries), I'd go for JSON or YAML. JSON simply stores data (it's more intended for automated data flow between systems), while YAML is better for human-generated (or maintained, or read) files, as it has comments, you can reference values elsewhere in the file... And on top of that, if you want robustness, flexibility, and means to check the correct structure of the file (but don't care much about the manual edition of the data), I'd go for XML.
I recommend giving trapdoor a try for turn-key configuration (disclaimer: I'm the author of trapdoor).
I also like to take advantage of the fact that you do not have to compile Python source and use plain Python files for configuration. But in the real world you may have multiple environments, each requires a different configuration, and you may also want to read some (mostly sensitive) information from env vars or files that are not in source control (to prevent committing those by mistake).
That's why I wrote this library: https://github.com/davidohana/kofiko,
which let you use plain Python files for configuration, but is also able to override those config settings from .ini or env-vars, and also support customization for different environments.
Blog post about it: https://medium.com/swlh/code-first-configuration-approach-for-python-f975469433b9
I am trying to create redirects using web2py from effectively the default index page (or just the route of the domain/package).
Some keywords (such as 'about', stored in a list) wouldn't redirect. However, all not in that list would redirect.
The desired behaviour is:
https://startbean.com/about -> No redirect
https://startbean.com/myc -> https://startbean.com/company/myc
The default page that is shown at startbean.com is from the package 'default' and is called 'index'. If the redirect was as in the below, it would be easy:
https://startbean.com/default/about -> No redirect
https://startbean.com/default/index/myc -> https://startbean.com/default/company/myc
because the myc is a URL argument. But when it is from the root, Web2Py tries to open a package called 'myc' and then finds no page (index or controller function) so errors.
What is the best way of handling this? I was trying with routes.py, but couldn't figure out a way to do this (am pretty sure it is not supported). I thought about a redirect for the token after / to a page called /default/redirect/<token> which would then decide about the redirect, but there's no way to stop the infinite loop. Another possible solution was a tweak to the nginx config so redirect when there is one token after the /, but again I think this causes a problem with the about.
Maybe there is a catch-all function for controllers that I haven't found? I've gone through the web2py book and found nothing - any ideas very welcome!
Thanks,
Sam
You can use the parameter-based rewrite system. In routes.py include:
routers = dict(
BASE=dict(
default_application='yourapp',
default_controller='default',
default_function='company',
functions=['index', 'company', 'user', 'download', 'call']
),
)
Note, functions should be a list of all functions in the default.py controller.
If you go to /some_token, it will route to /yourapp/default/company/some_token, unless some_token is "yourapp", "default", "company", or any of the functions in the functions list (in which case, it will assume you are actually requesting the "yourapp" app, the "default" controller, or the particular function from the controller).
Note, if you simply go to the root URL (i.e., http://yourdomain.com/), it will route to /yourapp/default/company/, with no URL arg, so you should be prepared for that case.
So I found the solution (sorry for the delay in posting):
In the routes.py at the route of web2py directory, I added a rule in routes_in, so that this was in the my file:
routes_in = (
('/(?!about)$token', '/company/$token'),
)
to manage the default app (removing the application name and the default package name from the URL), I did this (not necessary for the redirects to work):
routers = dict(
BASE = dict(default_application='startbean'),
)
And it all worked :)
Here it says: "The special entry name self stands for the document containing the toctree directive. This is useful if you want to generate a “sitemap” from the toctree." And I have been looking at this thred - Using self to create a sitemap with toctree in sphinx seem broken?. I can't seem to get this to work.
Is there anywhere that has a detailed example of a sitemap being generated by sphinx I can look at?
I ended up using the sitemap generator in this theme with my own.
https://github.com/guzzle/guzzle_sphinx_theme
# Import guzzle theme https://github.com/guzzle/guzzle_sphinx_theme
# Not actually using the theme but intead using the
# sitemap functionality and overriding the theme/templates in source/
html_translator_class = 'guzzle_sphinx_theme.HTMLTranslator'
html_theme_path = guzzle_sphinx_theme.html_theme_path()
html_theme = 'guzzle_sphinx_theme'
extensions.append("guzzle_sphinx_theme")
html_theme_options = {
"base_url": "YOURSITEURL"
}
I'm overriding everything in my source directory I'm not using any other parts of the theme other than the sitemap generator. Pretty sloppy solution but it worked for me.
I know the question is four years old, so at that time maybe this plugin was not available. I just tried the sphinx-sitemap plugin, and it worked for me.
The integration is easy:
pip install sphinx-sitemap
and then in your config.py set:
extensions = ['sphinx_sitemap']
html_baseurl = 'https://my-site.com/docs/'
And then generate the site normally. A sitemap.xml will apear at the base of your project. They also have some advanced functionality such as versioning and multi language (i haven't tried yet).
i'm working with bottle framework and i found this problem.
When i used static path everything works fine, but when i used dynamic routing the path for .css and .js change and give not file found error.
I have this method:
#get('/mod_user/<id_user>')
def mod_user(id_user):
user = driver.get_user_by_id(id_user)
return template('moduser', user=user)
And i have this one for static files, which works fine for path like '/contact', etc:
#route('/static/:path#.+#', name='static')
def static(path):
return static_file(path, root='static')
the problem come beacuse add /mod_user to the path for search static:
http://10.141.0.63:8080/mod_user/static/css/formularioadd.css
I tried changing path for static in several ways and nothing works.
Some idea?
thank you all
You have no route that matches /mod_user/static.
(Also, you're needlessly using a regex.)
Have you tried something like this?
#route('/mod_user/static/<path:path>')
def static(path):
...
I'm using cherrypy with Mako as a template engine.
I want Mako to lookup different directories based on what app is being requested.
I.e.
I have three 'apps': Site, Admin and Install.
They all have their own template folder, structure looking something like:
/template
/template/site
/template/admin
/template/install
/template/system
/system contains some system wide templates, like 404 pages, etc.
I'm using Twiseless as a reference whilst trying to get to grips with cherrypy / mako, but I'm stuck with how to do this.
Read on for a brief overview of how I've tried to do this, but a warning: I think I'm going about this completely the wrong way! :) So, if you have any ideas/pointers, it might be a good idea to save yourself the trouble of reading any further than this.
In my main file, server.py, I do something like:
from libs.plugins.template import MakoTemplatePlugin
engine = cherrypy.engine
makoTemplate = MakoTemplatePlugin(engine, self.base_dir)
setTemplateDirs(makoTemplate, self.template_path)
MakoTemplatePlugin is a slightly modified version of the plugin by the same name found in Twiseless, linked above.
What this code does is set the TemplateLookup to use the default template directories from my global config file. i.e.
/template
/template/system
Then, each time an app is loaded, I call a function (setTemplateDirs) to update the directories where Mako searches.
I thought this would work, but it doesn't. Initially I made the error of creating a new instance of MakoTemplatePlugin for each app. This just resulted in them all being called on each page load, starting with the first one instantiated, containing just the basic, non-app specific directories.
As this was called first, it was triggering a 404 error, as it was searching in the wrong folders.
I instead made sure to pass a reference to the MakeTemplatePlugin to all of my apps. I thought if I ran setTemplateDirs each time each app is called, this would solve the problem... but it doesn't.
I don't know where to put the function so it will run every time a page is requested...
e.g.
# /apps/site/app.py
import somemodule.setTemplateDirs
class Site(object, params):
def __init__(self):
self.params = params
self.makoTemplate = params['makoTemplate']
self.base_path = params['base_path']
setTemplateDirs(self.makoTemplate, self.base_path, '', '/')
#cherrypy.expose
#cherrypy.tools.render(template='index.html')
def index(self):
pass
This obviously just works when the application is first loaded... I tried moving the update function call into a seperate method update and tried calling that for each page, e.g:
#cherrypy.exposed
#cherrypy.tools.render(template='index.html')
#update
def index(self):
pass
But this just gives me config related errors.
Rather than to continue to mess about with this, there must be an easier way.
How would you do it?
Thanks a lot,
Tom
I got this working. Thanks to stephan for providing the link to the mako tool example: http://tools.cherrypy.org/wiki/Mako.
I just modified that slightly to get it working.
If anyone's wondering, the basis of it is that you define tools.mako.directories in your global config, you can then override that in individual app config files.
e.g.
server.conf
...
tools.mako.directories: ['', 'system']
...
site.conf
...
tools.mako.directories: ['site', 'system']
...
I did some extra work to translate the relative URIs to absolute paths, but the crux of it is explained above.