Commit 2ef001a8 authored by Enrico Zini's avatar Enrico Zini
Browse files

Removed macro templatetags library in favour of new 'import with' template tag

parent 33de91fc
# See http://djangosnippets.org/snippets/363/
# The snipped was posted according to djangosnippets.org terms of service
# (http://djangosnippets.org/about/tos/) that state that they can be used by
# anyone in any way.
#
# templatetags/macros.py - Support for macros in Django templates
#
# Author: Michal Ludvig <michal@logix.cz>
# http://www.logix.cz/michal
#
"""
Tag library that provides support for "macros" in
Django templates.
Usage example:
0) Save this file as
<yourapp>/taglibrary/macros.py
1) In your template load the library:
{% load macros %}
2) Define a new macro called 'my_macro' with
parameter 'arg1':
{% macro my_macro arg1 %}
Parameter: {{ arg1 }} <br/>
{% endmacro %}
3) Use the macro with a String parameter:
{% usemacro my_macro "String parameter" %}
or with a variable parameter (provided the
context defines 'somearg' variable, e.g. with
value "Variable parameter"):
{% usemacro my_macro somearg %}
The output of the above code would be:
Parameter: String parameter <br/>
Parameter: Variable parameter <br/>
4) Alternatively save your macros in a separate
file, e.g. "mymacros.html" and load it to the
current template with:
{% loadmacros "mymacros.html" %}
Then use these loaded macros in {% usemacro %}
as described above.
Macros can take zero or more arguments and both
context variables and macro arguments are resolved
in macro body when used in {% usemacro ... %} tag.
Bear in mind that defined and loaded Macros are local
to each template file and are not inherited
through {% extends ... %} tags.
"""
from django import template
from django.template import resolve_variable, FilterExpression
from django.template.loader import get_template, get_template_from_string
from django.conf import settings
import re
register = template.Library()
def _setup_macros_dict(parser):
## Metadata of each macro are stored in a new attribute
## of 'parser' class. That way we can access it later
## in the template when processing 'usemacro' tags.
try:
## Only try to access it to eventually trigger an exception
parser._macros
except AttributeError:
parser._macros = {}
class DefineMacroNode(template.Node):
def __init__(self, name, nodelist, args):
self.name = name
self.nodelist = nodelist
self.args = args
def render(self, context):
## empty string - {% macro %} tag does no output
return ''
@register.tag(name="macro")
def do_macro(parser, token):
try:
args = token.split_contents()
tag_name, macro_name, args = args[0], args[1], args[2:]
except IndexError:
raise template.TemplateSyntaxError, "'%s' tag requires at least one argument (macro name)" % token.contents.split()[0]
# TODO: check that 'args' are all simple strings ([a-zA-Z0-9_]+)
r_valid_arg_name = re.compile(r'^[a-zA-Z0-9_]+$')
for arg in args:
if not r_valid_arg_name.match(arg):
raise template.TemplateSyntaxError, "Argument '%s' to macro '%s' contains illegal characters. Only alphanumeric characters and '_' are allowed." % (arg, macro_name)
nodelist = parser.parse(('endmacro', ))
parser.delete_first_token()
## Metadata of each macro are stored in a new attribute
## of 'parser' class. That way we can access it later
## in the template when processing 'usemacro' tags.
_setup_macros_dict(parser)
parser._macros[macro_name] = DefineMacroNode(macro_name, nodelist, args)
return parser._macros[macro_name]
class LoadMacrosNode(template.Node):
def render(self, context):
## empty string - {% loadmacros %} tag does no output
return ''
@register.tag(name="loadmacros")
def do_loadmacros(parser, token):
try:
tag_name, filename = token.split_contents()
except IndexError:
raise template.TemplateSyntaxError, "'%s' tag requires at least one argument (macro name)" % token.contents.split()[0]
if filename[0] in ('"', "'") and filename[-1] == filename[0]:
filename = filename[1:-1]
t = get_template(filename)
macros = t.nodelist.get_nodes_by_type(DefineMacroNode)
## Metadata of each macro are stored in a new attribute
## of 'parser' class. That way we can access it later
## in the template when processing 'usemacro' tags.
_setup_macros_dict(parser)
for macro in macros:
parser._macros[macro.name] = macro
return LoadMacrosNode()
class UseMacroNode(template.Node):
def __init__(self, macro, filter_expressions):
self.nodelist = macro.nodelist
self.args = macro.args
self.filter_expressions = filter_expressions
def render(self, context):
for (arg, fe) in [(self.args[i], self.filter_expressions[i]) for i in range(len(self.args))]:
context[arg] = fe.resolve(context)
return self.nodelist.render(context)
@register.tag(name="usemacro")
def do_usemacro(parser, token):
try:
args = token.split_contents()
tag_name, macro_name, values = args[0], args[1], args[2:]
except IndexError:
raise template.TemplateSyntaxError, "'%s' tag requires at least one argument (macro name)" % token.contents.split()[0]
try:
macro = parser._macros[macro_name]
except (AttributeError, KeyError):
raise template.TemplateSyntaxError, "Macro '%s' is not defined" % macro_name
if (len(values) != len(macro.args)):
raise template.TemplateSyntaxError, "Macro '%s' was declared with %d parameters and used with %d parameter" % (
macro_name,
len(macro.args),
len(values))
filter_expressions = []
for val in values:
if (val[0] == "'" or val[0] == '"') and (val[0] != val[-1]):
raise template.TemplateSyntaxError, "Non-terminated string argument: %s" % val[1:]
filter_expressions.append(FilterExpression(val, parser))
return UseMacroNode(macro, filter_expressions)
{% extends "public/base.html" %} {% extends "public/base.html" %}
{% load nm %} {% load nm %}
{% load macros %}
{% load js %} {% load js %}
{% block head_resources %} {% block head_resources %}
...@@ -8,50 +7,6 @@ ...@@ -8,50 +7,6 @@
{% jsinclude "nm" %} {% jsinclude "nm" %}
{% endblock %} {% endblock %}
{% macro process_table processes %}
<table>
<thead>
<tr>
<th>Applicant</th>
<th>From</th>
<th>To</th>
<th>Applying for</th>
<th>Progress</th>
<th>AM</th>
<th>Advocate(s)</th>
</thead>
<tbody>
{% for p in processes %}
<tr>
<td><a href="{{ p.get_absolute_url }}" title="{{p.person.fullname}}">{{p.person.uid|default:p.person.fullname}}</a></td>
<td>{{p.started.date}}</td>
<td>{{p.ended.date}}</td>
<td>{{p.applying_for|desc_status}} ({{p.is_active|yesno:"in progress,done"}})</td>
<td>
{% if p.is_active %}
<a href="{% url 'public_progress' progress=p.progress %}">{{p.progress|desc_progress}}</a>
{% else %}
{{p.progress|desc_progress}}
{% endif %}
</td>
<td>
{% if p.manager %}
<a href="{{ p.manager.get_absolute_url }}" title="{{p.manager.person.fullname}}">{{p.manager.person.uid|default:"None"}}</a>
{% else %}
None
{% endif %}
</td>
<td>
{% for a in p.advocates.all %}
<a href="{{ a.get_absolute_url }}" title="{{a.fullname}}">{{a.uid}}</a>{% if not forloop.last %},{% endif %}
{% endfor %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endmacro %}
{% block breadcrumbs %}{{block.super}} / <a href="{% url 'people' %}">people</a> / {{person.uid|default:person.fullname}}{% endblock %} {% block breadcrumbs %}{{block.super}} / <a href="{% url 'people' %}">people</a> / {{person.uid|default:person.fullname}}{% endblock %}
{% block relatedpages %} {% block relatedpages %}
...@@ -108,13 +63,13 @@ ...@@ -108,13 +63,13 @@
<h2>Personal history</h2> <h2>Personal history</h2>
{% usemacro process_table processes %} {% include "public/person_process_table.html" with p=p processes=processes only %}
{% if adv_processes %} {% if adv_processes %}
<h2>Advocate history</h2> <h2>Advocate history</h2>
{% usemacro process_table adv_processes %} {% include "public/person_process_table.html" with p=p processes=adv_processes only %}
{% endif %} {% endif %}
...@@ -122,7 +77,7 @@ ...@@ -122,7 +77,7 @@
<h2>AM history</h2> <h2>AM history</h2>
{% usemacro process_table am_processes %} {% include "public/person_process_table.html" with p=p processes=am_processes only %}
{% endif %} {% endif %}
......
{% load nm %}
<table>
<thead>
<tr>
<th>Applicant</th>
<th>From</th>
<th>To</th>
<th>Applying for</th>
<th>Progress</th>
<th>AM</th>
<th>Advocate(s)</th>
</thead>
<tbody>
{% for p in processes %}
<tr>
<td><a href="{{ p.get_absolute_url }}" title="{{p.person.fullname}}">{{p.person.uid|default:p.person.fullname}}</a></td>
<td>{{p.started.date}}</td>
<td>{{p.ended.date}}</td>
<td>{{p.applying_for|desc_status}} ({{p.is_active|yesno:"in progress,done"}})</td>
<td>
{% if p.is_active %}
<a href="{% url 'public_progress' progress=p.progress %}">{{p.progress|desc_progress}}</a>
{% else %}
{{p.progress|desc_progress}}
{% endif %}
</td>
<td>
{% if p.manager %}
<a href="{{ p.manager.get_absolute_url }}" title="{{p.manager.person.fullname}}">{{p.manager.person.uid|default:"None"}}</a>
{% else %}
None
{% endif %}
</td>
<td>
{% for a in p.advocates.all %}
<a href="{{ a.get_absolute_url }}" title="{{a.fullname}}">{{a.uid}}</a>{% if not forloop.last %},{% endif %}
{% endfor %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% load nm %}
{% if procs %}
<table class="proctable tablesorter {{class}}">
<thead>
<tr>
<th>Appl date</th>
<th>Last change</th>
<th>Progress</th>
<th>Applying for</th>
<th>Applicant</th>
<th>Uid</th>
<th>Advocate(s)</th>
<th>Manager</th>
{% if visitor.is_admin %}
<th>FD comments</th>
{% endif %}
</tr>
</thead>
<tbody>
{% for p in procs %}
<tr tag="{{p.progress}}">
<td>{{p.started|date:"Y-m-d"}}</td>
<td>{{p.last_change|date:"Y-m-d"}}</td>
<td val="{{ p.progress|seq_progress }}"><a href="{{ p.get_absolute_url }}">{{p.progress|desc_progress}}</a></td>
<td val="{{ p.applying_for|seq_status }}">{{p.applying_for|desc_status}}</td>
<td><a href="{{ p.get_absolute_url }}">{{p.person.fullname}}</a></td>
<td><a href="{{ p.get_absolute_url }}">{{p.person.uid}}</a></td>
<td>
{% for a in p.advocates.all %}
<a href="{{ a.get_absolute_url }}">{{a.uid}}</a>{% if not forloop.last %},{% endif %}
{% endfor %}
</td>
<td>
{% if p.manager %}
<a href="{{ p.manager.get_absolute_url }}">{{p.manager.person.uid}}</a>
{% endif %}
</td>
{% if visitor.is_admin %}
<td>{{ p.person.fd_comment }}</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% extends "public/base.html" %} {% extends "public/base.html" %}
{% load nm %} {% load nm %}
{% load macros %}
{% load js %} {% load js %}
{% block head_resources %} {% block head_resources %}
...@@ -54,53 +53,6 @@ $(function() { ...@@ -54,53 +53,6 @@ $(function() {
</script> </script>
{% endblock %} {% endblock %}
{% macro process_table procs class %}
{% if procs %}
<table class="proctable tablesorter {{class}}">
<thead>
<tr>
<th>Appl date</th>
<th>Last change</th>
<th>Progress</th>
<th>Applying for</th>
<th>Applicant</th>
<th>Uid</th>
<th>Advocate(s)</th>
<th>Manager</th>
{% if visitor.is_admin %}
<th>FD comments</th>
{% endif %}
</tr>
</thead>
<tbody>
{% for p in procs %}
<tr tag="{{p.progress}}">
<td>{{p.started|date:"Y-m-d"}}</td>
<td>{{p.last_change|date:"Y-m-d"}}</td>
<td val="{{ p.progress|seq_progress }}"><a href="{{ p.get_absolute_url }}">{{p.progress|desc_progress}}</a></td>
<td val="{{ p.applying_for|seq_status }}">{{p.applying_for|desc_status}}</td>
<td><a href="{{ p.get_absolute_url }}">{{p.person.fullname}}</a></td>
<td><a href="{{ p.get_absolute_url }}">{{p.person.uid}}</a></td>
<td>
{% for a in p.advocates.all %}
<a href="{{ a.get_absolute_url }}">{{a.uid}}</a>{% if not forloop.last %},{% endif %}
{% endfor %}
</td>
<td>
{% if p.manager %}
<a href="{{ p.manager.get_absolute_url }}">{{p.manager.person.uid}}</a>
{% endif %}
</td>
{% if visitor.is_admin %}
<td>{{ p.person.fd_comment }}</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% endmacro %}
{% block breadcrumbs %}{{block.super}} / <a href="{% url 'processes' %}">processes</a>{% endblock %} {% block breadcrumbs %}{{block.super}} / <a href="{% url 'processes' %}">processes</a>{% endblock %}
{% block content %} {% block content %}
...@@ -132,11 +84,11 @@ instead. ...@@ -132,11 +84,11 @@ instead.
<li><a class="filter" href="#done">New Members</a></li> <li><a class="filter" href="#done">New Members</a></li>
</ul> </ul>
{% usemacro process_table open "open" %} {% include "public/process_table.html" with visitor=visitor p=p procs=open class="open" only %}
<h2 id="done">Recently closed</h2> <h2 id="done">Recently closed</h2>
{% usemacro process_table done "done" %} {% include "public/process_table.html" with visitor=visitor p=p procs=done class="done" only %}
{% endblock %} {% endblock %}
{% extends "restricted/base.html" %} {% extends "restricted/base.html" %}
{% load js %} {% load js %}
{% load macros %}
{% load nm %} {% load nm %}
{% block head_resources %} {% block head_resources %}
...@@ -32,55 +31,6 @@ $(function() { ...@@ -32,55 +31,6 @@ $(function() {
</script> </script>
{% endblock %} {% endblock %}
{% macro process_table progs extras %}
{% if progs %}
<table class="proctable tablesorter">
<thead>
<tr>
<th>Started</th>
<th>Last</th>
<th>Target</th>
<th>Applicant</th>
<th>Uid</th>
<th>Adv.</th>
{% if "m" in extras %}
<th>Manager</th>
{% endif %}
<th>Last log</th>
</tr>
</thead>
<tbody>
{% for p in progs %}
<tr>
<td>{{p.started|date:"Y-m-d"}}</td>
<td>{{p.last_change|date:"Y-m-d"}}</td>
<td>{{p.applying_for|sdesc_status}}</td>
<td><a href="{{ p.get_absolute_url }}">{{p.person}}</a></td>
<td><a href="{{ p.get_absolute_url }}">{{p.person.uid}}</a></td>
<td>
{% for a in p.advocates.all %}
<a href="{{ a.get_absolute_url }}">{{a.uid}}</a>
{% endfor %}
</td>
{% if "m" in extras %}
<td><a href="{{ p.manager.get_absolute_url }}">{{p.manager.person.uid}}</a></td>
{% endif %}
<td>
{% if p.log_last.logtext %}
{{ p.log_last.logtext }}
{% else %}
[{{p.log_last.progress|sdesc_progress}}]
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p><i>none</i></p>
{% endif %}
{% endmacro %}
{% block breadcrumbs %}{{block.super}} / <a href="{% url 'restricted_ammain' %}">ammain</a>{% endblock %} {% block breadcrumbs %}{{block.super}} / <a href="{% url 'restricted_ammain' %}">ammain</a>{% endblock %}
{% block relatedpages %} {% block relatedpages %}
...@@ -121,41 +71,41 @@ $(function() { ...@@ -121,41 +71,41 @@ $(function() {
{% endif %} {% endif %}
<p>The following people have applied but have not enough advocates or we did not send the activity poll yet.</p> <p>The following people have applied but have not enough advocates or we did not send the activity poll yet.</p>
{% usemacro process_table prog_app_new "" %} {% include "restricted/process_table.html" with p=p progs=prog_app_new extras="" only %}
<p>The following people have not replied to the activity poll yet.</p> <p>The following people have not replied to the activity poll yet.</p>
{% usemacro process_table prog_poll_sent "" %} {% include "restricted/process_table.html" with p=p progs=prog_poll_sent extras="" only %}
<p>The following applicants are waiting for an Application Manager to be <p>The following applicants are waiting for an Application Manager to be
assigned (first one is oldest).</p> assigned (first one is oldest).</p>
{% usemacro process_table prog_app_ok "" %} {% include "restricted/process_table.html" with p=p progs=prog_app_ok extras="" only %}
<p>Applicants currently not ready to be assigned to an AM (ordered by hold date):</p> <p>Applicants currently not ready to be assigned to an AM (ordered by hold date):</p>
{% usemacro process_table prog_app_hold "" %} {% include "restricted/process_table.html" with p=p progs=prog_app_hold extras="" only %}
<p>Applicants assigned to AM but AM has not confirmed:</p> <p>Applicants assigned to AM but AM has not confirmed:</p>
{% usemacro process_table prog_am_rcvd "m" %} {% include "restricted/process_table.html" with p=p progs=prog_am_rcvd extras="m" only %}
<p>The reports of the following applicants approved by their AM need to be <p>The reports of the following applicants approved by their AM need to be
checked:</p> checked:</p>
{% usemacro process_table prog_am_ok "m" %} {% include "restricted/process_table.html" with p=p progs=prog_am_ok extras="m" only %}
<p>The following applicants have incomplete AM reports (ordered by hold date):</p> <p>The following applicants have incomplete AM reports (ordered by hold date):</p>
{% usemacro process_table prog_fd_hold "m" %} {% include "restricted/process_table.html" with p=p progs=prog_fd_hold extras="m" only %}
<h2>Debian Account Manager</h2> <h2>Debian Account Manager</h2>
<p>The following applicants have been approved by the NM committee and the FD <p>The following applicants have been approved by the NM committee and the FD
but a DAM has not fully processed them yet (sorted by FD approval):</p> but a DAM has not fully processed them yet (sorted by FD approval):</p>
{% usemacro process_table prog_fd_ok "m" %} {% include "restricted/process_table.html" with p=p progs=prog_fd_ok extras="m" only %}
<p>Applicants approved by a DAM, but for which no account has been created yet:</p> <p>Applicants approved by a DAM, but for which no account has been created yet:</p>
{% usemacro process_table prog_dam_ok "m" %} {% include "restricted/process_table.html" with p=p progs=prog_dam_ok extras="m" only %}
<p>These are applications that have been put on hold at the DAM stage <p>These are applications that have been put on hold at the DAM stage
(sorted by hold date):</p> (sorted by hold date):</p>
{% usemacro process_table prog_dam_hold "m" %} {% include "restricted/process_table.html" with p=p progs=prog_dam_hold extras="m" only %}
{% endif %} {% endif %}
...@@ -172,25 +122,25 @@ you are the AM for:</p> ...@@ -172,25 +122,25 @@ you are the AM for:</p>
<p>These applicants have been assigned to you by the Front Desk but you have <p>These applicants have been assigned to you by the Front Desk but you have
not confirmed that you will or will not be their AM (ordered by assignment not confirmed that you will or will not be their AM (ordered by assignment
date).</p> date).</p>
{% usemacro process_table am_prog_rcvd "" %} {% include "restricted/process_table.html" with p=p progs=am_prog_rcvd extras="" only %}
<h3>Applicants to process</h3> <h3>Applicants to process</h3>
<p>The following applicants you are the AM for (ordered by the date you <p>The following applicants you are the AM for (ordered by the date you
accepted them as NMs):</p> accepted them as NMs):</p>
{% usemacro process_table am_prog_am "" %} {% include "restricted/process_table.html" with p=p progs=am_prog_am extras="" only %}
<h3>Applicants on Hold</h3> <h3>Applicants on Hold</h3>
<p>Applicants who make it here have some issue with completing the process but <p>Applicants who make it here have some issue with completing the process but
are expected to be able to work around that soon (ordered by hold date).</p> are expected to be able to work around that soon (ordered by hold date).</p>
{% usemacro process_table am_prog_hold "" %} {% include "restricted/process_table.html" with p=p progs=am_prog_hold extras="" only %}
<h3>Processed Applicants</h3> <h3>Processed Applicants</h3>
<p>These applicants you have processed through the system and are here for <p>These applicants you have processed through the system and are here for
historical or informational purposes (ordered by account creation date).</p> historical or informational purposes (ordered by account creation date).</p>
{% usemacro process_table am_prog_done "" %} {% include "restricted/process_table.html" with p=p progs=am_prog_done extras="" only %}
{% endif %} {% endif %}
{% comment %} {% comment %}
......
{% load nm %}
{% if progs %}
<table class="proctable tablesorter">
<thead>
<tr>
<th>Started</th>
<th>Last</th>
<th>Target</th>
<th>Applicant</th>
<th>Uid</th>
<th>Adv.</th>
{% if "m" in extras %}
<th>Manager</th>
{% endif %}
<th>Last log</th>
</tr>
</thead>
<tbody>
{% for p in progs %}
<tr>
<td>{{p.started|date:"Y-m-d"}}</td>
<td>{{p.last_change|date:"Y-m-d"}}</td>
<td>{{p.applying_for|sdesc_status}}</td>
<td><a href="{{ p.get_absolute_url }}">{{p.person}}</a></td>
<td><a href="{{ p.get_absolute_url }}">{{p.person.uid}}</a></td>
<td>
{% for a in p.advocates.all %}
<a href="{{ a.get_absolute_url }}">{{a.uid}}</a>
{% endfor %}
</td>
{% if "m" in extras %}
<td><a href="{{ p.manager.get_absolute_url }}">{{p.manager.person.uid}}</a></td>
{% endif %}
<td>
{% if p.log_last.logtext %}
{{ p.log_last.logtext }}
{% else %}
[{{p.log_last.progress|sdesc_progress}}]
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p><i>none</i></p>
{% endif %}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment