 All right, this is PDFs in Drupal. I am excited about how many people have turned out for this. This is something I've tried to be teaching for a while now. Tried to get a session for DrupalCon for a couple years. And just the fact that this room filled up the way it did represents that a lot of other people are passionate about this, or at least have to work with us all the time. Who am I? My name is Dan Hansen. I'm a lead developer at Sava Group Inc. We do managed services. We do hosting. We do development, obviously. Mostly Drupal, but we don't really pigeonhole ourselves. We also are a WordPress shop. We also are a generic PHP shop. We do everything from code development to reports creation. There are still a handful of seats around, if you guys are filtering in. Not a lot, but a few. I've worked personally with Drupal for seven years. And I'm an awkward certified developer. I think it was the D7 test. I'm working on the D8 ones. And I'm generally pretty cool, in my opinion. I always got to throw in a bat-dan picture. I'm usually hairier than this. I tripped out a few guys. But you didn't come here to hear about me. You came here to hear about PDFs at Drupal. So why is that important? PDFs are used, by and large, as a universal document format. You can send somebody a doc, or a docX, or an Excel file. But there's never any guarantee it's going to be opened or look the same. Might not have the same fonts. Might not have the same images. There could be relatively linked files, which is also occasionally in PDFs. But PDFs are used to sort of stabilize a document and send it in a way that everybody can look at it in the same way. It was previously a closed format, something that Adobe created. And it was previously an expensive format because it took a very pricey Adobe software or third-party software to try to create and manage PDFs in any reasonable way. But the goal of this talk is to sort of get a foot in the door in trying to make PDF handling as ubiquitous or well-supported on the web, and particularly at Drupal, as image handling is. And PDFs in core. We've got these great image libraries all throughout Drupal Core. Or at least being leveraged in Drupal Core. It would be lovely to see some of these PDF libraries sort of join the fray. Maybe not something as large as done PDF, but something small that could manage different pages. PDF.TK, some sort of expansion of that would be lovely, in fact. So let's talk a little bit about PDFs. PDFs are based on PostScript. If you have ever worked with old printer drivers then you'll recognize the .ps format, which is how your computer would send files to printers in that PostScript format. It was a proprietary format from Adobe created back in 1993. But nowadays, as recently as 2008, it's actually a recognized ISO standard. And having said that, there's also a PDF 2.0 standard that's actually even more recent. I think it's 2017. Same ISO code, just I think it's 32,000-2. So easy to remember. The idea behind PDFs was to bring together that PostScript-based document layout format with font embedding and data storage that would allow it to be compressible, make it easy to pass a document around. So it really is designed to be a layout tool. We're not repurposing an old file format for something that's not meant for. It's really designed to make it so that everybody can see the same thing at the same time. But there are three key things to make PDF special. First and foremost is rich media. When you look at PDF, you can see images, you can see SVGs, PNGs, JPEGs. If you're working with really specialized PDFs sometimes, I've seen videos at least linked in PDFs. But the idea is that you could bring in sort of rich media to have at least some exciting graphics to look at instead of just text. Another thing that makes PDF special is security. It's possible to encrypt PDF, make it password protected, make it so that only people you want to see it can see it. I wouldn't lean on any sort of PDF encryption. There's always ways to break encryption and as old as this format is, I'm sure somebody's found a way to snap it in half at their whim, but it is possible to semi-secure document. And finally and most importantly, standardization. Like I said, everybody can see the same document. It's got the same layout. It's got the same pictures. It's got the same fonts. That's sort of the key. So knowing what we know about PDFs, let's move headlong into PDF rendering libraries. And let me know, I tend to dance around with the podium. So let me know if I get too far for the mic and you can't hear me. PDF rendering libraries. Print to PDF. This is not actually a library. This is really an important consideration you want to make before you start trying to make PDFs on a webpage or website that you're creating. Do you actually need to generate these PDFs in code? Chances are you don't. Specifically, the example I'm thinking of is the content pages on a site. If you're creating PDFs on the back end of the site, it's really unnecessary. Most modern browsers have print drivers. I don't know if you'd call it driver at this point, but methods of printing to PDF that do an excellent job of taking care of that sort of output. It's also very easy to control using print style sheets. So if you have the option, if you don't have the need to actually create a PDF, I would highly recommend just letting the user print to PDF with a print style sheet. So how do you determine whether you do need to generate PDFs? You generate PDFs if you require precision layouts. By this, I generally mean forms, but it could be something simpler, like maybe you're trying to create a certificate and you've got all this great art, but you just want to make sure that there's a name and place in the right spot. You generate PDFs if you need to implement a template. This is also kind of a form thing, but if you've got a stylized header or something, instead of an entire page worth of form, then you could maybe use a template for that. And then finally, if you need to implement security features. This is, again, not something I would particularly rely on, but is definitely something that would be available if you are generating these PDFs. All right, let's talk about some proper libraries now. First is JS PDF. It's a client-side rendering library as implied by the JS in front of the PDF. I'm not going to spend a lot of time on it because this is a back-end dev talk, not a front-end dev talk, but it can be used to render HTML with the addition of HTML to Canvas, or Rasterize HTML, which are also component JavaScript libraries. I've not used this exclusively. That's a wrong word. I've not used this myself, but from what I can tell of the library commands, it reads a lot like what you'll see on some of these other sort of PDF generation libraries. You get the basics, you could create squares, round of rectangles, text boxes, those sort of things, lines across a page, and then you've got the option to create HTML with these other libraries as part of them. You can find that library there. I will try to post these slides online. I've got a Twitter handle, Dan at Sava, you'll probably be able to find those slides there after the talk. So rendering libraries, FPDF. This one's an oldie. It's a server-side, 100% PHP-based rendering library. That's the web address, but it's not been updated since 2015, and there are a lot of things that have come after it. Particularly libraries like MPDF. Again, another server-side, 100% PHP-based library, but it's based pretty closely on FPDF and HTML to FPDF. The big difference between the old version of FPDF and MPDF is that MPDF offers improved language and UTF-8 handling, so you're gonna have a lot less times where it crashes because of the umlot. The problem with this library in particular is that it's noted in its own documentation as slower than the original tools, and that comes kind of part and parcel with the expanded feature handling and language abilities, but it's not a bad tool. It's pretty lightweight. You could stick it on a site and really get some basic PDF generation done pretty quickly. There's a site for that. TCPDF is another one that's very close to FPDF, and probably got a lot of its motivation and inspiration from FPDF. It's also server-side generation and 100% PHP-based. The biggest issue with TCPDF right now is that there's a new version being worked on, which means that the current functional version is obsolete, and no longer receives actual feature updates. That being said, it's still a powerful library. It does a great job of doing HTML to PDF. Not my highest recommendation, but definitely something that you could put in place if you want some basic PDF generation. Another caveat, the old version of this doesn't work with PHP 7.2. Again, sort of a function of it being older and not getting any updates, but it can be patched to fix that, and I'm sure people will keep coming out with patches as long as the new version is sort of coming down the pipeline. Renewable libraries, FPDI. This is a server-side library as well, but it's sort of a bonus library. Works for FPDF, and it also has capability to work with TCPDF. Offers you a lot of extra features, one of which is allowing the use of PDF files as templates, which is to say you can pull a single page from a large PDF and then just use that to create a new PDF. There's also some FPDI extension libraries that are very handy. The one that I would single out would be FPDI Protection, I believe it's called. That can be used to encrypt PDFs and attach passwords and those security features we were talking about before. You can see that information there. One big caveat on this is that if you were trying to do a PDF that's above version 1.4, I'm trying to, I don't know exactly where that feature set lies, but there will be a paid add-on that you'll have to get to actually use features with those types of PDFs. It's not incredibly expensive, licensing's a little confusing, but we've used it in the past. So it's very successful on more recent versions of FPDI, but that's something you really only need to worry about if you're not actually generating your own. Chances are that'll only come into play if you were getting files from third parties and they don't have control over versions or feature sets and you're trying to use those. The one you've probably heard of if you've been in this sector is DOM PDF. Server side, 100% PHP base. I didn't mean to do dramatic fades here, just kind of happened. This was stuck for a very long time on version zero, six zero, if I remember correctly, but it's back to active development after a long static stint in Google code. It also cooperates pretty well with Composer Now, which is super handy because before it was pretty rough going. It's powerful, it's widely used. There are some large issues with it, but they are well documented and there are a lot of places I can teach you how to get around them. The one I tend to run into most of all is that if I am using any sort of tables for layout and have a page that, or have a table rather, that goes longer than the length of a single page, it will run into a very large render loop and probably eat up all your RAM and generally probably crash eventually. There's also no float support. Officially actually it only supports CSS 2.1 and HTML5, so you're not gonna get the fun things like CSS Grid or anything like that. But that's pretty common in these HTML to PDF libraries. It's pretty rare you'll see anything that can actually take more modern CSS and implement it in a way that's gonna be useful. WKHTML to PDF, this is a server-side library as well but is actually not PHP-based. It's a software binary. It's actually one of the better ones that you can use. The WK in WKHTML to PDF actually stands for WebKit. So if you're used to building sites and operating browsers that use WebKit, then you will have a better time. You'll get what you expect when you go to render a PDF to HTML or an HTML file to PDFs. Because it's a software binary, you have to use an interface like PHP, WKHTML to PDF to get it to work with Drupal or other PHP applications. Not a huge issue with Composer but something you do need to be aware of. As I said before, it's predictable rendering. Use the WebKit engine. And this is definitely your best option if you can get it to work. It's not hard to get the binary but if you get the binary and you get the wrong version and you don't have an X server running, then you either have to have that X server or have an X server simulator. XVFB I think is the one that comes in line. But I did recently find that there is actually a pair of Composer-Based libraries that you could just drop in place. Drupal in particular, sees it worked pretty well with these. There's a i386 version and an AMD 64-bit version. I haven't seen much difference. I'm sure the 64-bit version will use more computing and processing but they seem to be able to drop in pretty right readily and as long as you configure correctly, do the job quite well. So no longer do you have to worry about the binaries being working or functional or even installed. You should be able to grab this through Composer. PDF-TK, this is another server-side one that is a software binary. It's more of a PDF manipulation tool but it's incredibly useful. Offers things like the ability to easily add and remove pages, combine PDFs. You can, the word escapes me, abbreviated cat. Somebody shout it out. You can catenate, thank you. You can catenate PDFs in such a way that you can pull pages from the beginning, middle end of a particular PDF, pull pages from a different PDF and just stick them all together in any order that you want. Very cleanly, doesn't use a lot of RAM. This also offers you ability to fill PDF templates with data. So if you have a form that's been built out into PDF and you want to either offer that form for available for download for somebody to fill out manually or if you have their information you could pre-fill those fields. This is capable of doing that. Lightning round, there's a lot of other libraries and I'm probably not even scratching the service but these are just a handful you can look into if you're interested doing server-side rendering of PDFs. Most if not all of these in particular will not have extensions related in Drupal and or will not have easy PDF, or I'm sorry, easy PHP implementations but they're out there. It could be up to one of you guys to write a wrapper class for something like Zen PDF to get that to work in Drupal. The more options we have the better but these are just not really ready for Drupal use just now. Speaking of Drupal, let's talk a little bit about some of the PDF modules that are out there for Drupal 8 right now. I specified Drupal 8 because there are a lot of PDF modules in the Drupal 7 environment that have just not been updated or upgraded to Drupal 8. Some of them are leaving some gaps in the ecosystem but some of them were superfluous to begin with so it's really up to the person controlling the module as to whether or not they're gonna come over ever but we have a couple of modules now that do the job quite well for what most people need. If you worked with Drupal 7 PDFs you'll remember printer email and PDF versions. Well there's a Drupal 8 version now, they call printable. It is more or less the same thing but is not my top recommendation. I just got stable as the end of last year. It also relies on some module, the PDF API module which unfortunately is not yet stable it's actually still in development. The big issue with that is that PDF API does not install without the older version of DOM PDF. So you can use this if you're comfortable with using the feature set of DOM PDF 060. You won't be able to use the newer 080. That's a little more stable. My recommendation for actually rendering PDFs right now is entity print. It's got a flexible library selection very similar to the printable module. There's no version issues you can call current branches for all of those libraries as far as I can tell. And it doesn't seem to have any upper cap on anything so there may be bugs but it should be good moving forward now. And it's in my opinion the best replacement for the old print module. Yes, but one of the examples we're gonna go over a little bit is really just how to render outside of an entity. It'll be the same libraries and it's actually usually pretty simple to do but the entity print module is actually going to be the only way is going to be only printing entities which fortunately, you know, Drupal 8 made everything kind of into entities so you should be pretty able to print everything. I think this also includes an extension module that allows you to print views but you're right in saying that it's focused on entities. Another useful PDF Drupal module is Phil PDF. This has been around for a while and it's pretty handy but it doesn't exactly what it says on the tin. It fills PDF templates with data. Basically the form methodology that I was talking about talking about before where you build a form at a PDF and then you can actually take that PDF pre-fill those fields, uses that PDFTK module or software or you can actually use it to leverage a third party service if you don't have the ability to install PDFTK on that system. The third party service is paid but again, it's one of those things that's probably going to be a monthly fee for however long. Because of it using PDFs as templates and because you can actually opt out and have it be rendered sort of off-site, it'll greatly reduce the overhead of creating PDFs if you could use this module. But again, not everything's going to be able to be templatized. So now let's go into some examples. Student PDF tricks. We'll see how many of these work. So you want to make a PDF from HTML. Use entity print with WKHTML to PDF or DOM PDF. That's what it's built for. But of course, what if you want to build it based on something that's not an entity? Well, let's take a quick look at the demo as to what that might look like. Actually, so I've got these demos. I'm running a Drupal 8 instance fully upgraded on doxel. If anybody's not using doxel or DDEV or something similar like that for containerized local development, I highly recommend it. This is also completely based off of Composer which I will crack that open in a little bit and we'll take a look at what all's being included there. But very straightforward here. Demo one, we'll make a PDF from HTML. We'll just click here, generates PDF for us. Very basic, using the HTML that we just saw. We can also use an image in our PDFs. This site's actually supposed to be a work in progress fan site for this game called Dropmex. We haven't played it, very fun. So let's take a look at the code behind that. This is just the, I have a basic module here. Just a little bit of routing to do pages, Drupal 8. Nothing in the module, a little bit in the info, but most everything here is based on these controllers. We'll take a look at this first controller. Key points to look at here. We're including the DOM PDF library here so that we can use it within the controller. I've got just a quick bit of mark up here. That's all stuck into a string. You can see this example, and I'll actually post this code alongside the slides once I get it online. But this example was pulled directly from the DOM PDF documentation page. It's very basic. The DOM PDF, you create a new one. You load the HTML that we define up here. Come down and you can set options like the paper size, letter and orientation landscape. Then you just render it and you stream it back to the user. The other one, the second one that actually used an image is not too different. The biggest difference is actually trying to retrieve the image. You'll have to use the internal path within the actual server as opposed to trying to reference it from outside. I believe there are DOM PDF settings that you could use to reference files externally, but this was the fastest way to get together an example in time for this. So that's basically how you would put together your basic HTML to PDF outside of an entity. It's gonna be basically the same for anything else that renders HTML to PDF. Obviously the function names will be a little different, but everything that I've listed in the presentation so far has different information about what those functions are called and how to access them. Their documentation's gonna be pretty complete when you look it up. So let's take a look at our second example here combining two PDFs. The best way to go about that is actually to use that PDFTK library and a wrapper that makes it accessible to PHP such as this one. This is actually available through Composer as most of these libraries are, so that's pretty handy. We'll take a look at the demo here. So demo two combined two PDFs. We'll look at this real quick. Basically have copies of those original PDFs that I generated back on the back end here. So you can see they're not any different than the ones that were generated before, but now we're going to combine them and click Link. Outputs PDF and you can see both those PDFs are together in here using PDFTK. Let's crack open the code on that one. So this is really straightforward with PDFTK. You'll include the PDFTK wrapper and the PDF class and then you just define this new PDF. You give it an A and a B and however many documents you want to attach together at the same time. One thing I have run into in the past on this is if you're trying to do a dozen PDFs and combining them together, much better idea to do them all at the same time instead of sticking on one, saving, sticking on one, saving, you will crush your site that way. So if you've got all the documents, put them all together at the same time. Again, you'll see we're attaching through this document root base path. That's just going to be your best default way to sort of access any file in the system if you are able to do that. Let me actually go to the example set I have listed here because that's got a bit more, see I was pulling gifts until the last minute here, nice. That's got a bit more robust example that we can take a look at, specifically looking at the cat. You can see here, you've got PDF with multiple pages and you're able to pull pages one through five and then if you want to set an array of pages to pull you pull seven, four, nine. And if you needed to, in that way you could actually just take a regular PDF and cut down the amount of pages you had on it. You also have the ability to specify password if you need to. A lot of different documents that you can specify. So if you have things defined as A and B you can actually pull from A, from B, and so on and so forth. A lot of functionality in this PDFDK library. That's very handy. So let's look at this one. Not sure why I made slides for each of these, slow down things. So we want to dump a generator PDF into a file field. Very easy to do with TruePlate's entity handling. So let's take a look at a demo. So dump PDF in the file field. So I've actually created a node. The node has a single field, field PDF field. And now this file has been dumped into it and it's very familiar. So we'll take a look at the example three controller here. I think we've added a couple libraries here. Notably the node library so that we can generate the node. Excuse me, the file library so we can generate the file. The PDFDK library, that was something we already had handy. URL and redirect response are two libraries that we're just using to redirect to that node after the fact. Most of this, at the top seems familiar. We're just concatenating these two PDFs and then we'll execute that so the concatenation is actually complete. And then we'll grab the contents of that file using this git temp file here and file git contents so that we have that in a string. And then everything from there is all Drupal-based. So we'll save that string using file save data, give it a destination, set it up in the public file directory, add name to it, rename if there's more than one, and then we'll create the node like normal. Node create, type title, and then in the field in particular we'll have the target ID of the file. We add an alt text, we add a title text. And once that's all wrapped up, we'll just save the node. And from there we'll just redirect so we can actually look at it once it's saved. Now I've talked a little bit about templates, now we're gonna see how to actually fill one out. If you can use fill PDF for it, it's obviously what it's built for, but sometimes you wanna do it programmatically. So we'll use PDF.tk and its wrapper again to do that. So we'll take a look at the original template first. I've got a PDF here that I created in Adobe Acrobat, very basic, literally just this text and then there's a text field down here that you're able to fill in. The key to this is that you have to remember the names of those fields. So in particular this one is called text with capital T1. If you don't have those names, I believe PDF.tk has specific functions that allow you to retrieve those names, but it's much faster obviously just to remember them if you're able. So we saw that, we'll see the generated one here. It's just got, woo-hoo! Cause we're excited, right? Yeah, excited. We filled it out. We're as good as someone with a keyboard. Take a look at the code behind that. The libraries, again just a PDF.tk wrapper library. Here we're just calling it in the way that we know how, and then there's a specific full form actual function here that lets you specify the name of the field and then the value of the field. Obviously it's gonna be a little bit different for things like radio buttons, text buttons, check boxes, things like that. Select boxes I think are a little weird too. There are definitely more complete examples of the PDF.tk wrapper demonstration site. And I had a fifth example, but I don't think that actually got wrapped up, so I think that might actually be it. So, questions? If anybody has any, feel free to line up to the microphone. We want to get that captured on the recording. So, do you happen to know if any of these libraries work with some of the modern print CSS features like chapter headings and page numbers, page offset for printing? I'm not sure if anybody can hear him. Can anybody hear him? Okay. The question was, do any of these libraries work with some of the more modern print CSS settings like page breaks and things like that? And I can honestly say sometimes, I think your best bet is going to be with WK HTML to PDF just because it's got the webcam library backing it. I know there's limited support as well within DOM PDF, but I wouldn't lean very heavily on it. Your best bet for those sorts of CSS is going to be print to PDF. That's where you'll see most success. But even the browsers are sort of hazy about which one support, which by and large, some of my solutions will usually include something that looks at the length of the page and is like, oh, hey, I'm not sure if this is all going to fit and will break down individual pages. So you may end up having to create a solution like that as well. Do any of those engines create tagged PDFs for accessibility? I don't know off the top of my head. Even if it brought in like the HTML tags, could potentially, could we use the valid PDF tags instead in the template instead of HTML tags? I admittedly don't know very much about accessibility tags and how they work within PDFs. I would say some of the older libraries, you're not going to stand much of a chance of seeing that in there because most of what they do is just render lines and boxes and things that correspond to what the HTML actually shows. It won't actually bring over any sort of accessibility features or classes, things like that. Again, that's another situation where you may have more luck on something like WK HTML to PDF, but I'm not sure even on that. That was actually my question. So I can just say what we've found so far is none of the PDF libraries that you've talked about support tag PDFs. The closest we've been able to get is to use pre-tagged PDFs and fill in boxes. That works the tags. The HTML tags don't translate to accessibility tags, so that doesn't work. But if your content is structured enough that you can just fill it in, then that works. But if you have dynamic tables or dynamic box sizes, that doesn't work at all. Yeah, that's an excellent recommendation. Anytime you can use a template in PDF as the basis for something you're actually able to generate, then that's going to be, A, a lot faster because you've got a lot less information actually to render or complete. And B, as he said, you're going to have those accessibility functions available to you when you generate the initial PDF and those will carry over once that's filled out. Yeah, and one of the issues I had with PDF generation is performance and the other one being with HTML, like rendering HTML. That being said, what would you say is the most well-rounded PDF generation tool, meaning it's fast and it basically renders everything the way you'd expect? Again, I'm going to go back to WKH, you know, the PDF. The best part of that is it is a software binary, so it's going to run outside of your PHP process in the first place, which means it's not going to hold up the website even if it is, you know, run slower. It may suck some resources from it, but it's not going to kill, you know, rendering the rest of the site. Obviously, there are some libraries you can run separately and distinctly, particularly for running containerized environments. DOM PDF most notably is a thief and scum when it comes to holding onto resources and also is known to crash in the ways that I described earlier, but it's, as far as a drop-in solution, it's one of the better ones for rendering. A happy medium is probably somewhere along the lines of MPDF. It's going to be an older library, it's not going to handle nearly as much stuff, but it is, or I'm sorry, MPDF or TCPDF, but those seem to be pretty lightweight when it comes to rendering. Okay, great. Hi. I was wondering if you had a recommendation for a library that has particular support for multilingual PDF generation, in particular non-standard character sets like Chinese or Arabic? Anything past MPDF is going to have more success. There's better language support, but as far as going, as far as like even right to left, I can't guarantee any of those libraries are going to be great. So we use DOM PDFs. Yeah. Have you tried WKH to PDF? No. Okay. I'd recommend trying that, but again that's going to be sort of a gray area, honestly, until you actually get into code and paper basically. But that's because it's operating based on the WebKit engine, you're going to see probably more success just because the WebKit engine will support something like that. It's probably a quick question for you, but using the Phil PDF and having a template base, is there a way of using that library that you can actually hard code in coordinates on the page? That's a good question. If you were trying to place an image. Well, it's more or less for like a name, like we put the name of the person that's using these forms on the bottom of every page of the form. Okay. So we have a library right now and they'll do that in WordPress, but we're going to be converting over to Drupal, so I was just curious. Honestly, the best way, if you're planning on using Phil PDF, which means you're basically coming in with a template, I would just have another field at the bottom of that template that says, you know, call it name or something. You use the same field as in the same field name. Yeah. It should just fill all of those. Recursively all those with the same name. Cool. All right. I had a comment and a question. Sure. Someone had asked about InstyPrint and you can definitely print views like with contextual filters and everything. So we're doing that with web form submissions to create certificates. Excellent. I was wondering if you had any recommendations about printing something like a Drupal book as a PDF? I honestly haven't tinkered much with, you're talking about the book module in particular, out of like, is that still around in Drupal 8, honestly? I don't have much experience with it and I can't say it will render perfectly because I don't think it's abuse based and I don't think it's entity based. It really is kind of its own thing, but I'm sure with some experimentation you could probably get it to render. Basically, a lot of times what I end up doing is I'll make, you know, a render array out of everything that I want, similar to how you would do a form or a page and then dump that into the DOM PDF. So if you can get a render array of the book, which should be relatively simple, I think that's probably in the module, then you should be able to render that and then spit it out into DOM PDF creation or something along those lines. Thank you. Sure. Maybe my question is a little misdirected, but I actually have more of a reciprocity. They're like a file sharing type setup and we want to take the PDFs that are there and create images so that, you know, they can have those thumbnails and stuff. And we have that as the basic module, except it messes up our tracking and sort of saving sort of structure. Did you have any recommendations on modules that work like that? That was honestly going to end up being my sixth example if I got to finish the fifth one. I don't have a specific recommendation. I know some of the libraries are pretty handy for generating those thumbnails, but beyond that, there was a question in my mind at least about where those thumbnails were going to be stored, because there's obviously going to be now a second file corresponding to that first one, unless you're generating it on the fly, which is going to be very expensive performance-wise. So short of coming up with a new field that basically tracks two files instead of one, I don't really have any recommendations for that. But I think FPDI does... I know it does thumb nailing for like an entire PDF where it will list the thumbnails. One of the examples they have there is that it'll list all of the thumbnails for the entire PDF in a single PDF for you. And as a component of that, it actually is generating those thumbnails. So that's probably the library I turned to for the thumbnails, if you're not using that already. But outside of that, what to do with those thumbnails? Not really sure. You probably have to come up with a custom field implementation. But I have a question regarding styling of PDFs. Sure. There are times when floors are not working, and I have personally to use non-breaking spaces. And then there are times when margins are not working. So what's the best approach? Say we have two-column or three-column layout in a PDF. So how will we do it? Should we use tables or tables or the non-breaking space is the way to go? The best way, well, not the best way, honestly. The way I've usually approached it is to go with tables, particularly if I'm using something like DOM PDF, just because that is guaranteed to work, even though DOM PDF uses an older version of HTML, older version of CSS. If you're using something like WK HTML to PDF, you'll probably have more options available CSS-wise as to how to organize that. You'll get floats. You'll get maybe even grid. I'm honestly not sure. But you'll definitely get floats and be able to arrange content that way. So I'd recommend probably that library and try to use as modern CSS as you think you need. Anything? Any other questions? All right. Well, thank you guys for joining me. Like I said, very excited about this technology. I'm glad you could make it.