diff --git a/polymorphic/templatetags/__init__.py b/polymorphic/templatetags/__init__.py
index f08e9fb..1c7e071 100644
--- a/polymorphic/templatetags/__init__.py
+++ b/polymorphic/templatetags/__init__.py
@@ -1,5 +1,65 @@
"""
-Template tags to use in the admin.
+Template tags for polymorphic
+
+
+The ``polymorphic_formset_tags`` Library
+----------------------------------------
+
+.. versionadded:: 1.1
+
+To render formsets in the frontend, the ``polymorphic_tags`` provides extra
+filters to implement HTML rendering of polymorphic formsets.
+
+The following filters are provided;
+
+* ``{{ formset|as_script_options }}`` render the ``data-options`` for a JavaScript formset library.
+* ``{{ formset|include_empty_form }}`` provide the placeholder form for an add button.
+* ``{{ form|as_form_type }}`` return the model name that the form instance uses.
+* ``{{ model|as_model_name }}`` performs the same, for a model class or instance.
+
+.. code-block:: html+django
+
+ {% load i18n polymorphic_formset_tags %}
+
+
+
+
+The ``polymorphic_admin_tags`` Library
+--------------------------------------
The ``{% breadcrumb_scope ... %}`` tag makes sure the ``{{ opts }}`` and ``{{ app_label }}``
values are temporary based on the provided ``{{ base_opts }}``.
@@ -13,4 +73,5 @@ This allows fixing the breadcrumb in admin templates:
{% block breadcrumbs %}
{% breadcrumb_scope base_opts %}{{ block.super }}{% endbreadcrumb_scope %}
{% endblock %}
+
"""
diff --git a/polymorphic/templatetags/polymorphic_formset_tags.py b/polymorphic/templatetags/polymorphic_formset_tags.py
new file mode 100644
index 0000000..575299c
--- /dev/null
+++ b/polymorphic/templatetags/polymorphic_formset_tags.py
@@ -0,0 +1,79 @@
+import json
+
+from django.template import Library
+from django.utils.encoding import force_text
+from django.utils.text import capfirst
+from django.utils.translation import ugettext
+
+from polymorphic.formsets import BasePolymorphicModelFormSet
+
+
+register = Library()
+
+
+@register.filter()
+def include_empty_form(formset):
+ """
+ Make sure the "empty form" is included when displaying a formset (typically table with input rows)
+ """
+ for form in formset:
+ yield form
+
+ if hasattr(formset, 'empty_forms'):
+ # BasePolymorphicModelFormSet
+ for form in formset.empty_forms:
+ yield form
+ else:
+ # Standard Django formset
+ yield formset.empty_form
+
+
+@register.filter
+def as_script_options(formset):
+ """
+ A JavaScript data structure for the JavaScript code
+
+ This generates the ``data-options`` attribute for ``jquery.django-inlines.js``
+ The formset may define the following extra attributes:
+
+ - ``verbose_name``
+ - ``add_text``
+ - ``show_add_button``
+ """
+ verbose_name = getattr(formset, 'verbose_name', formset.model._meta.verbose_name)
+ options = {
+ 'prefix': formset.prefix,
+ 'pkFieldName': formset.model._meta.pk.name,
+ 'addText': getattr(formset, 'add_text', None) or ugettext('Add another %(verbose_name)s') % {
+ 'verbose_name': capfirst(verbose_name),
+ },
+ 'showAddButton': getattr(formset, 'show_add_button', True),
+ 'deleteText': ugettext('Verwijder'),
+ }
+
+ if isinstance(formset, BasePolymorphicModelFormSet):
+ # Allow to add different types
+ options['childTypes'] = [
+ {
+ 'name': force_text(model._meta.verbose_name),
+ 'type': model._meta.model_name,
+ } for model in formset.child_forms.keys()
+ ]
+
+ return json.dumps(options)
+
+
+@register.filter
+def as_form_type(form):
+ """
+ Usage: ``{{ form|as_form_type }}``
+ """
+ return form._meta.model._meta.model_name
+
+
+@register.filter
+def as_model_name(model):
+ """
+ Usage: ``{{ model|as_model_name }}``
+ """
+ return model._meta.model_name