Martin Eve
Martin Eve

Reputation: 2751

Should this go in the view logic?

My Django model has a field within which I want to have reference logic. As an example:

This is an example of text in the field.[ref type="quotation" name="Martin" date="2010"]

When presented in the final markup, this is rendered as (reduced example):

This is an example of text in the field.<a href="#ref">1</a>
[SNIP]
<ul>
<li><a name="ref1">Martin, 2010</a></li>
</ul>

So, essentially, I am building a list of references to go into a different {{}} block further down the page.

Should this kind of text-processing logic be in the view (so I pass 2 values to the template, 1 that is the modified text and 1 that is the reference table), or is there some more Django-esque way to do it via filters etc.?

Upvotes: 0

Views: 135

Answers (1)

Jordan Reiter
Jordan Reiter

Reputation: 21002

If you're actually storing the references in the text field like, this, then essentially you're using a simple markup language to store the references.

In which case, I think the template would be the place to do this.

Unfortunately, I don't know of any way to have a filter create and write to a context variable. So instead of using a filter, you're going to have to use a tag, something like:

{% output_with_references article_content myreferencesvar %}

[snip]

<ul>
{% for ref in myreferencesvar %}
<li><a name="{{ ref.id }}">{{ ref.authors }}, {{ ref.year }}</a></li>
{% endif %}
</ul>

BTW: if there is a way to write to the page context while using a filter, I'd love to know about it.

Update

To implement it, you'd use something like:

from django.template import Library, Node, TemplateSyntaxError

register = Library()

class OutputWithReferencesNode(Node):
    def __init__(self, input, ref_varnam='references'):
        self.input = input
        self.ref_varnam=ref_varnam

    def render(self, context):
        output = self.input
        references = []
        # process self.input
        context[self.ref_varnam] = references
        return output

@register.tag
def output_with_references(parser, token):
    try:
        fnctn, input, ref_varname = token.split_contents()
    except ValueError:
        raise TemplateSyntaxError, "%s takes the syntax %s text_to_output references_variable_name" % (fnctn,)
    return OutputWithReferencesNode(input, ref_varname)

Upvotes: 1

Related Questions