From 8aa1e47f13441da7a4c454b32b44131927dca905 Mon Sep 17 00:00:00 2001
From: Nicolas ROCHE <nroche@entrouvert.com>
Date: Fri, 7 Aug 2020 17:00:06 +0200
Subject: [PATCH 1/2] templatetags: add removeprefix and removesuffix filters
 (#45780)

---
 combo/public/templatetags/combo.py | 27 +++++++++++++++++++++
 tests/test_public_templatetags.py  | 38 +++++++++++++++++++++++++++++-
 2 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/combo/public/templatetags/combo.py b/combo/public/templatetags/combo.py
index 36fbf386..57738bcc 100644
--- a/combo/public/templatetags/combo.py
+++ b/combo/public/templatetags/combo.py
@@ -293,16 +293,43 @@ def split(string, separator=' '):
 def strip(string, chars=None):
     if not string:
         return ''
     if chars:
         return force_text(string).strip(force_text(chars))
     else:
         return force_text(string).strip()
 
+
+@register.filter
+def removeprefix(string, prefix=None):
+    if string is None or string == '':
+        return string
+    value = force_text(string)
+    if prefix is None or prefix == '':
+        return value
+    prefix = force_text(prefix)
+    if value.startswith(prefix):
+        return value[len(prefix):]
+    return value
+
+
+@register.filter
+def removesuffix(string, suffix=None):
+    if string is None or string == '':
+        return string
+    value = force_text(string)
+    if suffix is None or suffix == '':
+        return value
+    suffix = force_text(suffix)
+    if value.endswith(suffix):
+        return value[:-len(suffix)]
+    return value
+
+
 @register.filter(name='get_group')
 def get_group(group_list, group_name):
     ret = []
     for group in group_list:
         if getattr(group, 'grouper', Ellipsis) == group_name:
             # Django >= 1.11, namedtuple
             ret.extend(group.list)
         elif not hasattr(group, 'grouper') and group['grouper'] == group_name:
diff --git a/tests/test_public_templatetags.py b/tests/test_public_templatetags.py
index 2489d3e6..fe7f06c4 100644
--- a/tests/test_public_templatetags.py
+++ b/tests/test_public_templatetags.py
@@ -128,24 +128,60 @@ def test_split():
     t = Template('{% for x in plop|split %}{{x}}<br>{% endfor %}')
     assert t.render(Context({'plop': 'ab cd ef'})) == 'ab<br>cd<br>ef<br>'
     t = Template('{% for x in plop|split:"|" %}{{x}} {% endfor %}')
     assert t.render(Context({'plop': 'ab|cd|ef'})) == 'ab cd ef '
 
 def test_strip_templatetag():
     tmpl = Template('{{ foo|strip }}')
     assert tmpl.render(Context()) == ''
-    assert tmpl.render(Context({'foo': None})) == ''
     assert tmpl.render(Context({'foo': ' foo bar '})) == 'foo bar'
     assert tmpl.render(Context({'foo': ' foo bar\t'})) == 'foo bar'
     assert tmpl.render(Context({'foo': ' félé  '})) == 'félé'
     tmpl = Template('{{ foo|strip:"XY" }}')
     assert tmpl.render(Context({'foo': 'XXfoo barXYX'})) == 'foo bar'
     assert tmpl.render(Context({'foo': ' foo barXX'})) == ' foo bar'
 
+
+def test_removeprefix_templatetag():
+    tmpl = Template('{{ foo|removeprefix }}')
+    assert tmpl.render(Context()) == ''
+    assert tmpl.render(Context({'foo': None})) == 'None'
+    assert tmpl.render(Context({'foo': 0})) == '0'
+    assert tmpl.render(Context({'foo': 'None'})) == 'None'
+    assert tmpl.render(Context({'foo': 'foo bar'})) == 'foo bar'
+    tmpl = Template('{{ foo|removeprefix:"" }}')
+    assert tmpl.render(Context({'foo': 'None'})) == 'None'
+    assert tmpl.render(Context({'foo': 'foo bar'})) == 'foo bar'
+    tmpl = Template('{{ foo|removeprefix:"XY" }}')
+    assert tmpl.render(Context({'foo': 'XYfoo barXY'})) == 'foo barXY'
+    assert tmpl.render(Context({'foo': 'foo bar'})) == 'foo bar'
+    assert tmpl.render(Context({'foo': 'xyfoo barXY'})) == 'xyfoo barXY'
+    assert tmpl.render(Context({'foo': ' XYfoo barXY'})) == ' XYfoo barXY'
+    assert tmpl.render(Context({'foo': 'XYXYfoo barXY'})) == 'XYfoo barXY'
+
+
+def test_removesuffix_templatetag():
+    tmpl = Template('{{ foo|removesuffix }}')
+    assert tmpl.render(Context()) == ''
+    assert tmpl.render(Context({'foo': None})) == 'None'
+    assert tmpl.render(Context({'foo': 0})) == '0'
+    assert tmpl.render(Context({'foo': 'None'})) == 'None'
+    assert tmpl.render(Context({'foo': 'foo bar'})) == 'foo bar'
+    tmpl = Template('{{ foo|removesuffix:"" }}')
+    assert tmpl.render(Context({'foo': 'None'})) == 'None'
+    assert tmpl.render(Context({'foo': 'foo bar'})) == 'foo bar'
+    tmpl = Template('{{ foo|removesuffix:"XY" }}')
+    assert tmpl.render(Context({'foo': 'XYfoo barXY'})) == 'XYfoo bar'
+    assert tmpl.render(Context({'foo': 'foo bar'})) == 'foo bar'
+    assert tmpl.render(Context({'foo': 'XYfoo barxy'})) == 'XYfoo barxy'
+    assert tmpl.render(Context({'foo': 'XYfoo barXY '})) == 'XYfoo barXY '
+    assert tmpl.render(Context({'foo': 'XYfoo barXYXY'})) == 'XYfoo barXY'
+
+
 def test_get_group():
     context = Context({'cities': [
         {'name': 'Mumbai', 'population': '19,000,000', 'country': 'India'},
         {'name': 'New York', 'population': '20,000,000', 'country': 'USA'},
         {'name': 'Calcutta', 'population': '15,000,000', 'country': 'India'},
         {'name': 'Chicago', 'population': '7,000,000', 'country': 'USA'},
         {'name': 'Tokyo', 'population': '33,000,000', 'country': 'Japan'},
     ]})
-- 
2.28.0

