summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mailman/utilities/i18n.py43
-rw-r--r--src/mailman/utilities/tests/test_templates.py74
2 files changed, 113 insertions, 4 deletions
diff --git a/src/mailman/utilities/i18n.py b/src/mailman/utilities/i18n.py
index a0f49a436..bb826e853 100644
--- a/src/mailman/utilities/i18n.py
+++ b/src/mailman/utilities/i18n.py
@@ -31,9 +31,14 @@ import os
import errno
from itertools import product
+from zope.component import getUtility
from mailman.config import config
from mailman.core.constants import system_preferences
+from mailman.interfaces.languages import ILanguageManager
+from mailman.utilities.string import expand
+
+from mailman.Utils import wrap as wrap_text
@@ -155,5 +160,39 @@ def find(template_file, mailing_list=None, language=None):
raise TemplateNotFoundError(template_file)
-def make():
- pass
+def make(template_file, mailing_list=None, language=None, wrap=True, **kw):
+ """Locate and 'make' a template file.
+
+ The template file is located as with `find()`, and the resulting text is
+ optionally wrapped and interpolated with the keyword argument dictionary.
+
+ :param template_file: The name of the template file to search for.
+ :type template_file: string
+ :param mailing_list: Optional mailing list used as the context for
+ searching for the template file. The list's preferred language will
+ influence the search, as will the list's data directory.
+ :type mailing_list: `IMailingList`
+ :param language: Optional language code, which influences the search.
+ :type language: string
+ :param wrap: When True, wrap the text.
+ :type wrap: bool
+ :param **kw: Keyword arguments for template interpolation.
+ :return: A tuple of the file system path to the first matching template,
+ and an open file object allowing reading of the file.
+ :rtype: (string, file)
+ :raises TemplateNotFoundError: when the template could not be found.
+ """
+ path, fp = find(template_file, mailing_list, language)
+ try:
+ raw_text = fp.read()
+ finally:
+ fp.close()
+ # The language is always the second to last path component.
+ parts = path.split(os.sep)
+ language_code = parts[-2]
+ charset = getUtility(ILanguageManager)[language_code].charset
+ template = unicode(raw_text, charset, 'replace')
+ text = expand(template, kw)
+ if wrap:
+ return wrap_text(text)
+ return text
diff --git a/src/mailman/utilities/tests/test_templates.py b/src/mailman/utilities/tests/test_templates.py
index 23f99b60e..b95b181f7 100644
--- a/src/mailman/utilities/tests/test_templates.py
+++ b/src/mailman/utilities/tests/test_templates.py
@@ -38,8 +38,6 @@ from mailman.interfaces.languages import ILanguageManager
from mailman.testing.layers import ConfigLayer
from mailman.utilities.i18n import TemplateNotFoundError, _search, find, make
-from mailman.Utils import findtext
-
class TestSearchOrder(unittest.TestCase):
@@ -214,9 +212,81 @@ class TestFind(unittest.TestCase):
else:
raise AssertionError('TemplateNotFoundError expected')
+
+
+class TestMake(unittest.TestCase):
+ """Test template interpolation."""
+
+ layer = ConfigLayer
+
+ def setUp(self):
+ self.template_dir = tempfile.mkdtemp()
+ config.push('template config', """\
+ [paths.testing]
+ template_dir: {0}
+ """.format(self.template_dir))
+ # The following MUST happen AFTER the push() above since pushing a new
+ # config also clears out the language manager.
+ getUtility(ILanguageManager).add('xx', 'utf-8', 'Xlandia')
+ self.mlist = create_list('test@example.com')
+ self.mlist.preferred_language = 'xx'
+ # Populate the template directory with some samples.
+ self.xxdir = os.path.join(self.template_dir, 'xx')
+ os.mkdir(self.xxdir)
+ with open(os.path.join(self.xxdir, 'nosub.txt'), 'w') as fp:
+ print >> fp, """\
+This is a global template.
+It has no substitutions.
+It will be wrapped.
+"""
+ with open(os.path.join(self.xxdir, 'subs.txt'), 'w') as fp:
+ print >> fp, """\
+This is a $kind template.
+It has $howmany substitutions.
+It will be wrapped.
+"""
+ with open(os.path.join(self.xxdir, 'nowrap.txt'), 'w') as fp:
+ print >> fp, """\
+This is a $kind template.
+It has $howmany substitutions.
+It will not be wrapped.
+"""
+
+ def tearDown(self):
+ config.pop('template config')
+ shutil.rmtree(self.template_dir)
+
+ def test_no_substitutions(self):
+ self.assertEqual(make('nosub.txt', self.mlist), """\
+This is a global template. It has no substitutions. It will be
+wrapped.
+
+""")
+
+ def test_substitutions(self):
+ self.assertEqual(make('subs.txt', self.mlist,
+ kind='very nice',
+ howmany='a few'), """\
+This is a very nice template. It has a few substitutions. It will be
+wrapped.
+
+""")
+
+ def test_substitutions_no_wrap(self):
+ self.assertEqual(make('nowrap.txt', self.mlist, wrap=False,
+ kind='very nice',
+ howmany='a few'), """\
+This is a very nice template.
+It has a few substitutions.
+It will not be wrapped.
+
+""")
+
+
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestSearchOrder))
suite.addTest(unittest.makeSuite(TestFind))
+ suite.addTest(unittest.makeSuite(TestMake))
return suite