Dates and template filters
I have a docx template that is applying filters to dates. The dates are expected to be in string format MM-dd-yyyy.
I have a question that is using the date picker. It appears that filters are not being applied to dates. question: | Date fields:
- Select Date: test_date datatype: date
I added the metadata tag to set the default date format
metadata: date format: "MM-dd-yyyy"
In my template I print the date along with using filters. The only thing that gets printed is the date.
{{test_date}}
{{test_date|filter}}
I know my filters work as if I remove the datatype from the question field and just put the date in as a string , ex 09-05-2025, they all work.
I have also figured out this workaround where I set the date to a temp variable and then use code to format it.
question: | Date fields:
- Select Date: temp_date datatype: date
code: | test_date = temp_date.format('MM-dd-yyyy')
What I don't understand is why simply setting the date format in the meta data doesn't produce the same result?
If you do:
fields:
- Date: some_date
datatype: date
then some_date will be defined as a DADateTime object. This class is a subclass of datetime.datetime.
If you set:
metadata:
date format: MM-dd-yyyy
then this has an effect on the format_date() function. The format_date() function can be called directly and it is also called by the .format(), .format_date(), and .__str__() methods of DADateTime.
If you write {{ some_date }} in a DOCX file, this calls str() on the DADateTime object, which will cause the .__str__() method to be invoked, which will cause format_date() to be called.
I just did a test and writing {{ some_date }} in a DOCX file caused the date to be printed in the format specified in the metadata directive. If you are getting something different, I would need to see more information in order to reproduce what you are seeing.
If you do {{ some_date | some_filter }}, then what happens depends on what some_filter does. One could write a some_filter filter that interprets some_date as a datetime.datetime object, adds 30 days to it, and returns a datetime.datetime object.
In your case, I don't know what "{{test_date|filter}}" does, so I can't explain its output.
If your filter expects a string as input, maybe you want to write {{ test_date | string | filter }}. https://jinja.palletsprojects.com/en/stable/templates/#jinja-filters.string
I just did a test and writing {{ some_date }} in a DOCX file caused the date to be printed in the format specified in the metadata directive. If you are getting something different, I would need to see more information in order to reproduce what you are seeing.
Yes this produces the same result for me, the date gets printed in teh format. My filter function is expecting the date at a string in that format.
So if I send for example, "09-06-2025" to my filter as a string, the filter works.
if datatype is not date
{{test_date|filter}} works
and
{{test_date}} produces "09-06-2025"
lI I rely on the format date functionality of the same variable with teh format in the metadata
{{test_date|filter}} does not apply the filter. it seems that test_date should be a string as implied by calling .str()
if there is a filter, is it keeping test_date as a DADateTime before calling the filter? It seems that it should render the date to a string first, before applying the filter.
{{test_date}} produces "09-06-2025"
So to be consistent with my other projects that use the same filter functions outside of docassemble, it may seem that I should render the DADateTime to string, which I did with the code work around.
It seems that this may be inconsistent in that {{date}} implicitly calls the string functionality but {{date|filter}} keeps date as a dateTime object.
so maybe yoru date|str|filter is the other workaround.
Im just used to passing JSON in to docxtpl templates so everything has to be valid json variable types which means datestimes are stored as strings.
In Jinja2, variables are not converted to a string before being passed to a filter. If using a filter in Jinja2 automatically converted the variable to a string before applying the filter, most of the built-in filters would not be able to function. https://jinja.palletsprojects.com/en/stable/templates/#list-of-builtin-filters
Can't you just stringify the input in your custom filter? Like input = str(input) at the top of your filter function. That way you get a DADateTime that is properly formatted and a string which your filter function expects. Or you could even do something like this so that you control the format of the date explicitly in your filter:
if isinstance(input, DADateTime):
input = format_date(input, format="MM-dd-yyyy")