Esther speaks to community member Bart about TextToAnything - an extension which allows generation of PDFs, QRCodes and Barcodes within Directus through the TextToAnyThing API.
Speaker 0: So the extensibility of Directus really drives me to watch Directus itself because it allows you to turn Directus into either a normal website, a CMS, for your, web shop, or even just a project's tool.
Speaker 1: Hi. Hi. Hi, everyone. Welcome to another episode of the Beyond the Core Show. It's a director who will shine a spotlight on extensions that have been created by community members.
As always, I'm your host, Esther Akbaje, developer advocate at directors. And today on this episode, I have with me Bart. I would like to say Bart is a super community member because he's really involved in community and has created a good number of extensions. So very excited to have this conversation, but thank you for joining me here today.
Speaker 0: Hi, Esther. Thank you for having me. So, yeah, as you already said, I'm very active within the community, both with helping out and also creating new extensions. So
Speaker 1: Okay. Yeah. It's good to have you. I'm excited for this conversation. Would you like to introduce yourself a bit more, maybe what you do, where you're based?
Speaker 0: Sure. So I'm Bart Lund. I'm 23 years old. I'm from the Netherlands, and I'm actually a software engineer for a company that doesn't use directors, but that, of course, doesn't matter. Yeah.
So in my free time, I've created a company with 2 friends of mine, and we're actually using Directus as the CMS for websites, web shops, and smaller back end tooling. Apart from that, I've been here since release, gonna date 42, if I'm correct. So that's almost 3 years.
Speaker 1: Okay.
Speaker 0: And I'm very active within the community. I'm trying to help out people whenever I can. So
Speaker 1: Nice. Nice. I'm curious to know, where did you hear about Directus? Like, do you remember?
Speaker 0: So I do remember we were talking about, like, what kind of CMS are we going to use? Because, obviously, Nuxt or something like it is not the only thing that, can handle data. So then we came across Trappy, and we were like, there are some limitations. It doesn't feel just right. And then we came across directors.
Back then, it was a little bit of a mess because it was a release candidate, but we really, really liked how you can extend directors and do anything with it, as you'd like. So then we decided, like, hey, we're going to do directors, man. That's
Speaker 1: Here you are. Right. Together. Yeah. Yeah.
And you've actually done so many amazing or built so many amazing extensions with directors. I know today we are here to talk about the text to anything extension. So just tell me more about it. Like, what does this extension really do?
Speaker 0: Text to anything is a generic name because it's going to do a lot of things. So the main focus right now is on generating PDF Mhmm. Both from your raw HTML if you want to provide it, or you can use a template, which is also based on HTML, but you can view it inside of the visual editor. And you can, of course, use parameters inside of it. Next to that, it's also, allowing you to generate QR codes and barcodes.
And in the future, there will also be, like, HTML towards an image or just an image towards text itself. So we have OCR. But those are just future plans for now.
Speaker 1: Okay. Okay. I I know that when I initially saw this extension, it was very exciting to me because I'd actually not seen a tool that could do so many things and still seem very simple. So, what really inspired this extension? Like, what what made you feel like, okay.
I think this extension is something that will be useful to the community?
Speaker 0: So first of all, we, of course, have to create, invoices ourselves and PDFs for them. Okay. Because we're also, so I left the company. It's a little side story, but I left the company for, like, a half year now. But we also need to generate PDFs.
We also
Speaker 1: Mhmm.
Speaker 0: Are using it like as our CMS. So we have our users, our invoices, our projects inside of, directors. So we needed to create PDFs. At first, we were using a hacky workaround. And now I actually decided to, like, create an official extension for it.
And I also saw inside of the community that people were asking, like, how can we ever create a PDF if it's not in direct us already? So that's why I decided to make an extension for it.
Speaker 1: Yeah. That's definitely interesting. I can't really wait to see it in action today. So, before we jump into the code, what what would you say was one of the most difficult things or challenges that you faced when you were developing this extension?
Speaker 0: So the main thing that's very hard about PDF is that you need something that renders the PDF. So in your browser, it's really easy because you have HTML, CSS already rendered for you. But when you're talking about only back end, you don't want to spin up a browser just to create your PDF. So at first, I started actually doing that. So I tried to integrate the browser.
It's called Puppeteer inside of your your directives, but it requires a lot of resources like CPU, RAM. And it doesn't feel right because you're make using a CMS. And for every CMS instance, you're also spawning a browser to generate PDFs for
Speaker 1: you. Okay.
Speaker 0: So to tackle that, I actually created a API, which basically, allows you to post any, HTML or whatever, and it will convert it into the PDF for you and give it back.
Speaker 1: Okay. Okay. Yeah. It makes a lot of sense. So would you like to share your screen and just walk us through, like, code, some code decisions that you had to make and just talk about what each code block does?
Speaker 0: So whenever you're creating an extension, you probably need multiple folders or directories, or even extensions themselves. So you can create a bundle a bundle to, bundle it altogether. And in my case, I have a lot of extensions that are required to make it all work. Okay. So we start off with the installation hook.
The installation hook is actually meant to create any collections that are not non existent at the moment and also add any fields if they are not there. Next to that it also talks to my API so you can actually get the pdfs or whatever.
Speaker 1: Okay.
Speaker 0: So first we actually create the templates collection so you can so we can use something to store the templates and the data about it.
Speaker 1: Okay.
Speaker 0: Then in case there are no fields yet for that collection, we're creating the actual fields.
Speaker 1: Alright.
Speaker 0: And the reason why I'm doing it like this is if something happens or you delete a field by accident the code will run next time you restart directives and it's just correct.
Speaker 1: Mhmm. Okay. Makes sense. Yeah.
Speaker 0: And then we also need an API key because there's a paywall between the API of mine and Directus itself. The reason for this is that I actually have some costs that I sadly have to make to make this API work. So in this case, it adds a field to director settings, which you can then of course populate later on. We have the same with some other fields and then we get into the actual interesting part. Yeah.
So within the global dish, which is like a global variable within your node. Yes. Runtime. I'm creating a text to anything, variable, which allows you to do any action that you can do within flows also inside of your own code. So if you have a hook or a schedule that needs to generate barcodes, PDF codes, you can just do it.
And to keep it everything as minimal as possible, Directus is using Axios. So I'm also using that to call out the API itself.
Speaker 1: Okay.
Speaker 0: Apart from that, it's fairly simple to me. I'm not sure if you see anything that makes you wonder. Likewise,
Speaker 1: you can do that. No. Just the generate PDF. You have how many, functions do you have? You have the generate PDF function.
What other function do you have? PDF template version.
Speaker 0: We have those 4 at the moment.
Speaker 1: Okay.
Speaker 0: And the generate PDF from template actually reuses the generate PDF function, but it just parses your template and make sure that everything goes correctly. Okay. So apart from that, we, of course, also have the flow nodes because you can also use them inside the flow. So one of the things that we have here is really short, basically for every flow node because it's using the, functions that I just showed you.
Speaker 1: Yeah.
Speaker 0: One difficulty that I actually had was to make a selection, like an input select field within the flows. So you can actually select the template that you want to use. So in the end I created an interface for it that allows you to do just that. You will probably see it within a second.
Speaker 1: Yeah.
Speaker 0: I'm not sure if you want to see any other things. I'm
Speaker 1: sure I I know you have a GitHub, repo, so everyone can just like, anyone interested in digging more on the code can just check it out. Yeah.
Speaker 0: So within directives, after you've installed the extension, you have a module.
Speaker 1: Okay.
Speaker 0: Which allows you to create any template you like. So, for example, this is a really simple one and actually does not hold any values. Okay. For example, this one. So on the left, it allows you to type any template data that you actually want to use.
On the right, you can actually see, like, a preview of how it would look like inside of the PDF itself.
Speaker 1: Yeah. So this how it will look like as a PDF. Right?
Speaker 0: Yes. And right now Okay. This is just for demo purposes. So it's not very stylish, but you can just use any HTML that you want and place it inside of the source code. This, by the way, is the what you see is what you get editor from the Reactors itself.
Okay. It has the same functionality built in.
Speaker 1: Interesting. Interesting. And yeah. Okay. Yeah.
That makes a lot of sense. So, basically, you just put in any text, and it just gives you the PDF format straight up. What if I'm interested in maybe getting a barcode? How would that
Speaker 0: look like? So barcodes are not require, do not require any template, obviously. Yeah. So if we go into flows we actually just created this flow. So in here, you can actually use the operation for that.
So if you want the barcode, you can Mhmm. Put in the type of the barcode, the contents, and you can also select type. I actually included a library that, has a lot of types.
Speaker 1: Okay.
Speaker 0: And from there, you can also adjust the width and the height. And if you want, you can also include any text. So because barcodes are more static than the actual PDF that you want to generate, I decided to not create any editor for it.
Speaker 1: Okay. Okay. Yeah. So, basically, that's it. And and I'm sure it's similar process for, QR code as well.
Right?
Speaker 0: Yes. That's true. Okay. So I can actually show you what it's doing. In here, I have created a sample collection with invoices.
Speaker 1: Okay.
Speaker 0: And in here, we have an invoice number, name, date, and also a relationship with the actual items that I have on this invoice. So then we have flows, and we can actually generate the PDF for it.
Speaker 1: PDF. Okay.
Speaker 0: Yeah. So it's actually going to use the templates that we just saw inside of the editor. And once it's done, we actually have a PDF in here.
Speaker 1: Oh, nice.
Speaker 0: Yeah. So I'll show you the logs after this. Okay. But here we have the PDF template that we just had.
Speaker 1: Interesting. Love it. I can see myself using this extension. Really interesting.
Speaker 0: Nice. So in the logs, you will actually wait. Inside of the flow, you can see, like, hey. We have our trigger. We have the button, and it's going to read the invoices.
So we actually have, like, the invoice data, and then we're going to use the generate from template, which allows you to give it any name. You can also use the variables in like normal flow supported. And then you can actually select a template, which you just created inside of the settings step. Yeah. And here we have our template variables.
So in here, you'll see that you actually get returned an ID. So if you want to make sure that the name is correct or that it's inside of the correct folder or link it up to any older record that you have, you can just use this ID and proceed with it.
Speaker 1: Yeah. Very useful. Very useful. See a lot of things. You like, you thought out, you know, how this extension can be very useful for many people and how it can be very efficient for them.
So, yeah, lots of thoughts has gone into it here. Yeah. So in terms of how the community can be, involved in this extension, like, how can they be involved in the extension? How can they find it? Where can they find it?
How can they use it?
Speaker 0: Okay. So I have a get a report story. So any issues in there, I will actually try and solve it as quickly as possible. And apart from that, it provides guides on how to use, how to use it, what variables you can use, how to actually set it up. So GitHub is the way to go, I guess.
And, otherwise, if you have any questions, you can also ask me in this in Discord.
Speaker 1: In Discord. Yeah. Okay. Cool. So my final question, which is like a fun one, is, what's your favorite director's feature?
Speaker 0: Actually, the one I started with. So the extensibility of directors really drives me to watch directors itself because it allows you to turn directors into either a normal website, a CMS, for your, web shop, or even just a project tool or an ERP. It's like the use cases of directors are very widespread from what I've seen.
Speaker 1: Okay. So extensions are like your favorite feature?
Speaker 0: Of course. I'm a programmer, so you could expect
Speaker 1: that. That makes that makes a lot of sense. Actually, it makes a lot of sense. I've had people say flows. Flows are like I think flows are like mine, actually, but extensions are also really great.
Yeah. But I see how you combine flows and extensions in this particular extension, so that makes a lot of
Speaker 0: sense. Yeah. And also with flows, it it feels like demi mode to me because Go can obviously do a lot more.
Speaker 1: Yeah. Yeah. You have a point. But, thank you, Bart. It's been amazing just chatting with you and just you working us through how you build the extensions, the need for it, and diving the part into your code.
So, I'm excited to see how the community engages and just starts using the extension and even more extensions that you build in the future. I'm excited about that as well. Yeah. So, thank you everyone for joining us, and we'll see you in another episode of the Beyond the Crossroad. Till next time.
Bye.