django-macros 0.4.0
A Django template tag library for repeating blocks tags and creating in template macros.
License: MIT License
Keywords: django repeat macros macro templatetags

django-macros
=============

Macros accepting positional and keyword arguments, and repeated block
tags in the django template system. Sometimes include tags just don't
get the job done. Either you have repeated code that you want to keep
all in the same single template, or your code needs to dynamically
generate and sub in certain values, in a way that the include syntax
inhibits. Whatever the case, if you're finding that the built in include
tag just isn't working for your use case, then perhaps django-macros is
for you.

visit the `github <https://github.com/nalourie/django-macros>`__.

Installation:
=============

from the command line:

::

    pip install django-macros

Within settings.py, add 'macros' to INSTALLED\_APPS:

.. code:: python

    INSTALLED_APPS = (
        ...
        'macros',
        ...
    )

Useage:
=======

django-macros contains two template tag libraries, one for creating
macros within templates, and one for repeating block tags.

Macros Useage
-------------

Explained Useage
~~~~~~~~~~~~~~~~

At the beginning of your file include:

::

    {% load macros %}

When you have a section of your template you want to repeat, but don't
want to have inherited or any other block tag-like functionality, define
a macro as follows:

::

    {% macro some_macro_name arg1 arg2 kwarg="default" %}
        {{ arg1 }} was the first argument.
        {{ arg2 }} was the second argument.

        {% if kwarg %}This is a {{ kwarg }}. {% endif %}
    {% endmacro %}

Then when you want to use the macro, simply do:

::

    {% use_macro some_macro_name "foo" "bar" kwarg="nondefault value" %}

which renders to:

::

    foo was the first argument.
    bar was the second argument.
    This is a nondefault value.

Alternatively, you can save your macros in a separate file, e.g.
"mymacros.html" and load it into the template with the tag
``{% loadmacros "mymacros.html" %}`` then use them with the
``{% use_macro ... %}`` tag.

All macros, including loaded ones, are local to the template file they
are loaded into/defined in, and are not inherited through
``{% extends ... %}`` tags.

A more in-depth useage example:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Macro:
^^^^^^

You can also input template variables into the macros, but filters are
not supported. That is, you cannot use filters in the arguments.

If the context where \`{'foo': 'foobar'}

::

    {% macro test2args1kwarg arg1 arg2 baz="Default baz" %}
        {% firstof arg1 "default arg1" %}
        {% if arg2 %}{{ arg2 }}{% else %}default arg2{% endif %}
        {{ baz }}
    {% endmacro %}
                

    {% use_macro test2args1kwarg "foo" "bar" baz="KW" %}
    <br>
    {% use_macro test2args1kwarg num_pages "bar" %}
    <br>
    {% use_macro test2args1kwarg %}

renders as:
^^^^^^^^^^^

::

    foo bar KW
    77 bar Default baz
    default arg1 default arg2 Default baz

Extended Syntax
~~~~~~~~~~~~~~~

Sometimes you might want to include data that is rendered by the
template engine, or longer data containing a lot of html in a macro. For
this, the syntax of plugging arguments directly into the tag doesn't
really work, so instead of
``{% use_macro some_macro_name "arg" kwarg_name="value" %}``, use the
syntax below:

::

    {% macro_block some_macro_name %}
        {% macro_arg %}
            arg
        {% endmacro_arg %}
        
        {% macro_kwarg kwname %}
            value
        {% endmacro_kwarg %}
    {% endmacro_block %}

Note that with this syntax you no longer have to quote
strings/arguments. If you have a mix of longer and shorter arguments,
you can also use both syntaxes simultaneously:

::

    {% macro_block some_macro_name "arg1" kwname1="value1" %}
        {% macro_arg %}
            arg2
        {% endmacro_arg %}
        
        {% macro_kwarg kwname2 %}
            value2
        {% endmacro_kwarg %}
    {% endmacro_block %}

Repeated Blocks Useage:
-----------------------

At the beginning of your file include:

::

    {% load repeatedblocks %}

When you have a block that you want to repeat, instead of using a block
tag, use a repeated block:

::

    {% repeated_block some_block name %}
        ...
        ...
        ...
    {% endblock %}

Later, when you want to repeat that block again, simply include the
repeat tag:

::

    {% repeat some_block name %}

Thus, the following template:

::

    {% repeated_block title %}Repeated Block Tags{% endblock %}

    {% repeat title %}

Renders to:

::

    Repeated Block Tags

    Repeated Block Tags

Make sure that the ``{% repeat ... %}`` tag comes **after** the
``{% repeated_block ... %} ... {% endblock %}`` tag.

They are fully inheritable, repeat inherited content and should work
exactly as you'd expect a block tag to work.

Bonus Content!
==============

Design Explanation for repeatedblocks.py:
-----------------------------------------

Using a "repeated\_block" followed by "repeat" tag structure, as opposed
to just repeating normal block tags, forces developers to be more
explicit about what is repeated. Thus, it guards against the potential
to remove block tags later in development, not realize they are
repeated, and create an error later. Hence, we've chosen this design
since it's more advantageous/pythonic in being explicit as well as dry.

Credits
=======

The macros tags are based on snippet originally by `Michal
Ludvig <http://www.logix.cz/michal>`__, michal@logix.cz, later modified
for args and kwargs by `Skylar Saveland <http://skyl.org>`__.

Code was updated for django 1.6, modified, and packaged by Nicholas
Lourie, while working for `kozbox, llc <http://kozbox.com>`__. Nick also
added the extended syntax to the macros.