get_absolute_url and reverse outside of templates - html

"...If you need to use something similar to the url template tag in your code, Django provides the following function: reverse()...."
I looked at the docs for get_absolute_url() and reverse, as well as the example given:
a href="{{ object.get_absolute_url }}">{{ object.name }} /a>
What I am not seeing, or understanding, is how are we passing the kwargs (name, self, ID, whatever) to the model method so it knows which one of 100 instances to return the url for, particularly where I need to use it in text, outside the template system?
a href="name_of_object.get_absolute_url ">text name of object
Do I have to put the full name of the object in the href?
How would I use a variable like self or object or modelname instead?
Can I rewrite gau to take kwargs as well as self?
If I do that, can I put the () on the end of gau to take in the kwargs? We can’t do that in the template.
Can I use:
a href="self.get_absolute_url(**kwargs) ">text name of object ?
or
a href="object.get_absolute_url(self, **kwargs) ">text name of
object ?
And if so, do I need to add anything to the definition of gau on my model to make sure those kwargs are passed to return?
Or do I just treat it like a regular outside link, and thus have to hard code it?
Thanks.
--update--
#ChidG: Thanks for such a complete answer, and my apologies for taking so long to get back to you. I'd like to clarify my use case a little, and see if that changes your answer any. If I have ten articles using the same template, each article is still unique, and their links to different urls are not going to be in the same place on each article. So there is no way for me to put a single (or multiple) url tag in the template that will be useful to all ten articles. That's what I meant by using gau / the url tag outside the template. I want to do a simple search and replace that will turn the affected text into links. Otherwise, I'd have to do them one at a time by hand, which I assumed couldn't be the way this has to be done. What am I missing?

When Django's docs say 'outside of the template system', they mean in Python code, in a views.py or models.py (or whatever.py) file. The examples you have given all appear to be HTML (they feature a tags, so it looks like you are talking about HTML).
If it's HTML, then it's not outside the template system, so the Python functions you've mentioned won't work. You need to use the Django template tags.
Regarding this question:
What I am not seeing, or understanding, is how are we passing the kwargs (name, self, ID, whatever) to the model method so it knows which one of 100 instances to return the url for, particularly where I need to use it in text, outside the template system?
{{object.get_absolute_url}} (or object.get_absolute_url() in pure Python) does not require a kwarg, because the get_absolute_url method on the model already knows how to generate the correct URL with whatever kwargs are needed. If it doesn't already know how to do that (because of your specific URL configuration), you can write a custom get_absolute_url method which will enable that.
Whenever you return an HTML file from a Django view (unless you're doing something unconventional), you are using the template system. When you're using the template system, you reference Django context variables using {{ }} and custom tags using {% %}. So to insert a URL into a template, whether it's into an a tag or just into the text, you will use curly brackets and it will be {{ object.get_absolute_url }} or using the url tag itself, {% url 'whatever_url_name' kwarg=value %}
Do I have to put the full name of the object in the href?
You have to put whatever the context variable is that refers to the object in the template context.
How would I use a variable like self or object or modelname instead?
You can use whatever name you like for the context variable. If you're using Django's class based views it will be object by default for a single object view, but you can change it to whatever you like using the context_object_name attribute on the view.
Can I rewrite gau to take kwargs as well as self?
That is unnecessary. get_absolute_url returns a full URL, and all it needs is the model instance. The model instance must be able to find its own url using its own get_absolute_url method without any further kwargs.
Can I use:
The correct syntax is clearly demonstrated in the Django docs for get_absolute_url that you've linked to:
{{ object.name }}

Related

How can I use macros/variables/scripts in articles with Pelican?

I have just started with Pelican. It's awesome, I just can't figure out how to use macros in my articles (and pages). I know I can use Jinja when making my own theme, but I can't seem to be able to use it in articles. I'd like to be able to define a macro/function/template/whatever that I'd put directly in the markdown of the article, possibly with parameters, and it would get expanded when the pages are generated. For example a function to generate an image with a caption of given size and css class that would also be a link directly to the image. I'd like to be able to access these macros from all articles, to be able to reuse them everywhere. Something I'd normally do with PhP.
I could probably use JS to do this, but if I'd like to avoid it and keep everything static if possible. Can this be done?
UPDATE:
I found a pelican plugin that solves this - jinja2content.
OLD SOLUTION:
I found a solution here. You can implement a filter in Python to process all texts in articles/pages like this:
Create a python file filters.py in which you write the filter function process_text to expand my macros (or generally do anything with the article/page text), for example to test the function write something like:
def process_text(input_text):
return "TEST " + input_text
In the Pelican config file (pelicanconfig.py) register this function as a possible filter to be used with Jinja:
import sys
sys.path.append('.')
import filters
JINJA_FILTERS = {'process_text':filters.process_text}
Now you have to edit the templates to apply this filter to article/page texts before adding them to output. In my case I edited two files: themes/themename/templates/article.html and themes/themename/templates/post.html and changed {{ article.content }} to {{ article.content|process_text }} and {{ page.content }} to {{ page.content|process_text }} in them to apply the filter.
Now all texts in articles and pages should be prefixed with "TEST".
The not so convenient thing about this is I have to write my own macro expander, which shouldn't be extremely hard with regular expression in Python, but if there is a nicer way to do this, feel free to post here.

can I customize a html|raw in twig

I am looking to secure some wysiwyg input in a symfony2 application, I have been looking at some flat php plugins like htmlpurifier but just tweaking the twig standard functionality like variable|raw_secure with some own parameters would suffice, if there is a way to create a filter that inherits from the |raw but lets me specify a few tags that are allowed...
Anyone done that?
I need to protect myself from xss, javascripts etc.
“if there is a way to create a filter that inherits from the |raw but lets me specify a few tags that are allowed...”
Twig's filter raw does nothing with parameter passed to it.
You can use Twig's filter escape with specific strategy. If that solution doesn't fit – you can create your own Twig filter.

How to parse the attributes value inside {{}} (curly braces) inside a infobox

Within Infobox at wikipedia some attributes values are also inside curly braces {{}}.. Some time they have lins also.. I need values inside the braces, which is displayed on wikipedia web page.
I read these are templates also.. Can anyone give me some link or guide me how do I deal with it?
Double-curly-braces {{}} define a call to some kind of magic word, variable, parser function, or template.. Help can be found on MediaWiki.org/.../Manual:Magic_words. The little lines that look like | are called pipes and are used to as separators that allow the wikicore parsing engine to define parameters that can be used with the magic word, variable, parser function, or template..
Hopefully this will help everyone who come across this very same issue.
Considering you will be parsing the infobox with PHP, you can use this:
http://www.mywiki.com/wiki/api.php?format=xml&action=query&titles=PAGE_TITLE_THAT_CONTAINS_AN_INFOBOX&prop=revisions&rvprop=content&rvgeneratexml=1
'rvgeneratexml' is being set to true (1), this will make the xml node <rev> generate an attribute "parsetree" containing the infobox information in XML format.
Then, in PHP, you can load the whole information (<api>everything including <rev></api>) with simpleXML:
$xml = simplexml_load_file($url);
Then you can load the template's information by getting the "parsetree" attribute and loading the string with:
$template = simplexml_load_string($xml->query->pages->page->revisions->rev->attributes()->parsetree);
$template = $template->template; // If more than 1 template, check template[0], [1], etc
Then, by using the correct structure, you can access the elements with something like:
if ($template->part[0]->name='name')
$film = $template->part[0]->value;
Then, $film will contain the film's name (->name is the parameter's name, and ->value is its value).

Mediawiki 1.16: Template documentation example usage

I'm writing template documentation for a wiki and wanted to include a working example of the template. However, I wrote the template to auto-categorize various fields and the entire template itself is also auto-categorized.
This means if I simply call on the template, it will categorize the doc page...and because the actual template page transcludes the doc page, the template page will also be categorized.
Is there a way to prevent these categories from automatically kicking in?
Something like the following should do the trick. Wrap the categorization in your template inside a parserfunction:
{{#ifeq: {{NAMESPACE}} | Help || [[Category:Some_Category]] }}
This sets the category when the template is transcluded onto a page that is not in the "Help" namespace.
Another option is to allow a parameter such as demo to avoid including the category.
If you don't mind being slightly cryptic, you could do the category in the template as {{{cat|[[Category:Some_Category]]}}}; then specifying the parameter as {{my template|cat=}} will prevent the category inclusion.
I'm not sure if I understand the question completely (what is "auto-categorize various fields"?). I am assuming here that you want to show a template "in action" on a documentation page - without attaching some categories (those categories the documentation page usually attaches to articles using this template) to the documentation page.
So
<onlyinclude>[[Category:Some_Category]]</onlyinclude>
will not do the job - as the template is in fact included. Right?
Try passing a parameter categorize=false to the template to indicate that categories are not to be attached in this case:
{{#ifeq:{{{categorize|}}}|false||[[Category:Some_Category]]}}
The double pipe after "false" means: if(categorize==false) then (empty), else [[Category:Some_Category]] - i.e. it is an equivalent construction for if(NOT(categorize==false))...
Good luck and thanks for all the fish,
Achim

How do I reuse HTML snippets in a django view

I am working on a django project (my first), and in one of my views, I have a sophisticated html snippet with JS weaved within it. I would like to reuse this "component" somewhere else in the same view. Is there a way of achieving this? Please let me know if this design is faulty to begin with?
Use the {% include '/my/common/template.html' %} templatetag.
Loads a template and renders it with
the current context. This is a way of
"including" other templates within a
template.
The template name can either be a
variable or a hard-coded (quoted)
string, in either single or double
quotes.
I know it's an old one but maybe someone is gonna have use of this answer.
There's also the inclusion tag. It's like the include tag, only you can pass it arguments and process it as a seperate template.
Put this in my_app/templatetags/my_templatetags.py:
#register.inclusion_tag('my_snippet.html')
def my_snippet(url, title):
return {'url': url, 'title': title}
and then my_snippet.html can be:
{{ title }}
then, to use this snippet in your templates:
{% load my_templatetags %}
{% my_snippet "/homepage/" "Homepage" %}
More info:
https://docs.djangoproject.com/en/dev/howto/custom-template-tags/#howto-custom-template-tags-inclusion-tags
Not sure, if you like to reuse your HTML in different templates (rendered by different views). If so, look into Django's template inheritance mechanism:
The most powerful -- and thus the most complex -- part of Django's template engine is template inheritance. Template inheritance allows you to build a base "skeleton" template that contains all the common elements of your site and defines blocks that child templates can override.
You should try Django custom template tags. This way you will keep your snippets in an external file and then call them easily by something like {{ your_custom_tag }}. It's a very convenient method for working with reusable chunks of xhtml markup. You can even use arguments with these custom tags, something like {{ your_custom_tag|image:"logo.png" }}.
You can learn more about custom tags here.