PBS_2024_09_28
An audio podcast where Bart Busschots is teaching the audience to program. Associated tutorial shownotes are available at https://pbs.bartificer.net.
Automatic Shownotes
Chapters
Introduction to Programming by Stealth
Beginning of the XkPassWD Project
Complications Arise
Understanding the Project Structure
The Role of the Model
The Importance of Index Files
Controllers and Views Explained
The MVC Pattern
Managing Interactions Between Controllers
Navigating the Code Structure
The Role of the Views
Binding Functions in the View
Introducing the Config Feature
Celebrating Milestones and Contributions
Closing Thoughts and Future Directions
Long Summary
In this lecture of "Programming by Stealth," recorded on September 28, 2024, host Alison Sheridan welcomes Helma Vanderlinden as she dives deeply into the practical applications of the Model-View-Controller (MVC) pattern as it is implemented in the xkpasswd.js library. This session sees Bart Bouchats participating as a fellow student, providing a unique dynamic to the lecture, as the trio engages in an interactive learning experience about the project's structure and objectives.
The discussion begins with a brief overview of the xkpasswd.js project, where Helma explains its evolution from inherently static HTML with minimal JavaScript functionality to a comprehensive application. She notes that the previous version relied heavily on Perl, while the current iteration converts the underlying logic to JavaScript—incorporating Bootstrap for improved UI components. A major aim of the session is to help Alison and Bart acclimate to the new project structure, particularly as it pertains to the MVC framework and how different segments of code are organized.
Helma illustrates the necessity of MVC in simplifying the complexity of the code. By segregating the project's components into models, views, and controllers, it becomes easier to manage and modify. The model, represented by the xkpasswd class in the lib directory, handles data and logic, while the views dictate presentation. The controller acts as the intermediary, linking the model's data and the view's display together. The analogy of an organizational chart helps clarify that interactions must follow a defined hierarchy: controllers only interact with their respective views and not with views from other controllers, which results in a clearer structure and minimizes potential errors.
The conversation delves deeper into the directory structure, discussing why the source code is organized into separate directories such as "src" and "dist." Helma explains that maintaining clarity in folder structures aids in file management and facilitates smoother transitions during debugging. This realization resonates with both Alison and Bart, reinforcing the notion that organized file systems simplify collaboration and maintenance over time.
As the dialogue progresses, Helma introduces the concepts related to binding UI elements to functionality. She shares insights on how her naming conventions, including the use of bind functions, promote clarity in the code—ultimately streamlining the process for the developers working on the project. Furthermore, the conversation highlights the introduction of a new configuration feature that stems from community contribution, emphasizing the collaborative nature of open-source projects. Helma illustrates how this new feature was integrated seamlessly into the existing structure without significant reworking of the foundational codebase.
In wrapping up the lecture, the importance of documentation and using organizational diagrams becomes apparent. Both Alison and Bart express newfound confidence in navigating the code and understanding its components and functionalities. The session culminates in a practical assignment for listeners to explore the MVC implementation, which encourages hands-on familiarity with the project's architecture.
The lecture exemplifies the journey from theoretical understanding to practical application in software development, underscoring how structured programming concepts can radically enhance the clarity and maintainability of codebases—a critical takeaway for both seasoned developers and newcomers in the field.
The discussion begins with a brief overview of the xkpasswd.js project, where Helma explains its evolution from inherently static HTML with minimal JavaScript functionality to a comprehensive application. She notes that the previous version relied heavily on Perl, while the current iteration converts the underlying logic to JavaScript—incorporating Bootstrap for improved UI components. A major aim of the session is to help Alison and Bart acclimate to the new project structure, particularly as it pertains to the MVC framework and how different segments of code are organized.
Helma illustrates the necessity of MVC in simplifying the complexity of the code. By segregating the project's components into models, views, and controllers, it becomes easier to manage and modify. The model, represented by the xkpasswd class in the lib directory, handles data and logic, while the views dictate presentation. The controller acts as the intermediary, linking the model's data and the view's display together. The analogy of an organizational chart helps clarify that interactions must follow a defined hierarchy: controllers only interact with their respective views and not with views from other controllers, which results in a clearer structure and minimizes potential errors.
The conversation delves deeper into the directory structure, discussing why the source code is organized into separate directories such as "src" and "dist." Helma explains that maintaining clarity in folder structures aids in file management and facilitates smoother transitions during debugging. This realization resonates with both Alison and Bart, reinforcing the notion that organized file systems simplify collaboration and maintenance over time.
As the dialogue progresses, Helma introduces the concepts related to binding UI elements to functionality. She shares insights on how her naming conventions, including the use of bind functions, promote clarity in the code—ultimately streamlining the process for the developers working on the project. Furthermore, the conversation highlights the introduction of a new configuration feature that stems from community contribution, emphasizing the collaborative nature of open-source projects. Helma illustrates how this new feature was integrated seamlessly into the existing structure without significant reworking of the foundational codebase.
In wrapping up the lecture, the importance of documentation and using organizational diagrams becomes apparent. Both Alison and Bart express newfound confidence in navigating the code and understanding its components and functionalities. The session culminates in a practical assignment for listeners to explore the MVC implementation, which encourages hands-on familiarity with the project's architecture.
The lecture exemplifies the journey from theoretical understanding to practical application in software development, underscoring how structured programming concepts can radically enhance the clarity and maintainability of codebases—a critical takeaway for both seasoned developers and newcomers in the field.
Brief Summary
This lecture of "Programming by Stealth" features Alison Sheridan and guest Helma Vanderlinden, who explore the practical applications of the Model-View-Controller (MVC) pattern as seen in the xkpasswd.js library. Helma details the project's evolution from static HTML with Perl to a robust JavaScript application utilizing Bootstrap for enhanced UI. The discussion emphasizes the organization of code into models, views, and controllers, which simplifies complexity and error management. They also examine the directory structure for better file management, the significance of naming conventions for UI bindings, and the integration of community-driven features. The session concludes with the importance of documentation and organizational diagrams, leaving listeners with a practical assignment to deepen their understanding of MVC. Overall, the lecture highlights the transition from theoretical concepts to practical implementation in software development.
Tags
Programming by Stealth
Alison Sheridan
Helma Vanderlinden
Model-View-Controller
xkpasswd.js
JavaScript application
Bootstrap
code organization
file management
documentation
software development
Transcript
[0:00]
Introduction to Programming by Stealth
[0:00]Music
[0:07]Well, it's that time of the week again. It's time for Programming by Stealth, and this is installment 171, recorded on September 28th, 2024, and I'm your host, Alison Sheridan. But we have a bit of a change-up for today's lesson. While Bart Bouchats is in attendance, he will not be the instructor. He'll be a student like me. Our instructor today is the delightful Helma Vanderlinden, and she's going to teach us about how Model-View-Controller is implemented in the the new xkpasswd.js library. So welcome to the show, Helma.
[0:37]Well, hi. I'm feeling a very honor to be here and being the instructor as well.
[0:45]We're taking it up a notch. You've taught class before, but you haven't taught BART before, so this is new. Are you ready for this to be a fellow student, BART?
[0:53]Absolutely. I'm looking forward to this. Normally, I have to be the teacher and stuff. This is It's really nice to have someone else do all the homework. I like this.
[1:03]Do the heavy lifting. So this all came about because, and we explained some of this last time when Bart explained what Model-View-Controller is from a theoretical standpoint, was when Helma kind of took over the project and ran with it and started converting the old Perl libraries into JavaScript. And things were going along swimmingly from my perspective as a student of programming by stealth, when one day the entire structure of the project was changed. And I panicked because I can't find anything. I don't know where anything is. So Helma's job today, from my perspective, is to explain to me how is the code structured, all the different pieces, and how do they work together? How do I find my way through the directories and figure out where stuff is and know how to help? And Bart, do you have a perspective on what you want to learn today?
[1:52]Kind of the same thing. I understand the abstract concept of model view controller. But I haven't spent nearly enough time in the code base to quickly find what I want. So yeah, I'm sort of looking to cheat. And instead of spending time figuring it out, just have it handed to me on a platter.
[2:15]There you go. So this will be the first time we've had three people on the show in a classroom setting. And I'm used to being able to just blurt out my questions. But the three of us can see each other on video. You guys can't see us. But we are going to try to raise our hands to break in with Helma so Helma knows we have a question. And so we don't step on each other any more than the normal lag of video and audio over the Internet causes.
[2:38]I'm having Zoom issues. you. So if I say, huh, can you say that again? It's because Zoom has a bug today and it's making my audio very difficult to understand. So it's not that I'm being obtuse. I'm just, yeah, I'm suffering a bit today. But hey, the recording is fine. So that's all that matters.
[2:55]So I will be playing the part of obtuse then. Okay, we got it. It's my normal position and I'm comfortable with it. All right,
[3:06]
Beginning of the XkPassWD Project
[3:04]Helma, where are we going to start?
[3:06]Okay, let's start at the beginning of the XkPassWD project because at the time, that was back in December last year, the entire thing was just 99% static HTML and there was only the generate button, which had a little bit of JavaScript code. It was easy to put everything in, say, two files, an HTML file and a JavaScript file. And because we use Bootstrap 5, there was already a drop-down menu and all kinds of other UI components that were actually working without any heavy lifting on my part.
[3:49]Yeah, it was great. I loved it. Why did you change it?
[3:53]Well, of course, over time, all the placeholders were filled in with actual functionalities. So the preset buttons came, and then the settings pane came. And of course, after much debate, we had this dual visual in the list of passwords. passwords one half of the world wants a list and the other half of the world wants a text area where all the passwords are together so that made the amount of javascript longer and more and more complex to put everything in one file yes bart
[4:33]I'm just remembering back to the old pearl versions web interface which is so long ago it was before i had learned about bootstrap it might even be before bootstrap existed so it might not have been me being silly it might have just not existed and it was very easy to start because it was a button that made passwords and that was all i had to do and then i started to try to design the form and then whenever you changed well okay do we want to have random digits or specific or say random characters or specific characters you click this button half the ui disappears and another half of the ui comes in and initially i I tried to just do it by hiding and showing and hiding and showing, and it was a disaster. And so it ended up becoming you push the button and it created the UI. And that's, I think, where you ended up going as well, that now when you push the button, it makes things happen with JavaScript instead of just hiding and showing things.
[5:31]Oh, no, I decided the best practice was if it can be done with HTML and Bootstrap, it's in the HTML file.
[5:41]Cool, yeah. I didn't have Bootstrap, so of course I wasn't thinking that way. Yeah, that makes sense.
[5:45]Yeah. So that's basically one of the rules of thumb. Well, I've got two. So, yeah, if it can be done with HTML and Bootstrap and jQuery, it's just in the HTML file, and I don't have to think about it or do anything else with it. I don't need to write JavaScript code. You don't need to write tests. So that's why I started with the UI, because that was the easy part. I just more or less ported your version of the web version to what is now XKWD pass. It's a tongue twister.
[6:31]Okay, so things got complicated.
[6:32]Yeah. Yeah. And maybe you remember, Alison, when we looked at your project of the time shift clocks, you had everything in one long file. And you even had to sort of use different views in your IDE to check different locations in your file.
[6:54]Right, bringing up the same thing multiple times so that I could see two different parts at the same time.
[7:02]
Complications Arise
[6:59]Yes, yes. I was running into that phase as well. And then I thought, I'll give up because now everything is using everything for the UI, at least. I need to split it up. And that's where ModelViewController comes into place. So the actual library, so the one that was driving the website and that's generating the passwords and the statistics, etc. et cetera. That's in the SRC slash lib directory.
[7:31]I think you're jumping ahead a bit. I have pre-read the show notes in hopes of understanding this when we get there. But I think the first thing is why the SRC folder is there, because there's a lot of other directories in here and you've got this SRC folder.
[7:45]Yeah. So when you build a project like this, you usually have your source code, which is in the SRC structure, and you have your build script that generate the output, and the output is usually placed in the dist folder.
[8:02]Just for people who are trying to figure out dist, dist, dist, it's short for distribution. And it's because it dates back from the days when we wanted to save characters, because we were only allowed seven of them in a file name. And so you have SRC and dist, whereas really it should be source and distribution. But, you know, hey. Tradition.
[8:23]Tradition yeah so we ignore all the other folders because there's uh well there's 14 items at the top level but we've got dist and source yeah and that does help to specify those because if i go into dist i see index.html but i go into source there's also an index.html but so for this purpose this discussion we're ignoring everything in this directory except for the source folder.
[8:45]Yes okay right and if we look at your handy dandy diagram of the layout of all the directories in that project. You'll see the light yellow ones.
[8:58]Remember, people might not be looking at the diagram, so speak in a generic tone here.
[9:02]Yes, okay. So there is the source directory or the source folder, which has two subfolders, a web folder and a lib folder. Again, short names because of the tradition. And developers are lazy. So, the lib directory contains the actual source code for the password generator. So, that's the Perl library that is ported to JavaScript. And if you would look inside that folder, you would see classes that would match the classes that were in the Perl version, like statistics and presets and dictionaries.
[9:45]I'm going to back us up a little bit again, because in the show notes you explain more of why you broke it up. You got to the part where we said that you were having open up different views, but what did you do to break it up? Before we get into the details of the directories and the naming and all that.
[10:00]Yeah, okay. Well, from early on, there was this idea that we would have a command line project and we would have a website. So what I did is I took all the classes that would actually generate the passwords and put them in the lib directory so that later on we could use them as the basis for a command line application. At the same time, I want to use it to drive the website.
[10:29]And I'm just going to jump in for a sec. So I'm kind of responsible for this to a large extent because the original Perl project only had the library and the website was never open source. So in the original, the library was open source, but the website was closed source. And so it was always the intention the library would be its own project because
[10:54]
Understanding the Project Structure
[10:50]you may want to write anything that generates passwords. passwords and so you should be able to take the brains to make passwords and bring that into your code without bringing a website you should just be able to bring the password generator and so xkpassword.js was only ever supposed to be the password generator but to test it we needed a website and in the long term that's going to be a separate github repository but imagine the pain in the backside. If every time you had to fix a bug in the generator, you had to commit a whole new version of the library, update your NPM fetch updates in the website one, you would be 20 minutes fixing a silly bug and that would drive everyone crazy. So I said to Helma, let's do the beta version of the website in the library's GitHub repository so they're together, but don't mix the code
[11:43]Keep please.
[11:45]Please please i had very few specifications but one of my specifications was don't mix the code for the brains with the code for the web that's why it's lib and web lib are the brains web is the interface
[11:57]So this is the first time i've heard any of this, haven't heard this before i i i knew that there was this command line version but i didn't know of this description that you've come up with but maybe i can put it in terminology i understand that'll help other people to understand, is I've got this silly little time adder app. All it does is add time. And in order to add time, you got to do a lot of math. So I've got the part that calculates the numbers. That would be the equivalent of what would go into lib. But the fact that I display it as a copy, a CSV, there's a button for it. The fact that the little display updates automatically when you lift your key, that kind of thing, that would all be the web stuff. Yeah. Is that a good description? Perfect. Yeah. Okay. Okay, good. So then in this example, what we're talking about is anything that is the generation of the passwords, just the generation of the passwords. That's what's in lib?
[12:53]Yeah.
[12:54]Yeah. Okay. But anything that is making it look like what it looks like on screen or little buttons we can push or, you know, choosing a preset and how we copy, whether we want to copy it as a list or we want to copy as individuals with a bulleted list, that would all be under web. Yes. True. Okay. And this is Model-View-Controller or no? No. This is just Barton-Helmo the way we want it structured because we're open sourcing one piece.
[13:20]How about yes and? Because as it happens, the model in Model-View-Controller is the library. So Model-View-Controller connects with this concept of having the brain and the user interface separately. That is completely in sync with Model-View-Controller. There's multiple reasons to want to separate those two. And one of those reasons was because I want the library to have a life where the library can be used for anything. And the web is a use of the library. But also when you're doing a web page, keeping those two separate is MVC as well. So it's just synchronous. It works together.
[13:58]Yeah. Yeah. Okay.
[14:00]Okay. I think I'm done interrupting until you go through the next paragraph.
[14:05]Yes.
[14:06]So as Bart already explained, the lib directory contains the model in this model view controller pattern. Actually, the way I set it up, and that was also more or less because Bart set his Perl version up like this, is it follows another design pattern. And the design pattern is called a gateway pattern. Because there is only one class in the lib directory that is communicating with the outside world. So every request for password generation or any of the other stuff, like the presets, etc., all go through this xkpasswd class.
[14:54]And that's one of the classes in lib. So just real quickly, we've got dictionary presets, random basics, statistics, and XKPathWD. And XKPathWD, that's the gateway?
[15:06]Yes, yes. You can look at the lib directory as a black box for the user interface. And the only door is the XKPathWD class.
[15:17]Okay.
[15:20]
The Role of the Model
[15:17]We're not having one design pattern. We're having two.
[15:20]Which, by the way, is normal. Because there's probably even more design patterns if we dig deeper. But, you know, computer science is full of, oh, this is an idea we've had before. Why reinvent the wheel? So we're collecting a couple of wheels here. So at the moment, we're on a bicycle. We might make it to a tricycle.
[15:38]Well, not today, probably. But hey, maybe I used a pattern that I didn't recognize as a pattern. The old index file that used to contain all the JavaScript code to just make the magic go when you press the generate button has now become a sort of bootstrap class in its own.
[16:00]I'm just going to stop some confusion before it happens. so bootstrap the open source project is named bootstrap because it does that's a word programmers love it's a thing to help you get started and so can we maybe call the index.js like the generator or something basically it's the entrance way that it builds everything it it assembles everything around it which is called bootstrapping in the abstract but if you call it the bootstrap class that's going to make everyone's head explode because we use Bootstrap.
[16:34]Yeah, true. Okay, okay. Yeah. Okay, now you just confused me,
[16:39]Bart. You talked about index.js. We don't have an index.js.
[16:43]Index.mjs.
[16:44]MJS. I'm sorry, index.mjs. No, we have index.html.
[16:48]No, no, no, I'm looking at it. Index.html.
[16:50]Well, there are two next to the index.html, which contains all the HTML.
[16:56]Alison's rubbing her head right now. So you said we were talking about index.html. I know that because I opened the file right when you said it, and now we're talking about index.mjs? I don't know what's the difference between those two. Why do we have two of those?
[17:09]Well, the HTML file just contains the HTML, the static HTML. And it has some IDs and classes that we can use in our JavaScript to drive the UI. It's very boring from a programmer's perspective because it's just static HTML. And the fun starts in the index.mjs, which is the JavaScript file.
[17:40]Okay, but he just said that index.mjs was the gateway, but we just finished saying that the xkpasswd.mjs was the gateway. So what's the gateway? Or did I misunderstand again?
[17:53]No, not gateway. If I use the word gateway, that was a slip of the tongue. I tried not to use either the word gateway or bootstrap, which is very hard not to use either of those two words. It is the initializer. It is the assembler of all the JavaScript. So the HTML, the browser gets the HTML. And at the top of the HTML or the bottom, it's going to say script S or C equals, and it's going to pull in that JavaScript.
[18:20]
The Importance of Index Files
[18:20]And that JavaScript has to go do everything. So the start of do everything is index.mjs. So all the other classes are going to be called by index.mjs. It's like, it's the starting point. It's part zero. So if you're looking through the code, that's what happens first.
[18:41]So the HTML, index.html is going to call index.mjs as the source in theory. Okay.
[18:49]Don't go looking for it, because Webpack is doing this, and it accidentally calls it main.mjs. So don't go looking for the index.mjs in the HTML file.
[19:05]Do you see why I'm lost, guys? Not only has everything changed and moved and the names changed, the names aren't even there. So I look at this and I can't follow it along. I don't know how to do it.
[19:19]Okay, but that's what we're telling you, Alison. So if you're looking for where the physical shape of the page starts, the master in charge of the shape of the page is index.html. That is where do the HTML tags start. And where does the JavaScript start is index.mjs. So that's like line zero of the code is line zero of index.mjs. So JavaScript start is index.mjs. HTML start is index.html. They're your two starting points. They are the two files that you start. And they call everything else. So they are your entry point.
[20:00]Okay, so index.mjs is really the gateway. As you've described, it's the one in this black box. It would be the open door, no?
[20:11]But it's not a black box. It's the gateway to the website.
[20:15]Oh, okay, okay, okay, good, good. That makes sense. I would like the record to note that index.html also doesn't refer to main.mjs.
[20:27]Webpack is doing it all because it's pulling in all the dependencies. So I would think of them as two, just think of them as your two entry points and don't, they are, index.html is the brain of the shape of everything and index.mjs is the start of the JavaScript. They are your two starting points is how to think of them.
[20:47]Yes. Yeah. Okay, so the only thing that the index.mjs does is initialize all the classes that we need, and that's the model view controller classes, and we'll talk about them later. So it contains one object called xkp just to keep everything out of the global namespace, and it has one init function which contains all the class initialization. God, sometimes that tongue twisters. Anyway, I put the content of the init function in the show notes so you can have a look at how they are all created.
[21:37]It's very short.
[21:38]Yes. It's nice though.
[21:41]You're right, yeah, because it's just the starting point. So we have xkp.xkpasswd is going to be the lib folder, basically, goes all in there.
[21:50]Yeah.
[21:52]Xpay, and then we have our controllers for ModelViewController.
[21:55]Yeah.
[21:55]And they seem to match the chunks of the web page. I seem to have a class here to match each piece of the web interface.
[22:03]Yes, it does. So, and the other thing in the index.mts file is the document ready handler. which basically calls this xkp.init function and makes everything up and running.
[22:20]Nobody described what's in this list of code you just said. You guys talked around it, but didn't say what we're looking at.
[22:27]Well, what we're looking at is there is a variable for each of the classes that are used in the web part of the project. So there is a variable called xkpasswd, which is an instantiation of the xkpasswd God, this is hard.
[22:53]Yeah.
[22:54]So anyway, for this gateway class that we talked about earlier, there is one for the password controller, there's one for the settings controller, there's one for the config controller. And each of the controllers, and I'll talk about this in more detail later on, they get passed in a reference to the model and to the view class. So, for example, if you look at the password controller, its constructor takes XKPassWD variable and a password view instantiation.
[23:34]
Controllers and Views Explained
[23:31]Okay. Okay, so there, that just started to make sense to me. So you've got a controller that's going to take the brains, our entry point of XAPassWD and a view to couple those two things together. Now you can do something with it because you've got the brains and the way it looks, and you've shoved it into the controller?
[23:51]Yes, and the controller's job is to marry those two together. So it's perfect that it's two arguments or two things. It's connecting together.
[23:59]Okay.
[24:00]Yeah.
[24:00]I do like your long, specific names, Bart. Helma has called it new password controller, and password view. Bart would call that PVW or something. You always shorten things to make them easier to type.
[24:18]I'm not sure about that. I think Helma stole a lot of my, not stole, Helma copied intentionally a lot of my class names. So I might not be entirely, I may get a teeny bit of credit here, maybe.
[24:30]Okay, okay. But maybe in the last 15 years since you wrote it, you've gotten shorter and shorter names.
[24:35]In some of the classes, because I didn't do RNG, I just did random.
[24:41]Oh, I did random number generator, which was too long. So I went, why don't I make random number generator shorter? I called it an RNG. Okay, yeah. Okay, guilty as charged. I take it back.
[24:51]
The MVC Pattern
[24:52]Okay so so basically we can move on to the the mvc pattern and i put a diagram in the show notes that consists of four blocks of stuff yeah stuff well actually it's it's four pairs of rectangles and one rectangle represents the controller and the other rectangle represents the view and there is only an arrow going from the controller to the view where the controller calls the view nothing else calls that view than the controller that is part of this view
[25:33]So this allison this is very important for when you're trying to find out okay so i have this button right here in the interface and i want to change what that button does if that button is in the presets chunk of the page it can only be in the preset controller you're never allowed to connect part of the preset view to some other controller because then the universe would explode and no one would ever find anything so the part of the screen that you're trying to change tells you which file to go get okay
[26:03]Okay oh oh okay that does help yeah.
[26:06]So and in the center of this diagram you see a cylinder with a label model xk passwd which is this gateway class in the lib directory so and the only thing that is called is this xk passwd class nothing else in this lib directory okay So I'm moving around in my show notes, but I think it makes sense if you read them without listening.
[26:41]But if you're listening, you're going to be completely lost.
[26:44]But here's the secret, Helma. Myself and Alison jump around all the time because a conversation will flow differently to the show notes. So as long as the show notes read well, as long as the conversation flows well, they don't have to be the same. And I think the longer we've been doing this, the more we get out of sync with our notes, and I think the better we are for it.
[27:03]And I retain the position of telling Bart when he forgot something, because we jumped around.
[27:07]Okay, great. Yeah, that's what I heard when I listened.
[27:11]We all have our little jobs to do here.
[27:13]Yeah. If we are going, I said there are four pairs of controller and view. In the pre-June version, there were only three, and I'll talk about the fourth one later on. I color-coded all of the the boxes so the upper left is the preset controller and preset view in green and the password controller and the password view on the right they are blue and the settings controller and settings view are red so what i also put in is a screenshot of the current user interface and I marked in colors which part is handled by which control of U-pair.
[27:56]That's genius. That's brilliant.
[27:58]In case you're worried about the colorblind here, the words are also there so that you can tie the colors to the words to the sections over in the other diagram. So this was not clear to me until I studied this part of the diagram. So what she's got is a screenshot of the web interface and it's It's showing you here's where the config controller kind of stuff is going to need to go. And this over here is where presets are. And here's where settings are.
[28:22]Yes. Me being a little bit OCD, I actually copied the color codes into the, I did it with CleanShot X. So I copied the color codes from the diagram into the colors of the boxes.
[28:39]As one should. We can't have anarchy here and have it be a slightly different color of orange for crying out loud.
[28:46]True, true, true. I think I skipped. Why did I break it up? Because one thing is the file gets too long and it gets very unwieldy to make sure that you easily lose your place where you want to edit something. Another reason is it's very difficult to make sure that you don't accidentally should accidentally use a function from one class that you want to leave out. So the only way I could make sure that this xkpasswd class was the only one used in the model was pushing it off in a different library. With the controllers, it also meant that I could sort of isolate code into different files, which makes the files shorter and therefore makes the files easier to test. And if the test lines are very short, then you don't even, the functions are very short. You don't even need the test because it's quite obvious.
[29:58]
Managing Interactions Between Controllers
[29:58]Okay.
[29:59]And it also enforces good hygiene because if the functions are in the separate classes, you can't accidentally mix, you can't accidentally break the the model if you know you can't break the design if they're in separate files by accident because then you end up with these stealth connections where everyone thinks we're using this design pattern only we forgot that you're not supposed to talk to these two because they're supposed to be a hidden wall but if you put them in separate classes it'll be a bug oh that's not a secret bug that's going to bite us in five years that's now this doesn't work So you fix it straight away, and you don't build up this technical debt of whoopsies.
[30:38]Yes.
[30:38]Did you ever find yourself working on one of these and going, oh man, I wish that piece was over in here? That this controller and this controller I need, and you're thinking, oh, rethinking it?
[30:50]Yes. That's why I decided I add some helper functions to some of the classes, the controllers, so that when one of the controllers wants to do something, say for example when i update the presets the settings should change but you don't want the preset controller to handle anything in the settings area so
[31:16]There's a just it should just tell it yes you need to go do your job.
[31:20]Yes so that's why the preset controller tells the settings controller do something yeah but it's
[31:27]A bit like a management structure so if you if you have two peers at the same level of the org chart working for different departments. They don't talk to each other. They talk through their managers. And so the controllers are the managers, and they can hand information over and back between each other, but the views don't because they're the underlings.
[31:47]And the two underlings are convinced, this would be way more efficient if I could just talk to that person.
[31:52]Until reality kicks in. I know this from bitter experience. It's not more efficient. That's called chaos.
[31:58]Yes. If we go back to the diagram, you will see dashed arrows, and the dashed arrows is where controllers are addressing, or rather calling functions in the other controllers.
[32:16]Oh, wait a minute. They bypass the director, though. They go manager to manager, and they're not including their boss, the model.
[32:26]Yeah. Yeah.
[32:27]Right. Like, again, in an org chart, if you're a peer, you can, right? So maybe it's just in where I work, but basically me and the other sysadmins, we work away among each other. And then the DBAs work away among each other. And the managers above us work away among each other. But we go up through our managers to go to DBA.
[32:45]Yes, but you're skipping the director. You're not going up to the model.
[32:48]Oh, we only go up to the model.
[32:49]The model never knows that this is going on.
[32:51]But are we doing something model-ish, right? But if all you're doing is changing the settings, you're not actually telling the model anything. Until you hit the button that says make me a password, the model isn't involved here. The model gets told make me a password when the interface is ready. It's two parts of the interface changing each other.
[33:10]Yeah, but the model doesn't just contain the password generation. It contains the presets and the statistics and all kinds of other stuff.
[33:22]So what happens is if you press one of the preset buttons, the preset controller figures out which one it is through the preset view. And then it updates the model with the current preset. And then it tells the settings controller, go and make sure that the settings part of the UI matches the configuration of the preset. set, then the settings controller goes into the XKPassWD, so the model asks it what is the configuration currently, takes that, and then tells the settings view to update the settings dialog box or section.
[34:09]That makes sense, but I thought you just said that the preset controller can talk directly to the settings controller without going through the model. Your dashed lines say so.
[34:18]Yes, but that doesn't mean that when the message arrives, they don't talk up, right? Because you have the black lines as well. So you say to the manager, I want you to achieve this end. How that end is achieved may involve... talking up to the director so you tell the settings controller i need this to happen i don't know how you do this that's not i don't it's not my department if the settings controller needs to talk to the model to make that happen that's up to the settings controller uh
[34:45]There you go so it could follow on this dashed path between peers yes but then when the settings controller gets it goes well i don't actually know how to do that so i'm going to ask my boss get the information and then I can make the settings view reflect what the preset controller asked for.
[34:59]So in a different application, the settings controller and the preset controller could have different models. So the preset controller doesn't know that the settings controller is actually using the same model.
[35:17]Oh, that's interesting.
[35:19]Because again, we're dealing with abstraction, right? It's just a bunch of black boxes. I know I can ask that manager to do this, this, and this. I don't know how the manager does it I don't need to know how the manager does it I know how to do my job and I know what I can ask of others And each other does it their own way. And that's by design, because it means that when you're working on one piece of code, you don't need to understand the detail of any other piece. If I'm working within the config controller, everything I need is here, and I know I can ask other things, these specific functions, these arguments will give me back this value. But I don't know how, but I don't need to know how. I just need to know, yeah, that guy can tell me this. Or can do this.
[36:02]
Navigating the Code Structure
[36:02]Do you find yourself, Helma, when you're trying to make a change, you're trying to fix something, opening up all these different files, going, wait, is it in here? Nope. Is it in here? Wait, no, I'm confused where it is. Or does this whole thing sit in your head and you have no problem? You know, I'm going to open this file because that's where I need to change it.
[36:19]No, that's the model view controller pattern. I know what I want to do. So I know which part of the UI it is. So I can go from eight files to just two. Is it in the controller or is it in the view that is part of this part of the UI? And then if it's something I need on the screen, then it's probably in the view. or if I need to change something in the UI. But when I have to sort of store something in the model or I have to take something out of the model, then it's the controller.
[37:02]Yeah, the point of these design structures is to answer your question, Alison.
[37:13]
The Role of the Views
[37:07]If it didn't have an MVC-style structure, then you would never know what file to look for stuff in. So the reason there's a logic to it is that when you're in harmony with the logic, it should, if it's well-designed, and again, the colored boxes show you the logic, the whole point is to make that an easier ask than it would be if you had the same lines of code not in a pattern.
[37:36]I pictured that Helma would have to have this diagram in her head, but she doesn't. She's looking at the display on the web, and she's playing around with something in the presets and she's trying to get something to work, as she said, that narrows it down to two files. It's either the preset controller or the preset view. It can only be one of the two of those. Yeah, exactly. Now, it might end up being that there's something over in the settings controller that, well, I picked a bad example because it doesn't have any arrows that way, but it could be where the settings controller can also have these helper apps, so you might end up having to go over to that pair.
[38:10]Yes, but only if you see a function call that says tell that manager to do something, and you're like, oh, I need to tell that manager to do something the manager doesn't know how to do yet. Oh, I better go teach the manager.
[38:19]Yeah.
[38:21]Okay, so if you do have a helper function, say in, let me see if I can get, in the settings controller that is going to be talking to the preset controller, how in the code would I recognize that the settings controller was calling the preset controller? Would it say presetcontroller.mjs in the code somewhere?
[38:43]It would be the name of the object, right? So we created all the controllers in the index at mjs, so they all have those nice names you liked.
[38:51]So, I've got to go back and open the index.mjxs to find the names. So, that means it's abstracted again.
[39:01]Well, what I did is every controller class has a constructor. And the constructor has two parameters, two arguments. One is the model and one is the view. Right. And whenever it's necessary, there is a third one with the settings controller because the settings controller is sort of doing all kinds of things.
[39:29]Sorry, I've just noticed, yeah, the preset controller has extra arguments because it takes the settings controller as an argument and the password controller as an argument. So it doesn't need to go figure them out. They're going to be called settings controller and password controller. So you're going to know it's calling the password controller because it's going to say password controller dot name of function.
[39:48]Yeah so they are they are variables in the class so we're in the constructor nowhere
[39:55]Near to answering my question yet you guys are saying lots of words i'm looking at the preset controller, and or i don't really understand the way the arrows go so i may be saying it backwards but i'm in the preset controller how would i know that the preset controller is calling the the settings controller with a helper app how would i does it say settings controller.mjs does it say No.
[40:17]No, just settings controller.
[40:18]Settings controller, which...
[40:19]It's a variable. It's a JavaScript variable, so it's going to be settings controller dot some function name.
[40:26]So I've got to go into index.mjs and find out what she's called it in order to know which one it is. But they're named well.
[40:34]I was going to say they're named right. If they were named terribly, then yes, you'd have to go figure out which name was stored in which file. But the Helm is very good about the naming, so when it calls a controller, it will be really obvious.
[40:48]Yeah, so all the classes, they have a name, like PresetController, SettingsController, et cetera. Every class lives in one file, and the file is called PresetController or SettingsController, just in lowercase. That's the only difference with the class name. So if you want to go into the preset controller class, you open the presetcontroller.mgs file.
[41:17]I'm not getting this quite across. Let me test a theory.
[41:21]Yeah.
[41:22]If I'm in the settings controller file, I should find somewhere in there the word preset controller because there's arrows between them, and it's not in there. So the settingscontroller.mjs code does not contain the word preset controller with a capital P and a capital C?
[41:44]No, it doesn't, because the setting controller doesn't know anything about the preset controller. The preset controller knows...
[41:51]There's dotted lines between it.
[41:52]Yeah, but it's the arrow pointing away from the preset controller to the settings controller.
[42:00]So, does that mean the preset controller knows about the settings controller, but the settings controller does not know about the preset controller?
[42:06]Correct.
[42:08]Okay, so if I change this to settings controller...
[42:14]Preset controller.
[42:17]Okay, hang on, I've got to open that file. I didn't have that one open. Sorry for the live thing, but I'm trying to get to the meat of how hard this is for me. so I'm in the preset controller I should be able to find settings controller please tell me it finds it ok it does so the arrow means that the preset controller is talking to the settings controller yes because the arrow goes from preset to settings but the arrow doesn't go back the other way so the settings controller can't tell the preset controller anything to do correct, but when we get to that config controller you haven't talked about yet Yeah, they can both talk to each other. Yes. Config and settings can talk to each other. Yeah.
[42:59]So let's leave that one out until we understand the other three.
[43:05]This gets back to what you have to keep in your head. You have to know in your head that the preset controller can tell the settings controller something to do, but the settings controller can't tell the preset controller. You have to know that in order to know where to look for it.
[43:18]Well, no, because the variable names are going to tell you what's in play here. The variables are all named correctly, so you can see in the file what it's doing because it's all so well-named.
[43:31]Yeah, but I'm going to go in and code something in presetcontroller.mjs. I'm going to type in some new code. I need to know that I'm not allowed to do anything. I can't talk from the preset controller to the config controller. I can only talk to the settings controller because that's where the arrows go.
[43:48]Well, you don't need to know that because if you look for what's the name of the variable that goes the other way where there is no arrow, you're going to find the variable doesn't exist. So you don't have to remember the diagram. The diagram is showing you the variables that exist in the code. The diagram isn't telling you what to do. You don't have to keep it in your head. It's in the code. There is no variable in the config controller. There is no...
[44:13]I have to open the index.mjs to know that.
[44:16]No, no, no, no, no, no. So imagine you're editing something in the preset area, right? You don't like the way the preset shape of the web page is. You want to change something in that part of the web page. So you've looked at it because that's where the problem is to be solved. So you've come to the website with a specific task, which even it's in the green part of the user interface. So you open the preset controller file, and then in there you will see right there in front of you which parts of the variable names will tell you what it can talk to because the variables are there for what it can talk to. So you'll know exactly what's in play.
[44:55]Because she's already written it.
[44:56]Right. But if you need to make a new dotted line appear, just add a new variable. If you need to make them talk to each other, then you add the variable, and then they'll talk to each other. The diagram doesn't tell you what you can't do. The diagram is telling you what the code does today.
[45:14]Okay, okay, okay. That makes sense. Hmm. But nothing talks to the views except their own controllers.
[45:24]Yes.
[45:25]But since that variable exists I could add something that said that the preset controller is going to talk to the settings view You absolutely could.
[45:33]That would be valid JavaScript but that's not MVC, right? So this is why MVC is a philosophy that we're imposing on the code So the philosophy is the controllers talk to each other the controllers talk to the model but you don't mix the...
[45:48]Yeah, yeah So I don't have to hold all these variable names and ideas in my head But I do need to keep in my mind that each controller talks to its own view. No controller talks to somebody else's view.
[46:00]Right.
[46:00]Yeah. Okay. So it's the org chart is in your head, not all the fine details, the fine details of the code.
[46:08]Okay. I don't have to understand the structure of the DBA team. I just know I'm not allowed to talk to their view because I'm over here in the sysadmin team. Okay.
[46:17]Yeah. And in fact, as I was saying before, every controller class has a constructor. And in the constructor, I set class variables with this model view, settings controller, password controller, whatever is necessary. They will add it there. So later on, you can use the class variable for the controller you want to talk to.
[46:49]All right. We haven't let you go through in order in your code at all. Where are your notes? Where would you like to jump to next?
[46:55]Okay. Well, the views and the controllers, we already said it, they form a pair. And so the controller is more or less a manager, and the view is just the stooge that does the thing on the UI. so that also by splitting the code that does something and the code that just drives the UI by separating that it makes it also easier to test them because UI testing is one of the hardest parts to write and whenever you can separate the code that is easier to test from the code that's harder to test you'll have a win yeah
[47:40]Ui testing is one of the most difficult things just why because you have to is it's opinion no you have to simulate users doing things in your code you have to simulate people clicking on things things hiding things showing the test is did this thing show properly it's easy for me to tell another human being how do we tell a computer to do that automatically right right right
[48:07]Yeah so and one of them the ideas behind unit testing is if the function you want to test is is trivial you don't need to test it so if we can write trivial functions with only a few lines of code where it's very obvious what happening and there is absolutely absolutely a minuscule chance of something going wrong, you don't need to write a unit test for it. If I have a controller, a function that only calls the model, for example, to generate a password, I don't need to write a test for that model because I've already written all kinds of unit tests for the xkpasswd class to make sure that it generates correct passwords according to our specifications.
[49:01]
Binding Functions in the View
[49:02]Okay. Okay. So are we going to talk about the views themselves?
[49:07]Yes. What every view class has some class variables that point to some section in the HTML. For example, in the preset view there is a variable called preset group which is the actual preset box that can open or close the accordion box and there's the preset header because that's the line if you close the preset box and you've selected a preset it will show which preset is selected And the reason these variables are there is that when you change the name of the ID or the class or whatever selector you're using in jQuery to, well, actually, yeah, what you need to use in jQuery to access this part of the UI, there's only one location where you have to change it in your code. Otherwise, you change all over the place. And I've been changing IDs and classes in the settings part, I think, maybe 10 times. So having these variables keeps me sane.
[50:18]So in the constructor, you can see which piece of HTML is tied to which nice pretty name. So $octothorpe, pound sign, whatever we're calling it this week, preset-button-group. there's going to be something in the html that says id equals preset dash group and so in your javascript code you can just call it preset group and then if helma decides that preset dash group is not the name you want you change the html and there's only one place where the html joins the javascript that's in that constructor i
[50:54]Am delighted to point out that i was able to find the ID preset-bitten-group in index.html. So I was able to find something that I thought I knew where it should be, and it was there.
[51:05]Yes.
[51:07]It's growing on you. This first time that's happened in four months.
[51:12]Okay. What is also in these Vue classes, I call them bind functions, and that's simply because the function's name starts with bind. and what they do is they bind a handler to some UI piece
[51:32]I like that naming convention. That's nice.
[51:35]Yeah, I give two thumbs up to that as well. I'm going to do that in my other code I do elsewhere. That's a fantastic naming convention. We need to bind this to this. I like it a lot.
[51:45]So those aren't in the view.mjs files? Yeah. No, I said they're not. The word bind is not.
[51:54]The bind function is in the view class.
[51:58]I'm looking at settingsview.mjs and I can't find the word bind it does.
[52:03]On line 74
[52:06]Line 74 line 74 in settingsview? yes line 74 says star valid process and save the settings, it's a comment yes.
[52:19]Yes it might mean, Alison, that you need to pull some code anyway Anyway, in this function, and I put an example in the show notes for the password view class, because that's a very easy bind function. So it binds a submit handler to the button to generate passwords.
[52:51]That seems like an important feature of this interface.
[52:53]Yes yeah so if yeah if you look at the example that there is a bind generate password function which takes one argument called handle and then it sets up a submit a submit handler so it does prevent default stop propagation then it takes the the number from the number of password it feels, checks if it's a number and if it's not it just sets the number to one. And then it calls that the handle function with the number. And this handle function is actually defined in the controller class. In the controller class, if you scroll down a little in the example, you see a generate password function, which is passed on by the controller class. And this takes the number as an argument and then goes over to the model and asks it to generate a password with the number as argument. And then it does all kinds of things to make sure that the view is rendering it. Yes.
[54:03]So just to help. So the view's job is just to connect the HTML to the JavaScript. And what does it mean to generate a password? That's the controller's job.
[54:17]Yes.
[54:17]So the viewer said that when someone submits this form, i need to go call this function over here that's all the view is doing the view isn't actually making the password it's saying dear controller the function i want is generate password yeah generate passwords
[54:32]Yeah so actually the the view doesn't know anything the view just knows i get this argument from the controller which is called handle i know it's a function and so i can call it with my number variable as argument and the controller has bound this that's why it's called a bind function it binds not only the HTML to to the JavaScript but it also binds the handle in the controller to the view
[55:11]Yes.
[55:12]In your example, you said, so it says bind, generate, password, handle, and then it goes through and it says, okay, on form submit of this ID, we're going to go through and we're going to go ask for the password. You said it calls the model. Where in that code do I see that it calls the model?
[55:29]Nowhere. Okay, so the magic happens on the example, the one line example below. that one line is actually in the controller because the controller is in charge of everything and the controller says bind the generate password to this.generatePassword so the controller is saying what function and
[55:51]How do I know that this.generatePasswords is talking to the model?
[55:55]That line is from the model this.dollarView that is inside the model
[56:03]Describe it because the audience isn't looking at the show notes necessarily Okay.
[56:06]So it is from the model and it says this. So it means myself. View.bindgeneratepassword. This.generatepasswords.
[56:20]How do we know that's in the model? It says it's in the password controller.
[56:24]Yeah, so this is the controller. It has a variable called hashtag view, which is its view. So it's the password view. This has a bind function called bind generate password. And I pass it my own controller function generate passwords.
[56:49]So we're not talking, is this single line of code, is it in the password controller or is it in the model?
[56:55]It's in the password controller.
[56:57]So Bart thought it was in the model.
[56:59]Did I say model? Oh, I'm sorry. I used the wrong words. No, my brain was sorry. I used the wrong words. That was a verbal typo. I am so sorry. That's very confusing today of all days.
[57:10]Considering the fact that the question I had was how do we know when we're calling the model? Yes. So how do we know we're calling the model?
[57:16]Well, this generatePassword, that's the one that's calling the model, and that's written below. And the meat of this function is just you can – it has one argument called a number, and that one calls this being the controller, hashtag model, which is the model class, and it has a generatePassword function, which I call with this num argument.
[57:48]Where is the clue to me in any of this that we're talking to the model?
[57:53]This dot octo sort model.
[57:57]Yes.
[57:58]It doesn't say that. It says this dot hashtag view.
[58:02]Sorry.
[58:03]Oh, we moved along.
[58:07]Okay. So, Alice, okay. Sorry. So this.generatePasswords, you were asking, how do I know that this.generatePasswords calls the model? Well, the next example is the content of the generatePasswords function.
[58:23]Okay.
[58:24]And inside the generatePasswords function, it says this.octothorpeModel. So there's your clue.
[58:31]I'm looking for it. Okay. The constant pass in stats says this.octothorpeModel.
[58:37]Yeah. So I call this function and it returns an object and this object contains passwords and statistics. So that's why the variable is called pass and stats.
[58:52]Okay. I don't think I'm ever going to get this, guys. I really don't.
[58:58]Alison, in the abstract,
[58:59]I don't know where we are anymore.
[59:01]Right, we're confusing you more because we haven't got a specific thing you're trying to do. So the big picture is really, really, really important. And that will tell you which class to go get things in. And then a worked actual, I need to make this button do this thing instead of this thing, will make the penny fall out of the air.
[59:29]Yeah. I feel like I need the connector diagram, and we've got that here that tells me where I should go look for something, but I don't know how to tell that it is looking for something in a different file. So when I open up index.html and it's got something, or I end up index.mgs and then it calls something, how do I know where that thing is and figure out where that thing is that's where I get lost, and I don't know that I've a lot of this I've gotten a lot closer but I think we just took a turn I may never recover from but that's okay because I don't I'm never going to look at the library I got news for you kids that's not going to be my job that's.
[1:00:09]Kind of the point though that's actually a really the fact that you just said that tells us that we've done things right
[1:00:15]That I'm not going to touch the generate passwords part?
[1:00:19]No, no, the fact that you know you don't need to go into the model because you're working on making the user interface better. So that's already a sign of success.
[1:00:27]Yeah. Oh, good, good. I thought you were going to say that's a sign of failure. No, no, no, no.
[1:00:33]No, no.
[1:00:33]Good. Keep your grubby little hands out of the library.
[1:00:38]Yeah. You triggered me. you said something like, how do I know what is where? Every file starts with a list of imports. And if, for example, we take the password controller and you scroll up to the, this one doesn't, oh, yeah.
[1:01:05]Every means most. Except for the preset controller.
[1:01:07]When a programmer says every, a programmer always means most because you can guarantee that whatever file they have open to show you every, it doesn't have the thing. Always, 100% of the time.
[1:01:17]No, true. Yeah, because this is like Node.js. Yes, you can include files from different directories. So if you use a Node module, you would do an import. I think, Bart, you explained import somewhere along the line.
[1:01:36]Yeah.
[1:01:37]Yeah, I can't remember what episode number. It was before Git.
[1:01:42]
Introducing the Config Feature
[1:01:42]Yes, it was.
[1:01:43]Which means a long time ago.
[1:01:45]It was in the ES6 part of the classes, I think. Yeah. Yeah, so the index.mjs file lives outside of the web directory. So it's on the same level as the web directory in the lib directory. So if it wants to use some of those classes, it will have to import them.
[1:02:13]Okay. And I see it doing that, yeah. Yes.
[1:02:17]So you will see there a whole list of classes that are imported. And so it says preset view from .slash web slash preset view .mjs.
[1:02:31]I really like that 10 lines of code. I think what I'll do is I'll take a screenshot of that and pin it to my screen. Where is it? Okay, it's over there.
[1:02:42]That's actually not a bad thing. You know the way you can have a split view in VS Code? You could leave that on the top of a split. Just leave it at the top of a split and then work away below that.
[1:02:53]On one tab. Yeah. Well, no matter what file I'm in, I want that one over there.
[1:02:58]Yeah. So here you can see that the class names are actually the same as the file names, except for the casing. So the classes are Pascal case. and the file names are lowercase.
[1:03:17]Alison, this concerns the convention again. This is one of those things. This is how programmers do it.
[1:03:22]I like it, though.
[1:03:22]Okay.
[1:03:23]Yeah. No, no, no, that's fine. Okay, are you going to tell us about this fourth controller yet?
[1:03:29]The proof of the pudding is in the eating.
[1:03:32]I'm hungry.
[1:03:37]Yeah, so in June of 2024, Luis Tavares, and his handle is irsheep on GitHub, he created a pull request to add a feature that was already requested several times. How can I store my own settings, my own configuration and recall it or whatever? And at the time I was working on the import export of the configuration files as they were present in the Perl version of the website. But he took a different approach and he created a settings link. So he basically said, I'll take the object of all the settings and somehow squash it together, encode it as a base64 code and add it as a query parameter to the URL of the website. site and so if you would um bookmark that url you can always start xk passwd with your own preferred settings which
[1:04:56]Is a brilliant feature so basically you set things up the way you want you make that url you save that url it'll look like garbage because it's just this big hexadecimal will go up on the end but when you open the url it's the settings are right where you left them
[1:05:12]Yes yes um and it's what what he did is he put um this input box below the settings and you can see it in the ui the screenshot i showed before it's right below the um the settings bar just above the Generate Password title. And it's basically a link, and it has a little copy button. So you can copy the entire URL with the glob, and then you can open it up in a different browser and make it a bookmark.
[1:05:52]So are you saying that you implemented what he, or you accepted the pull request from Luis?
[1:05:58]I accepted the pull request, and then I had a look at his, because the feature is brilliant. I want the feature. But the way he set it up was he created a config class that handles the encoding and the decoding and it drives the settings link and the copy button, et cetera. And he put half of it in the config class and half of it in the settings controller and the settings view. And because I was working on the import and export of the JSON files, I thought, well, this is all having to do with saving and restoring your own personal configuration. Let's take this out of wherever it is and put it in a separate config controller and config view.
[1:06:50]So you created a new config controller and new config view?
[1:06:55]No, I didn't at the time.
[1:06:57]You had a config controller.
[1:07:01]Yes.
[1:07:02]Oh, I see. That's how this came to be is you had this new feature and that said, wait, this is different. This isn't part of settings. It's not really part of a preset because it's a personal configuration.
[1:07:14]So what I did is I sort of destructured his code and put part of it in the controller. so the stuff that generates the URL and parses the URL, that's all in the config controller. And then the settings link and the copy button and the update is in the config view. And then when I finally finished my own import-export code to import and export the JSON file, that I could just add that to the config controller. And the only change I had to do is create a helper function in the settings controller, like update this. No, the other way around. I had to change the settings controller to say, wherever the settings change, change tell the config controller to update this settings link and generate a new url
[1:08:26]So the url is generated by the settings controller or the config controller.
[1:08:33]So imagine you're changing the settings. So the settings controller is in charge of changing the settings. And the last thing the settings controller does is tell the config controller, you need to do your work again because I've just gone and changed everything.
[1:08:49]Okay, so I've just changed the separator from a star to a dash or a pipe, and it's got to go tell the config controller. And then that just changed that long glop of code at the end of this URL that's generated. But the code is still Luisa's.
[1:09:05]Yes.
[1:09:05]Yes. The code that actually generates the URL and parses the URL, that's Luisa's.
[1:09:14]Cool.
[1:09:15]So the name of the functions is probably a little bit different. And the location of all this code is different. but the code that actually generates and parses the URL, that's Luis's and that's untouched.
[1:09:34]So, I don't see the config controller anywhere. It's not in web.
[1:09:43]It is.
[1:09:45]Password, preset, and settings.
[1:09:47]I think you have older code checked out, Alison, which would explain why your line numbers were different earlier.
[1:09:53]Yes, that's what I think.
[1:09:58]You know, maybe I pulled the show notes. What branch should I be on?
[1:10:03]Main.
[1:10:04]Main? Look, 90 changes.
[1:10:07]90.
[1:10:09]Yeah.
[1:10:09]Yeah. Okay.
[1:10:11]So you were in June.
[1:10:14]Yeah. Well, that explains it. Okay. Yeah. Okay. Oh, look, there's Config Controller.
[1:10:19]Yes.
[1:10:19]Thanks, Louise. makes me want to go find that line 47 again but okay 73.
[1:10:26]I think wasn't it 74
[1:10:28]Whatever it was yeah yeah so okay so you're not forcing the naming conventions.
[1:10:35]I'm not forcing the naming conventions.
[1:10:37]You just said he named things differently and not the way you had been naming things. No, no.
[1:10:42]She said the opposite, Alison. The names have changed from what he gave us to match our convention. So the code is, his code is still 99% the same, but it's been slightly renamed and moved about to fit into the structure. But it's still his code.
[1:10:58]I feel much better. Good, good, good.
[1:11:01]Yeah.
[1:11:02]I love that. I love that the community is out there working on it exactly as the vision always was, right?
[1:11:09]Yeah. And that's not just a little thing. That's a major feature.
[1:11:16]
Celebrating Milestones and Contributions
[1:11:13]Like, we contributed something of spectacular value to the project there.
[1:11:17]That was like going to be in version 4 or something that we always wanted it.
[1:11:23]Yeah.
[1:11:24]Yeah. So we might have a chat about the UI itself. I'm not real... When I looked at it, I had no idea what that section of the UI meant. So I might have some suggestions on that before we declare victory on it, if that's OK.
[1:11:40]I have some opinions, too, but I'm saving them until I have some. Basically, actually, I may as well tell the audience now. I've done my trick again that I did last year of working 11 months and taking a magic month off. So January may see some spectacular changes to XKPastWD because I don't have any work work in January. XKPastWD will be my work.
[1:12:02]So, January will be your month off?
[1:12:06]Yes, so basically we have a scheme where I can work 11 months and get paid for the 11 months over 12 months. So my salary shrinks and then gets spread out. And so January is my month for me.
[1:12:18]Aha. I just made sure that my boss will know that I'm off from December 9th until the Friday past New Year's Day. Nice.
[1:12:30]Nice.
[1:12:31]You Europeans and your work-life balance.
[1:12:36]Yes. Yes.
[1:12:37]We don't believe in that around these parts.
[1:12:41]Yeah.
[1:12:42]Okay. So is there anything else you wanted to tell us about what Louise did there?
[1:12:46]Well, actually, no, the fact that I could pull Luis's code out into a separate controller and view pair, and that there is only one change to the settings controller to update and use his code, sort of drove home for me the setup of this project, so this MVC pattern actually works.
[1:13:14]Yeah, yeah, because it wasn't a big muck about in the middle of a bunch of different files that are unrelated that you had to go pull on all these little strings and figure out what it was doing. It was self-contained, or you were able to quickly make it self-contained in a new way. That's fantastic. Yeah, yeah, that is a proof of the model. I'm a believer.
[1:13:34]Great. Yay! Great. Right, because actually, because I also finished my own upload your previous JSON configuration and export it again, that feature is also there. And I believe with this, we finished porting over all the functionality of the Perl version of the website. So we hit our first milestone.
[1:14:03]It is. We have feature parity. That's pretty darn cool.
[1:14:07]Yeah, All right. You said at the time of this episode, the fourth pair is not working, but I thought it was working.
[1:14:18]Yes. Well, it's working, but it hasn't been tested. And I couldn't leave it up. I couldn't leave it in a branch for you to test because that would be very difficult. So I just bit the bullet. I pressed the button. So it's up there for everybody to test.
[1:14:35]So it's working, but not proven.
[1:14:38]At the time of this episode, the functionality is available on the website, but it hasn't been tested yet by many people. All right, cool. So that's the exercise. That's the homework from this episode is to go test it.
[1:14:51]Yes, yes. And maybe figure out what, for example, if you can follow the pattern of one of the bind functions, where does it get initialized and what does it do where? and how do you know what this handle function means.
[1:15:11]Okay, great. So does that wrap us up?
[1:15:17]Yes, it does.
[1:15:19]Yeah, and I just want to say thank you very much, Helma, because that was a wonderful primer for me. I'm sure I could have figured it out, but this way it's taken me an hour. Otherwise, it would have taken me three or four. So yay, and thank you.
[1:15:35]And I can confirm that I'm sure I couldn't have figured it out. So teacher's pet and the obtuse one have come together here.
[1:15:47]Alison, do you have an idea that you can now follow along and figure out what is where?
[1:15:55]I think I've got a good shot at it. Let me put it that way. Because before we got on, the part I really understand is HTML, the part you refer to as trivial and not real programming. That's my happy place over there. And I couldn't figure it out before. Because there's two index.html files. There's these index.mgs. else. What the heck is that? Where are all these other files? So, now I have a fighting chance to at least do the trivial part. For example, that copy button is in the wrong place on the mobile version. The copy of the settings link is messed up. And I might be able to figure out how to fix that. Maybe.
[1:16:36]Well, I think you can just shorten the input box.
[1:16:40]No, don't tell me how to do it, Helma. You need to be able to figure out what file it's in. That's the tricky part.
[1:16:45]I was going to say what you have now, I hope, Alison, is basically, even if it hasn't, there's no way it's all sunk in because it's a lot. But I would imagine you can ask a much more sensible question because you're going to get a lot further before the question is asked. Yeah. I don't know how to explain that for you.
[1:17:09]Start with, I have, no, no, no, no. My sentences will no longer start with, I have no idea where to start, which is what I've written every time for the last three months.
[1:17:18]Yes.
[1:17:20]All right, Helmut, thank you so much for this. This was great. And I think it worked well with Bart helping me understand and interpret what Helmut's saying and vice versa. So I think that was helpful. So, Bart, you want to close this out?
[1:17:31]Oh, I guess I should. Actually, I want to start by saying, Helmut, thank you so much for the sheer, it is astonishing to me how much further this project is one year later since we had that was it christmas eve or new year's eve we had a one-hour chat on skype and it is just amazing to me how much work you have done in that year and it is just a testament to the whole concept of open source and i am eternally grateful for all the work and that it's all contributed to everyone That is just amazing.
[1:18:03]And I've been recommending it to everybody and not even been worrying about whether it's still in flux or not. I've been sending it to everyone and saying, use this. And I've been using it every day since it got stood up. So, yeah, Helma, you're the bomb.
[1:18:18]
Closing Thoughts and Future Directions
[1:18:16]Okay. Well, thank you.
[1:18:18]So on that note, happy computing to everyone.
[1:18:23]Well, I sure hope you enjoyed this three-way lesson in programming by stealth. and I've got to thank Helma for all of her work pulling me along through this episode. If you want to chat with Helma or Bart or me, you can find all of us in our Slack.
[1:18:36]Music