By Daniel Wood, 25 September 2019
That was the pre FileMaker 16 days, dating back to the introduction of web viewers in version 8.5. Printing web viewers back then worked pretty darn good.
Then in FileMaker 16 things changed. All of a sudden web viewers that render content fine in browse mode, would fail to render when in Preview mode, printed, or saved as PDF. The exact reasons for this change are murky and unclear.
In this article we cover a really simple and easy technique you can quickly add to your own solution to start printing web viewer content. No plugins are needed and no external OS level scripting or screen capturing required.
Is anything these days not solvable with an API? I like to think not. When looking for a solution to a problem such as this, my first option is to look for an API that can do the job. So when looking for an API to solve this issue I looked for one capable of rendering html content.
The results took me to phantomjscloud.com.
PhantomJsCloud is a cloud based variant based on the same principle. It has a restful API where you can request the API to render a website and return the rendered site as an image, pdf, text or json.
Where PhantomJsCloud is really useful for us as FileMaker developers is its ability to render specific html code you specify, and it is this feature we use to print the web viewer.
Setup of the API is really easy. The API is free for up to 500 calls per day - more than enough for most people. With it you get an API key that you use in each request. There is no additional authentication required.
The steps involved to print are:
That's it in a nutshell. We'll go into a little more detail as to how the setup and post request is constructed, but that is really all there is to it.
I encourage you to download and try out the example file for this article. You can use it to follow along with the rest of the article.
Simply go to phantomjscloud.com and sign up for an account. Verify your email address, and when you sign in on the dashboard screen you'll find your API key, that's really all there is to this part.
If you require more than 500 requests per day, there are pre-pay options or pricing plans available, but we think most developers won't need more than 500 a day.
There are so many different ways to render code in a web viewer. Some like to use a Data URL to render html content stored in a field or variable. Others might like to export their files to disk and reference them via the web viewer URL. Others might use a plugin to render content.
Whichever method you use, you're going to need your html code to be available to you in a script so that you can pass it to the API. If you simply display a standard URL in your web viewer than you are all set.
The API can accept either html code, or a URL to render.
using code in a field, rendered using a data URL.
The API request is a POST, and for this we'll use the "Insert from URL" script step, and some CURL parameters.
The URL for the request is pretty simple, it's the PhantomJsCloud site URL with the API key included:
The request is formulated as JSON, and sent as data in the CURL part of the request as a POST.
In our example file we have done the heavy lifting for you and written a standalone script you can use in your own solution. In it we've included the basic request parameters used, these include:
When it comes specifying what to render, the two key json key parameters are "content" and "url". If you are simply rendering a URL, you specify the URL, and content can be empty.
If however you specify content, then the content parameter will include your html code. The URL parameter must be set to "http://localhost/blank" for it to work.
We send the request as a POST using CURL options as shown below. The $body variable contains our JSON request.
The response from the API is typically an image (unless you specify the text or json options). So you simply set the result from the Insert from URL step into a container field. When done, now you have an image in a container that you are able to print however you wish, and that's all there is to it!
Rendering code as an image using an API is a really novel way to render the web viewer. But there are other interesting applications to this API. One of which solves an issue I had recently when developing the Elemental solution. In this solution some of the APIs I integrated with would return the result as an SVG image. This meant that the SVG was unable to be rendered in a container field, and so for those examples, the image had to be rendered in a web viewer only.
This meant the image - in this case an avatar - could not be easily used by a developer. It couldn't be rendered in a portal (web viewers don't render in portals), and so the only option is to convert. In Elemental, my solution was a clunky web based method that was unreliable. It involved rendering there SVG in a canvas object in a web viewer, then converting the canvas to base64 encoded PNG. In order to extract the PNG out of the web viewer, a callback URL to a FileMaker script was used and the base64 encoded image passed to the script as a parameter. However there were 2 major issues:
The technique was abandoned. However in using this technique, I realised this actually solves the SVG conversion issue really nicely, here's how:
In the example file for this article you'll find this exact technique as a working example. It can be used to convert any SVG of any size or complexity to png or JPG quickly and reliably.
We've used the API purely for rendering a site as an image to suit our needs. However the API is pretty cool and does some other potentially useful things, such as:
You must take caution when using any API, especially if you are sending it sensitive or private confidential information in your site or code. Any information you send to the API could be stored on the servers at their end, and so make sure you only use this for generic purposes where you are not using information you wish to keep private.
If security is a concern, then consider purchasing phantomJsCloud enterprise plans. These are private cloud instances dedicated to your solution.
We've found this to be a really easy to implement and reliable way to render web viewer content generated directly from FileMaker. The API takes around 1-2 seconds on average to return the rendered image (usually 30-40kb in size). Other methods we tried involved plugins that screen capture the web viewer part of your screen. The issue here is around resolution and size of the capture, it is quite limiting. The API gives fuller flexibility around this. Not to mention no plugin is needed. This one is definitely worth checking out.
We always strive to provide the best example file to help you understand the article and get a head start on implementing techniques found therein. Please download and try it out for yourself below: