Output all variables into Mako template - python

I don't have an easy access to the code, I'm working only with a Mako template, and I would like to know all the values that were made available to the template, which I can use.
Is there a way to add something in the template, so that the output result would contain all the variables (recursively)?

You're looking for the context object. After a minute or two of play:
${context.keys()} # list of direct variable names
${context.__dict__} # probably more along what you're looking for.
The entire section on the Mako Runtime environment is probably worth reading, especially the part 'All the built in names.' You may find the other post I just made relevant:
Mako how to check if variable exists or not.

Lets try this I think this must help:
${globals()}

Related

Write custom translation allocation in Pyramid

Pyramid uses gettext *.po files for translations, a very good and stable way to internationalize an application. It's one disadvantage is it cannot be changed from the app itself. I need some way to give a normal user the ability to change the translations on his own. Django allows changes in the file directly and after the change it restarts the whole app. I do not have that freedom, because the changes will be quite frequent.
Since I could not find any package that will help me with the task, I decided to override the Localizer. My idea is based on using a Translation Domain like Zope projects use and make Localizer search for registered domain, and if not found, back off to default translation strategy.
The problem is that I could not find a good way to place a custom translation solution into the Localizer itself. All I could think of is to reimplement the get_localizer method and rewrite the whole Localizer. But there are several things, that need to be copypasted here, such as interpolation of mappings and other tweeks related to translation strings.
I don't know how much things you have in there but I did something alike a while ago.. Will have to do it once again. The implementation is pretty simple...
If you can be sure that all calls will be handled trough _() or something alike. You can provide your own function. It will look something like it.
def _(val):
val = db.translations.find({key: id, locale: request.locale_name})
if val:
return val['value']
else:
return real_gettext(val)
this is pretty simple... then you need to have something that will dump the database into the file...
But I guess overriding the localizer makes more sense.. I did it a long time ago and overiding the function was easier than searching in the code.
The plus side of Localiser is that it will work everywhere. Monkey patch is pretty cool but it's also pretty ugly. If I had to do it again, I'd provide my own localizer that will load from a database first and then display it's own value. The reason behind database is that if someone closes the server and the file hasn't been modified you won't see the results.
If the DB is more than needed, then Localize is good enough and you can update the file on every update. If the server will get restarted it will load the new files... You'll have to compile the catalog first.

Using column_validators in pycassa

I'm trying to setup some column_validators in pycassa but having troubles in doing so with some kind of supercolum setup: I don't seem to be able to set a validator for a column contained in a supercolumn. I'm trying something like
cf.column_validators['supercolumn_name']['column_name'] = types.FloatType()
which doesn't work because the second dictionary isn't initialized yet, trying to set it to something like
cf.column_validators['supercolumn_name'] = {}
doesn't work either... So any example on how to handle this are appreciated, as the official pycassa doc doesn't show any more detailled information on this.
Furthermore these validators don't seem to be persistent, so is there any possibility on setting them persistently?
EDIT: After looking at pycassa's source I found out, that for the validators you do not have to specify the supercolumn the column is contained in, so
cf.column_validators['column_name'] = types.FloatType()
should do the trick! Still the question remains if the validators can be made persistent somehow?
You probably don't want to be modifying column_validators directly. Those are set automatically based on the column_metadata properties of the column family. You can use the 'alter_column' command in pycassa to modify the column family schema in Cassandra. Then column_validators will be set correctly permanently.
http://pycassa.github.com/pycassa/api/pycassa/system_manager.html#pycassa.system_manager.SystemManager.alter_column

How can you define a persistent variable in Django

I have a Django project, and what I would like to do is be able to create a reference to a variable defined in urls.py that is kept for the duration of the process.
I've tried an approach using global vars - but for whatever reason, the value of the variable in urls.py is the initial value - even if I change it somewhere else. I've followed the concepts as explained here, but just doesn't work.
However, when I try such a scenario outside of Django, it works as expected.
I think I'm missing a trick (or two) with Django - it's great, I'm new to it, and I think I'm going down the wrong path. Should I be using the caching stuff included with Django to store the variable, or is that even more off track?
Many thanks for any pointers.
I agree with S.Lott's comment, your question is a little vague. I think you're trying to reference some variable defined in urls? You know you can import urls.py into any other python script as long as it's on your PYTHONPATH. Assuming you're talking about a Django view when you say a "process", you could import a URL directly into a view function:
def foo_view(request):
from bar_app.urls import BAR_URL_PATTERN
Please give us more information on your specific use case, and I'll amend my answer to give you a better response.
Good Luck! I hope you're enjoying your first foray into the wonderful world of Django!

Better error reporting mako

Is there a way to add tempate string which contains error to mako`s error trace?
I don't think you're likely to find such a thing. Like all the other fast python template engines, Mako achieves its speed by compiling your template into python code and then executing it. An exception will divert execution out of your template's code, so by the time one is raised, that template will have no way of displaying it (or doing anything else for that matter).
As an alternative, I suggest putting your template rendering code inside a try block, and rendering any caught exceptions with a separate template used specifically for that purpose.
I was looking for another error I have and found this. I though it would be nice if you still ever need this, you can achieve it by setting mako.strict_undefined = True. I am using mako-0.6.2 so it may not been possible in the version back in 2010.

Syntax error whenever I put Python code inside a Django template

I'm trying to do the following in my Django template:
{% for embed in embeds %}
{% embed2 = embed.replace("<", "<") %}
{{embed2}}<br />
{% endfor %}
However, I always get an invalid block or some syntax error when I do anything like that (by that I mean {% %} code inside a loop). Python doesn't have {} to signify "scope" so I think this might be my problem? Am I formatting my code wrong?
Edit: the exact error is: Invalid block tag: 'embed2'
Edit2: Since someone said what I'm doing is not supported by Django templates, I rewrote the code, putting the logic in the view. I now have:
embed_list = []
for embed in embeds:
embed_list[len(embed_list):] = [embed.replace("<", "<")] #this is line 35
return render_to_response("scanvideos.html", {
"embed_list" :embed_list
})
However, I now get an error: 'NoneType' object is not callable" on line 35.
I am quite sure that Django templates does not support that.
For your replace operation I would look into different filters.
You really should try to keep as much logic as you can in your views and not in the templates.
Django's template language is deliberately hobbled. When used by non-programming designers, this is definitely a Good Thing, but there are times when you need to do a little programming. (No, I don't want to argue about that. This has come up several times on django-users and django-dev.)
Two ways to accomplish what you were trying:
Use a different template engine. See Jinja2 for a good example that is fully explained for integrating with Django.
Use a template tag that permits you to do Python expressions. See limodou's Expr tag.
I have used the expr tag in several places and it has made life much easier. My next major Django site will use jinja2.
I don't see why you'd get "NoneType object is not callable". That should mean that somewhere on the line is an expression like "foo(...)", and it means foo is None.
BTW: You are trying to extend the embed_list, and it's easier to do it like this:
embed_list = []
for embed in embeds:
embed_list.append(embed.replace("<", "<")) #this is line 35
return render_to_response("scanvideos.html", {"embed_list":embed_list})
and even easier to use a list comprehension:
embed_list = [embed.replace("<", "<") for embed in embeds]
Instead of using a slice assignment to grow a list
embed_list[len(embed_list):] = [foo]
you should probably just do
embed_list.append(foo)
But really you should try unescaping html with a library function rather than doing it yourself.
That NoneType error sounds like embed.replace is None at some point, which only makes sense if your list is not a list of strings - you might want to double-check that with some asserts or something similar.
Django templates use their own syntax, not like Kid or Genshi.
You have to roll your own Custom Template Tag.
I guess the main reason is enforcing good practice. In my case, I've already a hard time explaining those special templates tags to the designer on our team. If it was plain Python I'm pretty sure we wouldn't have chosen Django at all. I think there's also a performance issue, Django templates benchmarks are fast, while last time I checked genshi was much slower. I don't know if it's due to freely embedded Python, though.
You either need to review your approach and write your own custom templates (more or less synonyms to "helpers" in Ruby on Rails), or try another template engine.
For your edit, there's a better syntax in Python:
embed_list.append(embed.replace("<", "<"))
I don't know if it'll fix your error, but at least it's less JavaScriptesque ;-)
Edit 2: Django automatically escapes all variables. You can enforce raw HTML with |safe filter : {{embed|safe}}.
You'd better take some time reading the documentation, which is really great and useful.

Categories