jinja2content.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. """
  2. jinja2content.py
  3. ----------------
  4. Pelican plugin that processes Markdown files as jinja templates.
  5. """
  6. from jinja2 import Environment, FileSystemLoader, ChoiceLoader
  7. import os
  8. from pelican import signals
  9. from pelican.readers import MarkdownReader, HTMLReader, RstReader
  10. from pelican.utils import pelican_open
  11. from tempfile import NamedTemporaryFile
  12. class JinjaContentMixin:
  13. def __init__(self, *args, **kwargs):
  14. super().__init__(*args, **kwargs)
  15. # will look first in 'JINJA2CONTENT_TEMPLATES', by default the
  16. # content root path, then in the theme's templates
  17. local_dirs = self.settings.get('JINJA2CONTENT_TEMPLATES', ['.'])
  18. local_dirs = [os.path.join(self.settings['PATH'], folder)
  19. for folder in local_dirs]
  20. theme_dir = os.path.join(self.settings['THEME'], 'templates')
  21. loaders = [FileSystemLoader(_dir) for _dir
  22. in local_dirs + [theme_dir]]
  23. if 'JINJA_ENVIRONMENT' in self.settings: # pelican 3.7
  24. jinja_environment = self.settings['JINJA_ENVIRONMENT']
  25. else:
  26. jinja_environment = {
  27. 'trim_blocks': True,
  28. 'lstrip_blocks': True,
  29. 'extensions': self.settings['JINJA_EXTENSIONS']
  30. }
  31. self.env = Environment(
  32. loader=ChoiceLoader(loaders),
  33. **jinja_environment)
  34. def read(self, source_path):
  35. with pelican_open(source_path) as text:
  36. text = self.env.from_string(text).render()
  37. with NamedTemporaryFile(delete=False) as f:
  38. f.write(text.encode())
  39. f.close()
  40. content, metadata = super().read(f.name)
  41. os.unlink(f.name)
  42. return content, metadata
  43. class JinjaMarkdownReader(JinjaContentMixin, MarkdownReader):
  44. pass
  45. class JinjaRstReader(JinjaContentMixin, RstReader):
  46. pass
  47. class JinjaHTMLReader(JinjaContentMixin, HTMLReader):
  48. pass
  49. def add_reader(readers):
  50. for Reader in [JinjaMarkdownReader, JinjaRstReader, JinjaHTMLReader]:
  51. for ext in Reader.file_extensions:
  52. readers.reader_classes[ext] = Reader
  53. def register():
  54. signals.readers_init.connect(add_reader)