 Hi, everyone. Thank you for coming. I'm Alexander Gladysh and today I will tell you about an approach to implementing design in Qwink quickly. Functional UI sketches with Lua templates and mermaid.js. I will tell you about the case that we're solving. Some approaches to design that to implementation of the design that we're considered. I would tell you a little bit about the tools or quite a bit about the tools that we are using. After conclusion, I hope that there we will be some time for questions. Well, I'm a programmer in my background. I'm with Lua since 2005, I believe it's my favorite programming language. But, alas, I'm mainly doing management work now. The case I will be talking in this, well, talk is a huge professional enterprise application for civil aviation. The civil aviation domain is really, really huge. It's informatization started, I believe, in 1930s and it got piled up. It piled up and piled up and there's lots of legacy that's still used. So it's a huge domain and our task is to, well, renovate, so to say, 20 years old Windows application, which is still developed, still being in use. But, well, it's about the lifetime cycle in the aviation is about 20 years or maybe 25. So it's time to replace it. So we are implementing developing modern single-page web application instead. Like I said, the product is huge. So there's not a single person, I think, anywhere which is able to fit it in his head alone. So it's a team effort. There are technology experts which know the technology deeply. There are product owners and project manager which have the vision of the new product. And there's a designer in design team which, well, can design. So the application consists of set of screens, a large set, I think in the end, it would be about a hundred, maybe more. If it would be a web page, I would say that not screens but pages, but right here we call it screens. And each screen can be dedicated to an object or collection of objects or to some process. For example, I don't know, the list of flights and the one individual flight itself to be configured in the airline schedule. And for each screen in the new application, we have to using the old application as a template and the worldwide knowledge. So to say the other applications that you're doing this thing. We have to design it. We have to cut the screen, we have to consider first the concept, doing it with screen, how should we approach it, how should it work. When we have to do functional sketches, and sometimes for difficult screens into some interactive studies, brief ones, then designer has to design sketches to look nice and be usable. And after this comes the implementation. Well, this talk is about functional sketches, the second step. What are the functional sketches? Here's an example. Sorry, it's in Russian but it doesn't matter. The main question which the functional sketch has to answer is, what is on the screen? How does it work? It doesn't have to be pretty. It doesn't have to be designed. But it has to show what is on the screen. And well, what can you do with it? So that's just one example. And when design sketch, since main questions are already answered, answers the question, how does it look? The designer has to make it readable, usable, and well, look nice. So that's a functional sketch, that's what designer made of it. Doesn't matter what's shown on there. If anyone here is from airline industries, I'm sorry for the batch adapt terminology, but I don't want to cloud your minds with it. Anyway, my goals is, first of all, there are, like I said, a lot of screens in the application. And well, you have to see the flow of the screens, how user can move from one screen to another. Otherwise, you will get confused. But the main thing is that I need to the functional sketches themselves, obviously. And it doesn't matter how do I make the screens, because they're just illustrations, just images. Although those screens are well reviewed by the team, I'm basically only one person who does them, who implements them, actually. So as long as there's some facilities for use, which lets me not to drown in small changes for stuff which is the same on each screen, for example, it doesn't really matter what I use to get this screen done. As long as I have facilities to rapidly iterate on it because one screen can be changed, one illustration can be changed maybe 50 times for difficult screens. Usually it's five or six iterations until we get it right. So it has to be quick. Well, what tools to use to design those functional sketches? Now there's a lot of tools, starting from raster or vector editors and to the specialized editors like Balsamic. But well, you know, I'm a programmer. I work best and my hands are on the keyboard and not touching the mouse. Of course, I can use most of those tools and what I can't use, I can learn to use. But I spent all these years to be able to effectively work with essentially structured text with code. I can do that quickly. And I'm used to, well, as an engineer in commercial projects to getting work done first and getting the work done perfectly on the second. I found that for me it doesn't work this way for visual tools. I have to fiddle so it looks nice. So, well, I wanted to, of course it's not the first time I'm doing this kind of work. It's probably the largest by far projects, but still. And then I had to draw the diagram, the flow diagram for the screens once again. I dropped all the tools I used before and I come to this little tool called Mermaid, Mermaid.js. Here's the link. It allows you, it's not the only one tool which does it, of course, but this particular tool allows you to describe the diagram you want in a simple textual format. And then there's this little visual editor which is online and as you can see your changes as you type. It's quite convenient. So I thought I would create a screen flow diagram. Here's a very simple example. We have a list of flights and we can create a new flight from this list. By doing some action called create. On the left you can see the code for this diagram. As you can see, it's trivial. You declare the list, you declare, sorry, the boxes, the nodes, and then you declare the connections, the errors between nodes. Well, what does this create? User presses the button. So I tried this. I tried to embed the HTML into the arrow label and well, it worked. It works because Mermaid internally generates SVG with embedded HTML and it renders, if it's used as a command line tool, it renders this using the headless browser, the Phantom GS. So, well, pretty easy. I just type some HTML and I get a nice button. Let's go for it. Here's the list of flights in empty states, the state list of flight screen. It says, well, it has header, it has, well, there are no flights message and a button to create. As I said, it should not look beautiful. It should look functional so the designer and programmers will figure out what's going on. The beauty of design will hamper this process, actually. And well, there's a create button which leads to the new flight form. Here's the code for this diagram on the left. And well, here's a new flight form. It's greatly simplified, of course, but still there's a flight airline code and flight number and airport codes. Well, it's not an airport. It's a free Moscow airport, never mind. And well, the flight dates and you can create or cancel. And well, both of those buttons lead to list of flights. I assume that for most, and it really is, for most of the screens, actually what the button does, what this arrow means is clear from the context. Sometimes it is not and you have to add some, well, commentary on this. But still, usually it works only this screen and what the buttons do. If the person knows what, well, enough about the technology, it's sufficient. So on the left, there's a code for this diagram. As you can see, it's rather ugly. But still, it works. And we've got all three, all two, sorry, kinds of screens of illustrations we need. The screens themselves are detailed on the right, on the left, sorry. And on the right, there's a screen flow diagram that helps you navigate those screens. But, well, when you're doing HTML, it's not very convenient to use just an HTML, especially in this case because you don't have actual browser available. Then, well, you could have it, but it takes some work to set up the environment. So right here is kind of HTML4 era design. When you, even without dynamic HTML, when you have only the layout. So I think, in theory, you could write some JavaScript here, but I never tried. Instead, I'm using templates to generate my screens. And here is the list of flights screen, this one, as a separate file, so to say. As you can see, that's a simplest example. There's header, no flights, messages, and button. And I'm using those placeholders and curly braces to indicate templates as you, I think most of you are familiar with, at least one template language. So here, the template has arguments. So that's a title template, which has argument, the title string. And here is link argument, which has a link, sorry, template. I will call them, actually, not templates, but helpers after the handlebars template engine. So we have title helper and link helper. And link helper has one argument is the screen name, which links targets to points to, and then the link body itself. As you can see, I'm not adding any kind of layout here. I could, for example, move for this bold markup inside the title template. But since those two templates, two helpers are so basic, I don't want to do this. I don't want to change anything because otherwise, I don't want to have side effects, I mean, because otherwise, it would be harder at the later point to refactor this thing. So all that those should say to the template system is that for this bunch of template code, the title is list of flights. And this button leads to the new screens. Actually, not button, but this whatever piece of text there will be in the result in HTML. This code results to exactly this screen, nothing is changed visually. So here's the new flight form, which is exactly the same, we will not read it out loud. So like I said, we have two basic helpers, title and link here, and here is the format for those helpers. Like you see, the title takes text as a single argument and this argument goes until the end of the argument string. So this space is ignored. And not ignored, but put inside the argument. And the link here has two arguments. One is word as defined by a set of continuous set of non-continuous list, sorry, of non-space characters. So this is the screen. And then everything to the end is body. Okay, so let's try to define those two helpers. I introduce the, actually that's the only, I believe single one helper, which has to be defined by the system. It's defined, which lets you to define the other helpers. Define, so you define the helpers right in the body of your templates, basically. And the define takes the symbol, like the name of the helper as the first argument. Then there's a table, lower, finally, lower table of arguments. Here it is. And then there's the code of the template. What does it mean? Well, here you can see the definitions for simplest possible implementation of title and link, which just leave the layout unchanged and don't do anything. And here the code is, well, lower string, not the code, which contains the variable name, the argument name from the template. Right here, then the title is encountered. It gets replaced by the implementation, which I will show on one of the next slides. It gets replaced with this string, which in turn gets replaced, this placeholder text gets replaced from the arguments. Well, that's obvious. But, okay, let's go next. Let's look at the implementation. Here's the define function, which basically says here string, well, that's all this string from title to the end. Let's eat first word, then table, then all the text there is from this string. And let's load lower values from the argument. So basically the lower value function, all it does, it appends, sorry, pre-pends to this argument string. The key word return. So it would be return this table or return this text. And then call slot string and that's it. Since I'm only one person working with this, no person who would work with this has to use the secure environment. Well, it's okay to just not do any sandboxing, just call load string and that's it. Well, so you load the arguments as a table. You load the code, which may be a string or a lower function code. And then if it's a string, you just wrap it so it will work on replacing the placeholders in this string with the actual values. And then you define this symbol, the title. So it will be available for future replacements. How does it work? The definitions here are put into context. Context is a table, which holds everything which can be replaced. So this text has to be in the context of this title and vocation. It will be put there to this title and vocation, of course. It will be put there by this defined code. The context can be nested. So it all works, can you see this? No, I removed this code. Sorry, the context can be nested. So right here you're in global context. Is it correct? Yes, in global context. And inside the title there's a nested context which has the text definition. And I'm not sure if I'm coming through but just look at the code. I will have the link to the repo at the end of the slides. Okay, anyway, enough of this. So let's define something useful. Here's a title macro as a helper, sorry. As implemented as a lower function which gets the text argument. And it saves its sound there in the root context and just returns it. Well, first doing some replacements in case it contains other placeholders. And here's a link helper which, well, stores the link between two screens and returns the body of the link. And one interesting thing that's include, we are loading the template, we'll link that. So we will be able to enumerate all the links there. So we will be able to build the screen flow diagram. We will have data. And I will get to that a bit later. And well, that's it. Here's how include is implemented. It's really simple. So we just store the template name in the context, in the create nested context, store there the template name and call, and read this template name. It's actually should say template, not file name here. And well, call the replace. So all placeholders are replaced there. And that's it. And so depending on how you define your title and link helpers, you will get several kinds of diagrams from the same set of templates which has ended up quite useful for me. So from the same set of templates, I'm getting the outline diagram which has only screen titles and arrows. And from the same set of templates, I can get in the closeup diagram which we have seen earlier the screen itself with little arrows pointing to other screens. And also I can get a printable diagram which has no arrows, but only text content, screen content, sorry. Well, so that's useful. And for me, this is the main feature of this template in Drine. And the reason actually I event implemented it on my own. So more useful helpers. Here's a comment which does nothing and just eats its argument. Here's a horizontal ruler, HTML, which I found useful to separate blocks of templates. And here's an expression which accepts arbitrary lower code, probably with other placeholders embedded. And, well, just loads and executes. The standard stuff more or less. Okay, so here's another helper, Veef, which is really useful. It allows me to disable or enable parts of the, ah, sorry, it's Veef, not them. Veef this allows me to define my own context. For example, when used in conjunction with then helper, which renders the, its body only then the symbol is defined in context. I can define at the same place, both editable or not edit, nor read only parts of the screen. It's often that for the same set of data, it often happens that you has to show the editor form which user can change or just preview of this data of some form or another. So I define this form, which looks differently when it's editable or not. And then I enable editable in the additional context inside Veef and just invoke this template. And voila, I get the this line and not this line. So everything related to the same set of data is kept together. Well, another use for the Veef helper is to define extra context like constants to be used inside the template. Here I have a simple histogram drawing macro template, which well just calculates the Veef of the histogram from its arguments. Well, some stats. It took me two days to implement the core functionality. It was about 250 lines of code. And while I'm using this tool to create different screens, different illustrations for half of a year now. And the code grew up to about 330 lines of code, mostly additional error handling and diagnostics. And we created about 60 sketches and finalized 60 different sketches. And many more to come, I believe. Was it worth it? Well, yes. It's not invented here syndrome but it's best or worst and I don't know. But still, I've got the tool that does what I need. I've got it really cheaply, effort-wise. And its output while not ideal is quite readable and useful for the design and for the programmers and for the whole team. And well, I had much fun coding it. You may ask why not something else? It, given that I spent really, really low amount of time on working on this tool alone, I think that studying another tool would take about the same time. And well, but if you do know another good tool which does what I need, please share. It may be useful. Well, there are some problems in this tool. First of all, it's aerodiagnostic which are almost non-existent because I'm the only user right now. It gets better but since most of the time I know what's up with an error, I just skip it. It can be improved. Well, the main problem here is debugging the HTML output. Not the output itself but how it's rendered because basically it's like it was done in Internet Explorer 6. So you don't have any debug console and you can do nothing in just an image. You have to just try this and try that. And there are some issues with expressive power of this language but it's more than enough for me right now. Well, I'm done. Thank you. Questions? Please. Would there have been any use for doing non-HTML based prototyping like using ticks or graph bits? The question is will there be any use on using this tool for non-HTML diagrams? Well, no, using a tool which did not touch HTML generating an image via. Yeah, yeah. Sure, because all I do is work with text as long as the input for your tool which does something, code or something else. It's text, you can use it. Actually, for me the main new feature here is not the template language, it's a mermaid thing because it allows me to draw those flow diagrams easily between screens. And as for the template language, I think that you probably can use whatever you like or this one, it's the link is here. Welcome, and also pouches and pull requests are welcome too. Next question. So round of applause. Thank you. Thank you.