senny / sablon

Ruby Document Template Processor based on docx templates and Mail Merge fields.
MIT License
446 stars 128 forks source link

Add ability to generate one file for few contexts #123

Closed senych-vitalii closed 5 years ago

senych-vitalii commented 5 years ago

We have faced with situation when users need to generate one big DOCX file for few different contexts - for example generate letters to contacts in one DOCX file. We tried generate files in cycle using Sablon and after concatenate all in one file, but failed, Is there some ability to do it using Sablon? @senny , @stadelmanma if there is no chance in Sablon, can you help me with direction where I can find a solution?

stadelmanma commented 5 years ago

Hi @kaleb4eg, I think I understand what you want to do since it's related to #97, which isn't possible yet. I got around the issue by using ERB+HTML as an intermediary and then doing very large content injections across a few context keys (i.e. one for the letter, another for the enclosure, etc.) in a relatively bare master template.

This has it's drawbacks, the main one being maintenance since an error in the HTML is hard to track down. The other big issue is you are pretty limited in the formatting used, I extended Sablon's HTML grammar with a few custom tags to make things easier. However, the only reason I did this was because large sections of content need changed based on context parameters.

Is there any reason you can't use a large "master" template and then merge your contexts instead of merging your documents?

senych-vitalii commented 5 years ago

hey @stadelmanma , ths for response! Yes, it looks similar. In my case I cannot use your approach because we have next process: our users can upload custom templates and we are inserting context based on different records, and as a result we will send to user a lot documents with same layout but with different context. In our case I am not sure that I can use smth like master template, because in each case it's uploaded by user and totally custom.

senych-vitalii commented 5 years ago

for merging documents I am using next gem https://github.com/parthnagori/omnidocx but it's not supporting and pretty raw but working :) as a result I have working feature but MS Word throwing error (LibreOffice can open without errors) during opening concatenated document - I fixed few issues but it seems that not all :)

stadelmanma commented 5 years ago

@kaleb4eg I wasn't aware of the omnidocx gem but I am glad you have it working to a degree. I can tell you the docx partials idea will likely be implemented eventually since it is something I need but I do not have a definitive timeline since I've been pulled onto other work right now.

If it is something you'd like to help with I'll be glad to help get some PRs in working order. The basic concept would be simple at first, just extracting everything inside the <w:body> tag and injecting it into the desired location in the primary document. Once basic support is available various features of word docs such as images, footnotes, etc. would be supported later on to avoid a monolithic change. The initial stage would be very similar to a WordML content injection. In your case it sounds like your users would supply the "partial(s)" to be injected into which ever main template(s) you need.

In the near term, I may be able to help with your error. The first thing I would do is start slowly removing chunks of content and see at what point MS word is happy. In my experience the easiest things to get wrong are the various unique references in documents such as "rId"'s for images and other content like hyperlinks.

senych-vitalii commented 5 years ago

@stadelmanma ths for plans and ideas to fix it out! Right now I am going to dig deeper in this concatenating docxs stuff. Will ping you when get smth relevant.

senych-vitalii commented 5 years ago

@stadelmanma I have fixed few issues in omnidocx gem and now it's working good for merging docx files. Here is PR https://github.com/parthnagori/omnidocx/pull/4 . And yes, you were right - there were few small defects but the main was in elements ids :)

stadelmanma commented 5 years ago

@kaleb4eg I'm glad you have a working solution! You can subscribe to #97 is you wish to get updates when I eventually get around to supporting this type of feature in sablon. Although the implementation will likely be considerably different since we won't be merging docs head to tail like I think omnidocx does and instead injecting documents into various places based on the context key.

In the meantime I'm going to close this issue.