Skip to content

docxtemplater 4 roadmap #340

Open
Open
@edi9999

Description

@edi9999

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

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} :

  1. parser("name") is called and stored in "fn"
  2. fn is usually : return { get(scope, context) { if (tag === ".") { return scope; } if (scope) { return scope[tag]; } return scope; }, };
  3. fn.get(currentUser, {scopeList: [fullData, currentCompany, currentUser]}) => returns null because no name field
  4. fn.get(currentCompany, {scopeList: [fullData, currentCompany]}) => returns null because no name field
  5. fn.get(fullData, {scopeList: [fullData]}) => returns null because no name field
  6. nullGetter()

Replaced by :

fn.get([fullData,currentCompany, currentUser]);

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions