Description
1. remove setData(data)
and resolveData()
,
It is now possible to do render(data)
and renderAsync(data)
2. Multiple render calls # [POSTPONED]
Make it possible to call render multiple times, each returning a different JSZip instance :
const zip1 = doc.render({first_name: 1});
const zip2 = doc.render({first_name: 2});
Currently, calling render multiple times is not allowed, and will result in an error since version 3.30.2
Ideally, it would be possible to call render several times with different data.
To do this, we need to cache all compiled parts (this should be done already).
We would also need to cache all xmlDocuments parts before the rendering.
We would also need to be able to revert all zip operations (for example the image module will do this.zip.file(newImagePath, imageContent)
As this is quite complex, to do, I'm really not sure that this will be included in docxtemplater 4.
3. Reorder zip files when creating it via render [POSTPONED]
const zip1 = new JSZip();
const files = doc.render().file(/./);
files.sort((function (a1, a2) {
return a1.name > a2.name ? 1 : -1;
}))
files.forEach(function (file) {
zip1.file(file.name, file._data, {createFolder: true})
})
const buffer = zip1.generate({type: "nodebuffer", compression: "DEFLATE"});
4. Replace render
by renderAsync
render
by renderAsync
That returns a promise, that allows data
to have promises too. , This has been done in 3.5.0 with resolveData
5. Use another test runner [POSTPONED]
Jest / ava ? Finding a way to have tests run faster would be cool. First we would need to know for sure what takes most time, is it IO for reading the expected/actual docx, is it CPU for zipping/unzipping the docx ?
6. Make all modules optional [non-breaking-change][optional]
allowUnopenedTag?: "Hello }blabla",
allowUnclosedTag?: "Hello {foo"
changeDelimiterPrefix?: string | null;
disableRawXml: true,
disableLoops: true,
disableDelimiterChange: true,
rawXmlPrefix : "!!",
loopPrefix: ["if ", "end"],
dashPrefix: ["-", "/"],
To make it possible to disable loops, rawxml.
This won't however result in a smaller build (for the browser).
7. Add an official inspect module
that allows to debug the docx, and provides some utility function like getTags()
8. Make option : {linebreaks: true}
the default
9. Make option {paragraphLoops: true}
the default
10. Remove {tag:p} in following call in postparse, or pass this same value in the scopeManager call.
```
try {
this.parser(tag, { tag: p });
} catch (rootError) {
errors.push(getScopeCompilationError({ tag, rootError }));
}
```
11. Remove .compile
method
(since v4 constructor automatically compiles the doc).
12. Remove .attachModule
method
and put it in the constructor of Docxtemplater (modules
key). A question that needs to be solved with this approach is how to handle conditional modules depending of filetype, which are currently handled like this :
if (doc.fileType === "pptx") {
doc.attachModule(new TableModule.GridPptx());
doc.attachModule(new SlidesModule());
}
=> This has been implemented in #501
~~# 13. Require the use of the pizzip
module
(jszip fork intended to be sync-only)~~
14. Remove outdated methods
attachModule, loadZip, setOptions, compile methods since they are now all done within the v4 constructor.
~~# 15. Add proofstate module by default [Added in v 3.17.2]
https://docxtemplater.readthedocs.io/en/latest/faq.html#remove-proofstate-tag ? To think about.~~
16. Remove unused events for modules
For example, module.set({compiled: compiled})
is currently called before the compilation, thus it always equals to {} which makes no sense.
17. Use <a:p>
for rawTag instead of <p:sp>
see #622
18. Remove the internal property "resolveOffset"
of scope manager which is no more used.
19. Remove the getTraits
API
which is probably overkill because it seems to be used only for the "expandPair" feature.
20. Remove the getFullText
method which was just used as an internal utility function
21. Use the fixDocPrCorruption module by default :
Currently, one has to do :
const fixDocPrCorruption = require("docxtemplater/js/modules/fix-doc-pr-corruption.js");
const doc = new Docxtemplater(zip, { modules: [fixDocPrCorruption] });
22. Verify module API and add "docxtemplater" to each modules.
23 Create "lite-angular-parser" that is enabled by default.
24. Call parser just once for a given tag, instead of recursively calling parser while the result is null.
This is an idea, to be discussed.
When you have a template like this :
{#companies}
{#users}
{name}
{/users}
{/companies}
Say the data is like this :
fullData = { companies: [ { users: [ { age: 12} ] } ] }
// currentCompany = fullData.companies[0];
// currentUser = currentCompany.users[0];
The current behavior is the following for the tag {name} :
- parser("name") is called and stored in "fn"
- fn is usually :
return { get(scope, context) { if (tag === ".") { return scope; } if (scope) { return scope[tag]; } return scope; }, };
- fn.get(currentUser, {scopeList: [fullData, currentCompany, currentUser]}) => returns null because no name field
- fn.get(currentCompany, {scopeList: [fullData, currentCompany]}) => returns null because no name field
- fn.get(fullData, {scopeList: [fullData]}) => returns null because no name field
- nullGetter()
Replaced by :
fn.get([fullData,currentCompany, currentUser]);