diff --git a/CHANGES.rst b/CHANGES.rst index 08961f2..dd765d4 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,9 @@ +0.16.5 (2023-01-07) +------------------- +- PR #467 - thanks to Slarag +- fix #465 +- fix #464 + 0.16.4 (2022-08-04) ------------------- - Regional fonts for RichText @@ -23,9 +29,6 @@ 0.15.2 (2022-01-12) ------------------- - fix #408 - -0.15.1 (2021-12-20) -------------------- - Multi-rendering with same DocxTemplate object is now possible see tests/multi_rendering.py - fix #392 diff --git a/docxtpl/__init__.py b/docxtpl/__init__.py index 732521c..1ef0ba7 100644 --- a/docxtpl/__init__.py +++ b/docxtpl/__init__.py @@ -4,7 +4,7 @@ Created : 2015-03-12 @author: Eric Lapouyade """ -__version__ = '0.16.4' +__version__ = '0.16.5' # flake8: noqa from .inline_image import InlineImage diff --git a/docxtpl/template.py b/docxtpl/template.py index a4def7f..843aade 100644 --- a/docxtpl/template.py +++ b/docxtpl/template.py @@ -43,8 +43,8 @@ class DocxTemplate(object): self.is_rendered = False self.is_saved = False - def init_docx(self): - if not self.docx or self.is_rendered: + def init_docx(self, reload: bool = True): + if not self.docx or (self.is_rendered and reload): self.docx = Document(self.template_file) self.is_rendered = False @@ -252,6 +252,31 @@ class DocxTemplate(object): dst_xml = self.resolve_listing(dst_xml) return dst_xml + def render_properties(self, context: Dict[str, Any], jinja_env: Optional[Environment] = None) -> None: + # List of string attributes of docx.opc.coreprops.CoreProperties which are strings. + # It seems that some attributes cannot be written as strings. Those are commented out. + properties = [ + 'author', + # 'category', + 'comments', + # 'content_status', + 'identifier', + # 'keywords', + 'language', + # 'last_modified_by', + 'subject', + 'title', + # 'version', + ] + if jinja_env is None: + jinja_env = Environment() + + for prop in properties: + initial = getattr(self.docx.core_properties, prop) + template = jinja_env.from_string(initial) + rendered = template.render(context) + setattr(self.docx.core_properties, prop, rendered) + def resolve_listing(self, xml): def resolve_text(run_properties, paragraph_properties, m): @@ -363,6 +388,8 @@ class DocxTemplate(object): for relKey, xml in footers: self.map_headers_footers_xml(relKey, xml) + self.render_properties(context, jinja_env) + # set rendered flag self.is_rendered = True @@ -728,7 +755,7 @@ class DocxTemplate(object): self.is_saved = True def get_undeclared_template_variables(self, jinja_env: Optional[Environment] = None) -> Set[str]: - self.init_docx() + self.init_docx(reload=False) xml = self.get_xml() xml = self.patch_xml(xml) for uri in [self.HEADER_URI, self.FOOTER_URI]: diff --git a/tests/doc_properties.py b/tests/doc_properties.py new file mode 100644 index 0000000..2083c8c --- /dev/null +++ b/tests/doc_properties.py @@ -0,0 +1,15 @@ +import os.path + +import jinja2 +from docxtpl import DocxTemplate, InlineImage + +doctemplate = r'templates/doc_properties_tpl.docx' + +tpl = DocxTemplate(doctemplate) + +context = { + 'test': 'HelloWorld' +} + +tpl.render(context) +tpl.save("output/doc_properties.docx") diff --git a/tests/templates/doc_properties_tpl.docx b/tests/templates/doc_properties_tpl.docx new file mode 100644 index 0000000..d15557a Binary files /dev/null and b/tests/templates/doc_properties_tpl.docx differ