Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#334 Create set_attributes template tag #366

Merged
merged 4 commits into from
Apr 15, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions poleno/utils/templatetags/poleno/amend.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# vim: expandtab
# -*- coding: utf-8 -*-
import re
import lxml.html

from poleno.utils.template import Library
Expand Down Expand Up @@ -244,3 +245,47 @@ def action(fragment):

context[u'_amend'].append(action)
return u''

@register.simple_tag(takes_context=True)
def set_attributes(context, path, **kwargs):
u"""
Select elements specified by XPath and add, remove or edit their attributes.

Example:
{% amend %}
<ul>
<li>xxx</li>
<li ccc="value" ddd>yyy</li>
<li eee="value">zzz</li>
</ul>
{% set_attributes path=".//li[1]" aaa="value" bbb=True %}
{% set_attributes path=".//li[2]" ccc=None ddd=False %}
{% set_attributes path=".//li[3]" eee="new_value" %}
martinmacko47 marked this conversation as resolved.
Show resolved Hide resolved
{% endamend %}

Result:
<ul>
<li aaa="value" bbb>xxx</li>
<li>yyy</li>
<li eee="new_value">zzz</li>
</ul>
"""
if u'_amend' not in context:
context[u'_amend'] = []

def action(fragment):
elements = fragment.findall(path)
for element in elements:
for key, value in kwargs.items():
if not re.match(r'^[a-z][a-z0-9_.-]*$', key):
martinmacko47 marked this conversation as resolved.
Show resolved Hide resolved
raise ValueError(u'Invalid tag name')
if key not in element.attrib and not value:
continue
elif not value:
martinmacko47 marked this conversation as resolved.
Show resolved Hide resolved
element.attrib.pop(key)
else:
element.set(key, value if value != True else None)
martinmacko47 marked this conversation as resolved.
Show resolved Hide resolved
martinmacko47 marked this conversation as resolved.
Show resolved Hide resolved
return fragment

context[u'_amend'].append(action)
return u''
79 changes: 79 additions & 0 deletions poleno/utils/tests/test_templatetags.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,85 @@ def test_delete_tag(self):
u'</ul>'
u'')

def test_set_attributes_tag_add_attribute(self):
martinmacko47 marked this conversation as resolved.
Show resolved Hide resolved
rendered = self._render(
u'{% load amend set_attributes from poleno.amend %}'
u'{% amend %}'
u' <ul>'
u' <li>xxx</li>'
u' <li>yyy</li>'
u' <li>zzz</li>'
u' </ul>'
u' {% set_attributes path=".//li" aaa="value" %}'
u' {% set_attributes path=".//li[2]" bbb=True %}'
u' {% set_attributes path=".//li[3]" ccc="value" ddd="value" eee=True %}'
u'{% endamend %}'
u'')
self.assertHTMLEqual(rendered,
u'<ul>'
u' <li aaa="value">xxx</li>'
u' <li aaa="value" bbb>yyy</li>'
u' <li aaa="value" ccc="value" ddd="value" eee>zzz</li>'
u'</ul>'
u'')

def test_set_attributes_tag_edit_attribute(self):
rendered = self._render(
u'{% load amend set_attributes from poleno.amend %}'
u'{% amend %}'
u' <ul>'
u' <li aaa="value">xxx</li>'
u' <li aaa="value" bbb="value" ccc="value">yyy</li>'
u' <li aaa="value">zzz</li>'
u' </ul>'
u' {% set_attributes path=".//li" aaa="new_value" %}'
u' {% set_attributes path=".//li[2]" bbb="new_value" ccc="new_value" %}'
u'{% endamend %}'
u'')
self.assertHTMLEqual(rendered,
u'<ul>'
u' <li aaa="new_value">xxx</li>'
u' <li aaa="new_value" bbb="new_value" ccc="new_value">yyy</li>'
u' <li aaa="new_value">zzz</li>'
u'</ul>'
u'')

def test_set_attributes_tag_remove_attribute(self):
rendered = self._render(
u'{% load amend set_attributes from poleno.amend %}'
u'{% amend %}'
u' <ul>'
u' <li aaa="value">xxx</li>'
u' <li aaa="value" bbb>yyy</li>'
u' <li aaa="value" ccc="value" ddd="value" eee fff>zzz</li>'
u' </ul>'
u' {% set_attributes path=".//li" aaa=None %}'
u' {% set_attributes path=".//li[2]" bbb=False %}'
u' {% set_attributes path=".//li[3]" ccc=None ddd="" eee=None fff="" %}'
martinmacko47 marked this conversation as resolved.
Show resolved Hide resolved
u'{% endamend %}'
u'')
self.assertHTMLEqual(rendered,
u'<ul>'
u' <li>xxx</li>'
u' <li>yyy</li>'
u' <li>zzz</li>'
u'</ul>'
u'')

def test_set_attributes_tag_with_invalid_key(self):
martinmacko47 marked this conversation as resolved.
Show resolved Hide resolved
with self.assertRaisesMessage(ValueError, u'Invalid tag name'):
rendered = self._render(
u'{% load amend set_attributes from poleno.amend %}'
u'{% amend %}'
u' <ul>'
u' <li>xxx</li>'
u' <li>yyy</li>'
u' <li>zzz</li>'
u' </ul>'
u' {% set_attributes path=".//li" Aaa=True %}'
u'{% endamend %}'
u'')

martinmacko47 marked this conversation as resolved.
Show resolved Hide resolved
def test_amend_tag_on_plain_text(self):
rendered = self._render(
u'{% load amend prepend append from poleno.amend %}'
Expand Down