JSReport -- working with docxChild. I can't resolve the error : "docxChild helper requires asset parameter to be set" - word

I'm trying many functionality on jsReport and word and got stuck on this one.
I want to create an asset usable in different template, assuming that my asset got the right data.
Using this documentation and the UI jsReport Studio I create a working template called test-word, I upload a docx test_jsReport.docx with some ahnddlebar in it, create some data and it work.
Then I create an asset, in the same folder, with a second docx test_jsReport2.docx ; put some code and try to generate it alone with the same data, it worked again.
At this point my project look like this :
test project
Then, using this chapter I add in my docx test_jsReport.docx the following code : {{docxChild "test_jsReport2.docx"}}.
So I can no longer run my report, the error is the following.
Report "test-word" render failed.
Error while executing docx recipe
(because) error when evaluating engine handlebars for template anonymous
(because) "docxChild" helper call failed
(because) docxChild helper requires asset parameter to be set
(system-helpers.js line 706:11)
704 |
705 | if (assetNamePathOrObject == null) {
> 706 | throw new Error('docxChild helper requires asset parameter to be set')
| ^
707 | }
708 |
709 | const docxChildInfo = {}
What is that aset parameter that I need to set ? And how to do it ?
I'm pretty sure that I should omehow declare some kind of link beween my two reports, but I can't find how to do that.
First I tried to use the asset property in jsReport studio on my report, like this :
first try
But it doesn't worked and I never really believe it, I think it's an option to define a link to the physical docx I modify, so I don't have to upload after each save.
Second I read and try to mimic some other systems I can find in the doc like this and that and but it's for HTML report not word.
Lastly I tried to reference my report using a script like this :
const jsreport = require('jsreport-proxy')
// Use the "beforeRender" or "afterRender" hook
// to manipulate and control the report generation
async function beforeRender (req, res) {
await jsreport.assets.registerHelpers('test_jsReport2.js')
}
It doesn't work either.
I'm a little lost here, what is the right way to use docxChild ?
Here is a link to an example of what I do : https://playground.jsreport.net/w/anon/Pm_vIEwF
Here is how I setup the example :
I prepared my two word
Right click > new entity > template
Select handdlebars and docx > next > next
Click on my template > in properties, in docx I upload my main.docx
Right click > new entity > asset > upload, i put my subreport.docx

The docxChild feature works by searching a docx asset and take the content of such docx and insert it into the docx it was called from. You have follow the right steps, but the only issue is that you are using different characters for the quotes in your docxChild helper call. It was perhaps not your intention, for example on macos i noticed that whenever i try to use " it replace it for the characters present in your docx, so maybe if you are using macos this is the problem you are having.
Your original template
What should look like to have it working
I've prepared a playground example with your same code but fixing the docxChild call to use the right quote characters "",

Related

Word addin, set filename

If one starts a blank file on Word you can usually see in the top bar a name such as "Document1", "Document2" and so on.
Yet, if you attempt to open a file using the Word JS API like this:
Word.run((context) => {
context.application.createDocument(documentB64).open()
return context.sync()
})
The top bar comes out like this:
No filename is set.
To set a filename/handle(?), I tried using the code given here Office JS - Add customProperty to new document but that didn't help.
My addin is usually used in conjunction with another (VSTO) add-on and that add-on can't work properly with the documents opened by my addin and I believe the lack of a filename (/handle?) explains it to some extent.
Is there something I can do about this?
Thank you
Currently you can't do this because the newly created document is just a temporary file and not saved. can you try to call the following code to make sure the newly created file is saved?
const documentCreated = context.application.createDocument(externalDoc);
documentCreated.save();
documentCreated.open();

Can you get access to a pages front matter (or other data) in a eleventy (11ty) plugin

I'm creating (would like to create) an eleventy (11ty) plugin that can automatically generate Open Graph images based on a pages data. So in the template:
---
generate_og_image: true
image_text: "text which will be baked into the image"
og_image_filename: some_file_name.jpg
---
#some markdown
...
I can process each file in my .eleventy.js file via plugin using:
module.exports = function (eleventyConfig) {
eleventyConfig.addLinter("og-image-generator", function(content, inputPath, outputPath) {
title = HOW_TO_ACCESS_TEMPLATE_FRONT_MATTER
createImage(title)
});
}
But only have access to the content, inputPath and outputPath of the template.
How can I access the front matter data associated with the Template? Or is there a better way to go about this?
Answering my own question. As #moritzlost mentioned it is not possible directly. I found this workaround.
eleventyComputed allows you to dynamically assign values to keys. It also allows you to call a custom shortcode.
You can pass whatever properties you like from the template into the shortcode. In this case ogImageName the image name, ogImageTemplate a template or background image and text which is the text to be written on that background.
You can even pass in other keys from your front matter and process them as you go.
---
layout: _main.njk
title: "Some title here"
eleventyComputed:
ogImageName: "{% ogCreateImage { ogImageName: title | slug, ogImageTemplate: 'page-blank.png', text: title } %}"
---
Then in .eleventy.js or a plugin:
eleventyConfig.addShortcode("ogCreateImage", function(props) {
const imageName = props.ogImageName
const imageTemplate = props.ogImageTemplate
const imageText = props.text
console.log('-----------------ogCreateImage-----------------');
console.log(`filename: ${imageName}`);
console.log(`using template: ${imageTemplate}`);
console.log(`with the text : ${imageText}`);
// call the image creation code — return filename with extension
const imageNameWithExtension = createOGImage(imageName, imageTemplate, imageText)
return imageNameWithExtension
});
Returning the final filename which you can use in your template.
I've also come across this problem. I don't think what you're trying to do is possible at the moment. There are not many ways for a plugin to hook into the build step directly:
Transforms
Linters
Events
I think events would be the best solution. However, events also don't receive enough information to process a template in a structured way. I've opened an issue regarding this on Github. For your use-case, you'd need to get structured page data in this hook as well. Or eleventy would need to provide a build hook for each page. I suggest opening a new feature-request issue or adding a comment with your use-case to my issue above so those hooks can be implemented.
Other solutions
Another solution that requires a bit more setup for the users of your plugin would be to add your functionality as a filter instead of an automatic script that's applied to every template. This means that the users of your plugin would need to add their own template which passes the relevant data to your filter. Of course this also gives more fine-control to the user, which may be beneficial.
I use a similar approach for my site processwire.dev:
A special template loops over all posts and generates an HTML file which is used as a template for the generated preview images. This template is processed by eleventy. (source)
After the build step: I start a local server in the directory with the generated HTML files, open them using puppeteer and programmatically take a screenshot which is saved alongside the HTML templates. The HTML templates are then deleted.
This is integrated into the build step with a custom script that is executed after the eleventy build.
I've published the script used to take screenshots with Puppeteer as an NPM package (generate-preview-images), though it's very much still in alpha. But you can check the source code on Github to see how it works, maybe it helps with your plugin.

Combine two TCPDF documents

I'm using TCPDF to create two separate reports in different parts of my website. I would like that, in the end of the first report, the second report should be loaded.
It's different than import a PDF file, because the second report is also generated by TCPDF. Is there a way to do this?
I assume from your question that what you ultimately want to provide is one PDF file that consists of the first PDF concatenated with the second PDF.
One quick and dirty solution is to utilize the pdftk command line PDF processor and call it from within your PHP code using the exec() function. The pdftk command has many features and concatenating files is only one of them, but it does an awesome job. Depending on your hosting situation, this may or may not be an option for you.
The other option would be to use FPDI to import the two PDF files and concatenate them within your PHP code and then send the concatenated version to the user.
More information on using PFDI here:
Merge existing PDF with dynamically generated PDF using TCPDF
Given that you're already using TCPDF, importing the pre-existing file that you want to concatenate with the one you've just created shouldn't be too difficult.
Just add FPDI to your project/composer from:
https://www.setasign.com/products/fpdi/downloads/
Can you still used tcpdf.
FPDI support all the methods of tcpdf, just used new FPDI() instead new tcpdf() the result will be the same in your report, after you create your report marge the files with the code from this page:
https://www.setasign.com/products/fpdi/about/
In a loop, once set the first file and after this set the second...
If you will need help i am here for you.

Manipulate PDF via SQL

what I want to do is automatically create PDFs with data from SQL Server 2008 R2. After creation a string shall be added in the first line of the file. This "header" has to be clear text (right click PDF -> edit -> write string in the first line) and therefore can't be added in the pdf-creation process. The codes in the header are beeing used by another job for further processing.
Is there a way to do that via SQL?
Sample data looks like:
Name | Date | Time | Place | Appointment
John Doe |2014-09-15| 11:00 | Narnia | 12:30
I already found ways to create the PDF, using SSRS and subscription or the procedure mentioned here: http://www.sqlservercentral.com/articles/Miscellaneous/creatingapdffromastoredprocedure/1104/
But I wasn't able to write text to first line, just appended it at the end of the file.
Any help is much appreciated!
This can not be done in SQL. There are a few options that I now of that you can look into to see if it will suite your needs.
NOTE : These are not trivial tasks.
Implement your own device renderer, falling back on the default pdf render.
Override the built in pdf renderer to add your custom header.
Use the SSRS web service api and implement the Render method allowing the access to the Pdf as byte[] and further manipulate it to your needs.
The 3rd method would be the most straightforward and ideal method and would work in both web and windows apps.

Moodle local plugins and save_file

I've created a working form within a local plugin and it is inserting data fine into my custom table.
What I want tyo add now is a filepicker element that upon saving the form puts the file into a specified folder.
The filep[icker itself works fine but when I save the form no file appears, the code I'm using looks like this:
$mform->save_file('lowresCh', '/my_form/', false);
I've tried various things in the 'my_form' bit, but to no avail. The rest of the form still puts its data into the custom table and I can see my file in the mdl_files table (marked as draft).
With full debugging on I can get a warning of:
Warning: copy(/my_form/): failed to open stream: Is a directory in /...../lib/filestorage/stored_file.php on line 390
I don't know if I'm approaching it incorrectly or not, any help or pointers in the right direction would be most appreciated. 
Oh and I have read the Using the File API in Moodle forms page, useful in getting me to the point I'm at, but no further.
I solved it by using the filename as the second argument in save_file() and if I prepend a directory then all of the files will be saved within my plugin in a sub directory which is perfect.
So it looks like this now:
$mform->save_file('lowresCh', 'files/'.$mform->get_new_filename('lowresCh'), false);