Bind shorter var names in django template - django

To the risk of being closed as duplicate (I can't really find it...) I have the following question. I am sure it's either under my nose, or not possible, but I prefer to ask.
Is it possible to bind to multiple, shorter variable names in django? I know the existence of with, but with assumes you open a block. I would like to bind three or four, meaning that I would have to open (and close) four with blocks. Feasible, but not very nice.
Example, say I have this in my context: foo.bar.baz.quux1, foo.bar.baz.quux2, foo.bar.baz.quux3. I would like to bind them to quux1, quux2 and quux3 for easier access.

No, there isn't a built-in way. You could do this in the view, or write a shortcut method on foo. Alternatively a custom template tag could do it.

{% with foo.bar.baz.quux3 as quux3 %}

Related

How can I see all variables available inside a Velocity Template?

Is it possible to display all variables available inside a Velocity Template?
Let's say 1 developer pass 2 values to template: $headline and $body. Another developer has to deal with those 2 variables. How would he know names of those variables?
Right now we use 3 solutions:
we simply say what variables are present on templates
we agreed with all developers that all data we pass to template should be included into 1 map ($data)
developer that pass variables to templates has to update template as well and describe all the fields available on it.
I'm looking for way to do this correctly. Right now I'm not really satisfied with all approaches, but 2-nd looks like most preferable.
The short answer is:
$context.keys
The variables and "tools" are accessed by the templates via the velocity "context". If the context tool is available, you can request the list of variables via $context.keys. If not, you need to add the tool ContextTool to the context. How this is done depends on your application.
Although it's technically possible to list all keys in the context, I'm not sure it's also good practice in the situation you describe.

Django: Should I have complex template variable names or complex views

In django, which should I generally prefer, and why?
long template variable names, passing as few "root objects" (e.g. request) as possible:
{% if request.current_page.get_children.0.get_absolute_url %}
or pass a hell lot of different "root objects" and keep the template variable name simple:
{% if first_child_url %}
somewhere in the middle, e.g. passing children
{% if children.0.get_absolute_url %}
or passing first_child
{% if first_child.get_absolute_url %}
the advantage of the first approach is looser coupling, since I won't need to change the view every time I need to use another variable; the advantage of the second approach is that the template is simpler and much cleaner.
If I'm using generic views (or third party views) which does not allow me to add additional context variables (therefore the only way to add context variables is by writing middleware or context processors), would that change anything?
There is no right answer for this, but I can give you something else to consider:
1) Mistyped variable names in a template will fail silently, which is why I normally try to avoid things like
{% if request.current_page.get_children.0.get_absolute_url %}
2) In contrast to that, any issues in a view will immediately raise exceptions and be obvious to debug
first_child_url = request.current_page.get_children[0].get_absolute_url
3) What I sometimes do when the situation calls for it, is add shortcut methods to a model which allows me to call the method from the template but still keeping the complexity on the python side of the equation.
All that said, if you can't add extra context and need to do it using template tags (as mentioned in your comments) I think its best if you go for the complicated template option.
I only use custom template tags when it is the only way to do something, never as a shortcut.
Hope this helps....
If you're the only developer, it's mostly a matter of taste. However, if the one coding the views is not the one writing the templates, it's much easier to cooperate with well-defined "contracts" between view and template.
I tend to think of the view's parameters to a template the same way I think about API interfaces. My website logic can change, but as long as I respect the data structure passed to the template, I don't need to rewrite anything -- and when working in a group, this is of vital importance.

Django templatetag scope forcing me to do extra queries

The problem is that if I call a templatetag into a block
and it fills me a variiable with the usual context[varname]=something,
then if I need that variable into another block, I have to call the
templatetag again. This for me means extra db queries, which is really
something I'm trying to avoid.
This templatetag is called in a base template which is extended by
many other templates, so I can't just change all the views to pass
something to the context, it makes no sense (WET principle?)
Even a context processor would be not good because I don't want to
call it for every page rendered in the site, even the ones not based
on that template.
I was thinking about writing a templatetag which would use the
internal context structures to put the variable in a global context,
but I'd feel too guilty doing it.
How would you solve this problem?
You said, "This templatetag is called in a base template which is extended by many other templates."
The question is: is this tag called from within a named block? If it is then you have a couple of potential problems.
{% block %} pushes a new dict on the Context stack and pops it off when it reaches the matching `{% endblock %}'. This means any context value created while in the block has essentially gone out of scope on block exit.
If this block is overridden by some other template that extends the base template, the value may not be available at all unless you do a {{block.super}}, and even then I'm not certain the value will be available to the template doing the extending.
If the tag is not called from within a {% block %} then the context value should be available to all of the code that follows it, either in the base template, any included templates and (I think) any extending templates.
This is one of those cases where building a set of careful tests will probably save you time and tears.
Alternatively, if you are always accessing this value, you could just put it in a context processor so that its availability is guaranteed.
Update for comments: OK, time to bring in the big guns! One of the most irritating, long-standing bugs in Django templates is that callables (ie. functions) that are top-level context values (as opposed to functions that are dict-values/methods of context values) are not called! This ticket is over 2 years old and takes about 10 lines of code to fix. We have several heavy-weight DB calls that we only want to happen if the template cache has expired. So we a) MonkeyPatched the template _resolve_lookup() code to fix the callable problem, and then b) curry functions to have all of the necessary parameters if needed, because you can't pass params to functions in the template "language".
I think you've accurately described the limitations in this situation. The most maintainable solutions will likely involve some restructuring of your template inheritance chain, though its hard to say without knowing the details. Can you introduce a new template in the inheritance hierarchy, probably somewhere near the top of the pyramid but so it only is inherited by templates that need this data, with a single block that encompasses the entire region within which you need this data? That big block can then be subdivided into smaller blocks that inheriting templates will override. If you call your templatetag at the beginning of that block, all blocks within it (including in inheriting templates) will have access to the data.
Update: I can't say much without seeing your templates, but introducing a new template in the middle of an inheritance chain very rarely involves "changing all the templates," in a sane inheritance structure it often can be done with changes to only one or two other templates. And I think what I am suggesting is actually not a hack, it's just better design. If you need a certain piece of data in certain parts of your site and not other parts, there should be a specific single template you can point to and say "this template represents the logical layer at which this piece of data is introduced, and encompasses the parts of the site where that data is needed."
Are you just trying to keep down the number of database queries or are you looking for a clever solution?
If it's the former, I would definitely go with caching. Would fragment caching work in your case? If not, perhaps you could put the caching in the template tag code (assuming it's not one of Django's own template tags your using)?
Just came across this trick from Liviu, Agile Bear (all credit goes to him)
Instead of doing
context['some_var']='some value'
do
context.dicts[0]['some_var']='some value'
May not be a by-the-book-coding-practice but works well enough

Naming confusion? Is having objects named FlowerGroup and FlowerGroups confusing?

I'm writing a program and I seem to be creating alot of objects where one object will be the singular form and then the collection is the plural form. eg
SalesGroup
SalesGroups
Is this confusing for other programmers to read my code?
should not be confusing, in fact I find it pretty informative and clear; unless you have multiple kinds of collections (lame example: suppose you have an array but also a map of SalesGroup, then SalesGroups would not be the best choice but you'd rather pick SalesGroupArray, SalesGroupMap etc.)
I think that makes perfect sense. Not specifying the type of collection means you're at liberty to change the implementation later, and clients can't rely on a particular implementation.
While it's not confusing, I think it is very easy to miss. If I were doing this, I would use something that stands out more, perhaps SalesGroup and SalesGroupCollection.
seems OK to me. just maintain your coding style throughout all your project.

Replace giant switch statement with what?

I have a code that parses some template files and when it finds a placeholder, it replaces it with a value. Something like:
<html>
<head>
<title>%title%</title>
</head>
<body bgcolor="%color%">
...etc.
In code, the parser finds those, calls this function:
string getContent(const string& name)
{
if (name == "title")
return page->getTitle();
else if (name == "color")
return getBodyColor();
...etc.
}
and then replaces the original placeholder with returned value.
In real case, it is not a dummy web page, and there are many (50+) different placeholders that can occur.
My code is C++, but I guess this problem exists with any language. It's more about algorithms and OO design I guess. Only important thing is that this must be compiled, even if I wanted I couldn't have any dynamic/eval'd code.
I though about implementing Chain of Responsibility pattern, but it doesn't seem it would improve the situation much.
UPDATE: and I'm also concerned about this comment in another thread. Should I care about it?
Use a dictionary that maps tag names to a tag handler.
You want replace conditional with polymorphism. Roughly:
string getContent(const string& name) {
myType obj = factory.getObjForName(name);
obj.doStuff();
}
where doStuff is overloaded.
Have you considered XSLT? It's very well suited to this kind of thing. I developed a content management system that did the exact same thing and found XSLT to be very effective. The parser does a lot of the work for you.
UPDATE: Steven's comment raises an important point- you'll want your templates to be valid XHTML if you decide to go the XSLT route.
Also- I would use a different delimiter for your replacement tokens. Something less likely to occur naturally. I used #!PLACEHOLDER#! in my CMS.
i'll combine 3 ideas:
(from Steven Hugig): use a factory method that gets you a different class for each selector.
(from Neil Butterworth): inside the factory, use a dictionary so you get rid of the big switch(){}.
(mine): add a setup() method to each handler class, that adds itself (or a new class instance) to the dictionary.
explaining a bit:
make an abstract class that has a static dict, and methods to register an instance with a selector string.
on each subclass the setup() method registers itself with the superclass' dict
the factory method is little more than a dictionary read
Rather than parsing, have tried just reading the template into a string and then just performing replaces.
fileContents = fileContents.Replace("%title%", page->getTitle());
fileContents = fileContents.Replace("%color%", getBodyColor());
As "Uncle" Bob Martin mentioned in a previous podacast with Joel and Jeff, pretty much anything you come up with is going to essentially be reproducing the big switch statement.
If you feel better implementing one of the solutions selected above, that's fine. It may make your code prettier, but under the covers, it's essentially equivalent.
The important thing is to ensure that there is only one instance of your big switch statement. Your switch statement or dictionary should determine which class handles this tag, and then subsequent determinations should be handled using polymorphism.