 Hello. Thank you for being here today in one more webinar from Moodle Academy. Today's webinar is about MoodleNet and MoodleNet for developers particularly. And today with us, it's Alessandro Giassanti with the MoodleNet backend developer and Paul Holston, the MoodleNet product manager. Paul, would you like us to give an overview? Hello, everyone. I'm not going to take too much of your time. This is really Alessandro's webinar just to give you a little bit of background information. It's been just over a year since we released the latest version of MoodleNet and we've had lots of requests from developers about how they can adapt MoodleNet for their own use. And Alessandro and the team have been doing a lot of work in the last few months to enable this, to restructure MoodleNet and to enable packages to be written. So what we're going to go through today is essentially the development environment, the architecture that it's based upon and how to create and test packages. So then I'll come back at the end and talk about how you can contribute and accessible development practice in the future. But for now, I'll pass you over to the very capable hands of Alessandro. Alessandro, take it from here. Yeah, thank you Paul and hello everyone and thank you for joining. I'm Alessandro Giantsati, I'm a developer at MoodleNet for MoodleNet project. And yes, today we'll have our webinar to introduce the interested developers around the globe to on how we refactor the MoodleNet version 2 and how we are refactoring it to enable customization and enable developers to develop packages to extend and customize MoodleNet. Alessandro, can you share your screen? Oh yes, I will share your screen now, sure. And we will start directly from the development environment for MoodleNet. Well, development environment actually is just about having a good IED for developing in JavaScript or we recommend TypeScript as the software is written in TypeScript. JavaScript is also supported. So we need actually no JS in the environment in our local machine and in production also when we want to install it. And ArangoDB instance service running, ArangoDB is the database of choice of MoodleNet. So it's the main database and currently the only one that is needed for running MoodleNet. So we are going to use BS code as a day editor, as a preferred editor, because it has very good support for TypeScript. And yeah, we're just, we're going to use Docker for deploying the needed ArangoDB instance, but you can have it running however you like. The best way to develop, for the moment, the best way to develop a custom package for MoodleNet is starting from our project repository. Okay, first, maybe I should talk about some terminology, we will talk about the packages and extensions. And when we talk about packages and extension, in some way we're talking about the same thing. Packages, we say packages because packages are the standard MPM packages as any library that you can find on MPM.org, for instance, for JavaScript. And those packages, this is how extension custom functionalities and new functionalities for MoodleNet would be delivered and published. So we talked about packages because we will develop extensions for MoodleNet in packages, in JavaScript packages. Typically we use, maybe we will use extension term, mostly from the user point of view, because user admins when they will want to install new extension using the admin page, they will talk about extension, not packages. So, we can start by having, cloning the repository of the project, which is this one. We can just use, issue a couple of command yarn at the root folder project, project folder, and then yarn init depth to initialize the project to start to have it ready to develop. I actually did already all this stuff because it would take sometimes, you know, sometimes to install the dependency as usual with when we talk about project with a bunch of JavaScript dependencies. Moreover, sorry. So I already done all the initialization of the development environment. The first thing we can do here after initializing, having initialized the development environment, we can, well, see how it works. Next, we can start a development, sorry, a development backend. We can install a development backend in the development environment and start it with these two commands. We can do it here. So I am, I launched a terminal inside the model net project. Here we are. This is the model net project, the repository, the cloning repository. And we can issue this yarn that we start being in my depth. Yeah. My depth is just a name is a custom that you can choose to be whatever is just the name of the directory in which the back end will be installed. And let's see what happened. The, the, our development environment always install this development back ends inside this directory dot dev machine. So we now have this my dev, which is the name that we choose it here. I might have directly with an installation of modern net. And we now can start it with the issue in the common yarn that back end always passing the same the name of the directory of the installation director we choose. We can have many installation directory maybe with different, different configurations, we will need to test different configurations. So we can, yeah, now yarn that back end. My depth. Okay, here we are. Oh, sorry, I forgot something. I actually have to first. As I am saying here, we have to ensure that the language is running on local host. So I will run it with this. I'm running a Docker inside the Docker container, because it's quite handy for us to have it in Docker. But I'm going to run it here now I'm running a complete empty around the database. And yeah, let's step in a little bit just a moment into the other database interface, we can see what how is in on local lost. On port 85 29. And we'll have a nice UI that ships with that only be and see what's happening in there. We can see that we have an instance running, but we don't have any database inside of it. Now I said, as we tried before we can start the development back end that we installed it. And while it starts, we can watch what's happening in even in this database. Okay, first run will ensure that all the system packages are installed. So it takes just a couple of seconds. Now it's starting all the core packages that will give the most important features for movement. So if you go here and just well refresh the page, we will see that we're having where the system is creating some packages with some strange names. But we will get to it later and you will understand better what's happening here for the month to have three databases. And now it's hanging because crypto, we need some systems that needs some cryptographic keys and it's creating them now and it takes just a while. That's for the first launch. And meanwhile, it's, it's starting. Well, it's almost ready takes just a couple of minutes, the first time. But I would like to jump to and have a look on how is the modern architecture. So, modern architecture is what the software stack is very simple because it's the software is the whole software is is developed is built from what from back end to front end all in JavaScript well actually type script. And the whole code base is in TypeScript. And so we have the, our code base will run in two different environments in two different platforms on the back end it will run on Node.js. And on the front end of usually on browsers on any modern browser. I would say also that actually the JavaScript is full stack completely full stack from the back end to the browser because actually around the DB is a is a is a back is a database that is a is a JSON database. And it, even the query language is a resemble very much JavaScript. It looks very much JavaScript and it stores data in JSON format. Yes, the main, the first seat is an entity talking about the code base is MPM packages. Every functionality each functionality, or each set of functionality of the system are encapsulated in us in a independent MPM package. The other thing to keep in mind and the other feature of the system and it's a must for the moment is that we support for the moment only the new Xmas script modules from Node.js and from X from JavaScript from for latest Xmas script versions. We may support legacy modules, but for the moment we just support Xmas script modules. While on browsers, the main technology that we use is it act 18 and all the stuff that comes with it like HTML, SAP, CSS, CSS 3 and whatever other library that could be useful. So software architecture, the asset every every function every functionality is isolated in a is implemented in an isolated package. So the core main model that is is is comprised of a number of packages at the moment we have all those packages that sets up a standard installation or movement of core. The core package is the fundamental package that lets the whole framework. And it's about keeping all together all the function functionality packages. So we have a bunch of fundamental packages authentication manager direct application content graph we will talk about this other packages that give services like the ability to graphic email services. Other packages that's about about content. Other packages that have some the implementation for authentication. Yeah, and some utility packages. I would go too much about the details because it will take too much time, but we will have some information about all the core packages that we have in model and modern that installation. Just a couple of words about the core. The core keeps together all the functional packages and mediate the communication between them. It manages the boot sequence and the installation that great the installation and the upgrade of the packages or the system. Then we have our good to be that just manage the other database instance and then we have a communication manager that manages users in as a centralized with centralized APIs with centralized functions. An HTTP server and extensible HTTP server must say that most of the package are extensible. Then we have a direct application based on react. This is also extensible. Now I have a content graph, which is the heart of modern that actually here. This use along with the B and makes a database in the Rango DB instance and here you every package shares this database using this. The APIs of this package content graph and this database. This will be stored all the content, the content meaning all the content that users what user will see on the on the web application. And so different packages with different functionalities will insist on this content graph package extending it and making relation between different entities coming from different packages. An overview of all the core packages that we have here are some installation and how they are related in the system, what package uses or depends on the package how packages use other packages and how they depend to each other. So that's why versioning is for the packages is independent, but I wouldn't get too much into this now. It's more interesting to understand how to create a custom modern package. Let's see what's happening here. So the system is started now. We can see that after those databases after crypto has created these cryptographic keys, if we refresh, we see that we will have we have other databases. Every package, every function package. At on demand can ask that our database are going to be packaged to install or create a private database for its own purposes. So we have a database for the organization package, another base for the email service package database for the authentication and so on for the content graph. And so on. So we have a bunch of databases now here running with some data on it inside of it. So let's check what's happened if we go we have the server listener listening on port 8080. So we just jumped into localhost 8080 and we'll see. More than that running here. Okay, at the moment, it doesn't have many functionalities. But the moment we have, you can see functionalities for. Yeah, all the framework for extending stuff and for extending the react application and the back end and all the functionalities for for creating new user for login and sign up. And so if we want to see something now for the moment, we have to. Well, for the moment, just join create a new user. And at the moment we have just one. This just one authentication method, which is the simple email authentication method. I mean, this is a package. It's called a simple email you can see it here. In the log. And this is as well as standard authentication and sign up method you just provide an email and password and you have to confirm your email by a link that you get into your email. And that's all. Well, at the moment I didn't, I didn't configure an SMTP for the email service. So as a default, until we want to. Until we configure the email service SMTP, we just get the link that should be sent to the to the to the signing signing up user. And the link that confirm them so for the moment we can just copy it and confirm the mail manually this way, but this would be should be a link. Okay, we created a new user now. That's the user that I created. I can see my file. I can edit something and save whatever. I can log out and log in again. Okay, sorry. Okay, and log in again. Right. Authorization are not yet implemented. It's the first thing that we do from tomorrow. But now any, any sign up user can step into the second page, for instance, here we are. Here we have the second page. The second page have some functionalities some basic functionality for changing. Well, the stuff that you see on the main page, like we can change this one with with a new title, hello world, and say, yeah, simple stuff, nothing, nothing, nothing credible. The thing that is interesting for the moment for us is the extension section here we can see that we have here we call it extension for the users, but we know that they are packages. We see all the packages that has that are installed and running on the system. And you can see that these are all the main or the core packages that we have here. So let's understand this. Let's see a little just for a little while. How does this installation directory look. We have a package JSON. And we see that the packaging so defines all the packages that will be installed in the system and will be run in the system. And you can see that these extensions are the same that you see here in development these points directory to the to the to the folders here to development folders. In production that would point to a npm registry and point to an npm registry package. And we will see this later too. Here in the slides, you can see there are there are a number of steps to make to develop a simple very simple demonstration for a simple. Custom package. I want to go through all of these. But I will talk about all these steps in a in a much faster way. We can use. You see, in this package directory, we have all the core packages, but there is also a. Another package, another directory, which is called my modern mjs package template is just a template very simple custom extension custom package that could be used as a reference to understand how things work here. So let's say that a package. A modern package for extensive for extending modern it is just a simple standard npm package with its own package Jason. Here we have it. With a name with a okay it must be type module as we said that we currently just support a ESM modules we need to support just we need to know the JS major equal 16 because this will support properly the ESM ESM packages ESM modules. And with an export. Yeah, this is the the maybe you are used with the main property of package Jason to to define which is the main module in ESM it's better to use exports, it's, it looks like the same this is like it works like the same if you choose the point. And you point to the, the main module you have it's just equal to the main property in standard package Jason. And here we say that, yeah, a standard typical modern package will must have a dependency to to a modern that call because the modern that call is the fundamental hook to modern that system so you need to. To have a dependency to modern that core in as a peer dependency. This I won't get through this explanation of this now, because it's time consuming but we have to declare or the dependency that we need from modern it. And from other modern that packages in the peer dependency for the moment we are going to use the core, the react up, because we want to extend the react application to the component library, because maybe you want to use some components that are designed to be look good to look good on our on our react application that has some design patterns. First of all, we want to, well, before getting into the code, let's install it. Typically, on a production situation, you would have this section in style extension, and you would see here a list of compatible extension, making that, well, the system would make a query to MPM to the registry. And check for well extension that are published there. But at the moment there are none so we don't have any compatible extension MPM. But for development, we can have the we have the possibility to install an extension from our local directory to have this option enabled. We have to go to advance it, set the UI in developer mode. And here in the install extension, we will have also this option from local code, local package. We can copy the path of this package folder. Paste it here and say, oh, okay, we will open also here the log of the backend and install it. Okay. Okay, we don't click it. Okay. What will happen now? The system will install the package, this package in the system and restart the system and reboot all the packages. We have the system restarted now. And if we check out here somewhere in the log, we should see somewhere here is the system is importing and connecting my MooderNet and JS packet templates. This is the thing that we just installed it. Well, let's see what's happened here on the installation directory. On the installation directory in the packages, we see that we have a new package installed in the dependencies. So here we see all the set of packages and functionalities that are running in the system. This is a new one, the new entry. Now let's see how does it work. Let's see how is the code for the, how did we develop this package. The first thing to say is that the boot sequence will import the main module of the package. So it will import this one in this case. Let's go and see it, main mjs. And we see that there are a bunch of things going on here. Well, first thing to do is to import some functions for MooderNet Core. Because we want to hook into MooderNet into the MooderNet Core into the system. And the first thing to do is to connect this package. So we can use this function, connect package. We passed the import meta. This is also something that I want to get into the device here and into the because. And we say that we want to connect this package and we want to provide some APIs for this package. Now we will get into the APIs later, just in a while. Then I saying that I want to use also the React application because I want to extend this to so I get a reference to this importing it. And I ask the MooderNet Core to use this package. Now I can use this reference given by the core to the React app and I can call the plugin API in React package. And I'm telling to React package, look, I want to extend the React application. I don't want to extend it. And I will give it an entry point for my extension, for my React extensions. And I will give a path to this main component JSX, which is stored in SSRC web app main component JSX. Here it is. We will go through this just in a minute. Let's see the APIs. I'm saying that my package wants to publish some APIs. The API definition is just an object, a structured object. Where each leaf of this object is a definition of an API. We have an API here that is inside a structure of as hello and world. This is a hierarchy. And the API is just a simple function that takes some parameters and returns a promise of something. That's all. I get parameters and I return a promise. I return with a sync or however you want to do it, but it must return a promise. And it gets as a first, as a courier parameter, a context. Let's see how it works. And now it provides also a simple function that should validate the parameters that should be passed to the API. So here we want to ensure that the first parameter is a string and the second parameter is a number. And we can return something to H2 that tells the system that parameters are okay. Let's see. By default, the system will or HTTP, the HTTP package, HTTP server package will publish the APIs that the package APIs through HTTP. So we can see that we can already use these APIs. The API that we have defined here. By a post call to 8080. MyModernet. Here we have a prefix that is the package name, the version. And then the path to the API that we want. So in this case, hello world. Then we pass the arcs. And let's say that we pass two strings instead of two string and a number. If we call it, I get a validation failure from here. So I get a message, the pattern that I sense, and just a taste of what you can find in the context. For instance, in the context, you can find who called this API. In this case, it's the HTTP server that called the API. I mean, when I say the caller with what package called this API, you would find also information about the user, the original user that issued the call and other relevant information. Let's see what happened on the front end now on here. You won't see much here because meanwhile we are talking the system restarted and the web application recompiled with the new stuff coming from the console package. So if we now refresh the page, we see some difference. Okay, we see a link here. A link here. We see that it's a new page came here. And this page, it looks like it is using the API of this new package. So what happened here? Let's get into the main component that we registered for the React app. The main component. The main component is just a simple React component that will be injected into this into the application. And here we can use some APIs from React app that are exposed to customize the interface. In this case, we are going to use three thing, three registers to register widget or add-ons for the React application. In this case, we are using user register for the routes because we want to add, here are my routes. I want to add a new route that will render the hello world page. I want to register these routes here. And I want to add a right component with a link to my hello world page. And I use this register, right component. And this avatar menu items, I will register something as here. Another piece of code. It's going to be just a link, always to the same page. We can see that we have added a route because we have a new route here that wasn't present before. We have a link here. This is this link here, my page link, added on the right. And another element in the menu, my page. This is what the package have added in the web application. And here we can see also that how we could access the API of our package by using the library provided by React app. So we can just say my package that called hello world, which is the path of the API that we define it. We pass the string, the patterns, one string and a number. And then we get the response and set it here as a state. And then we simply, and we provide it with a context, with a React context in such a way that hello world page can. Render the API response that we for the code that we made on the main component. I mean, this is the main component that we register is the entry point of the for the web application extension. Here we can use all the APIs from different from other packages, code packages or other packages to extend them. And from now on, the whole implementation of the web application features for our package is just free. It's just you can do it as you want. You're completely free to do this. You just want to use probably likely hooks to other packages features to add the widgets or add pages. Once you've done this, you are completely free to implement your, your UI as you like. The same happens on the back end. Once you have looked into, into mood and that core. Well, you can use other packages to, to interact with them using the core APIs and core functionalities. But then you are completely free to implement to your the functionalities of your package. In the way that you like. In fact, in this, in this. We say that types typescript because the whole code base is completely and very strongly typed even in the dynamic parts. So you have strong typings, even when you call APIs from, from their web application, you, everything is completely typed. But if you can, you can see that you can even write a package with standard JavaScript. Note that we are using mjs extensions because as said, we are, we are supporting only ESM modules, ECMAScript, the new features of ECMAScript modules. So let's see here, let's go back to the second page. And if we go to extension page, now we can see that we have a new guy that we installed it. At the moment, any core package can't be installed. But new packages can. So we have installed this. Now we want to uninstall it. And again, we should see, if I click it the right way. Okay. That the system will restart after removing and uninstalling the package that we want to, we wanted to uninstall as soon as the, as the system restored. If we try to refresh the page, we won't see it by once. We still page and this stuff here because it takes a while to recompile the women's on this. It will take a couple of minutes now, maybe less, maybe more, it depends. But as soon as the application has been recompiled, we should see the application as the web application as it was before installing it. What more? Well, I think that's enough. I think we got through every step for now. I just want to see here the web application that has been, it takes just a while, but that's all we can get to question time setting. Thank you so much, Alessandro, for these. Here we are, the application has recompiled and we, and yes. And the page that used to have some content is now not available. Thank you. Yeah. Thank you so much. Before we go to the questions, what about go through? Oh, yes. Okay, but we have something more. Yeah, actually, please go. Yeah, sorry, I forgot one part. Let's say that we are happy with this package. And we want to use it on our production kind of production environment. Well, now I'm in an empty directory, and we just want to showcase how we can install a real modern net installation. We just need some standard MPM command and peaks. And we call it mood and slash create. And we choose a folder destination folder like my deployment. We for the moment we have to this would point to the standard MPM registered MPM dot JS dot org, but we didn't publish yet. We have this published in our own private registry private. Well, you can you can check it out. We have a registry where we test this and this system now, and we have all these packages published here. You won't find them in MPM. So if you want to install with this common you have to add the registry option pointing to this. To this URL. This will install modern net 3.0 alpha 10 in the destination folder that we choose it. It takes some time because it will install all the dependencies. We are also working for making this process much faster. And maybe we can go on with the webinar with other things and we can have a look at the end how to install the package that we deployed that we develop it inside a production like environment. As soon as this process is ready. Thanks. Thanks, Alessandro. Just to, I noticed a question in the chat there. So just to talk about contributing packages to middle next, I think it was when who asked if middle net supported plugin development and this is really this point. Just to ask a clarifying question. I'm assuming you don't mean does middle net accept middle elements plugins because it doesn't. It's a completely different technology stack. But will we have a contribution and a plugin system? Yes, indeed, we will. It will be redesigned to act like an app store that sits alongside middle net through an NPM repository. Obviously, we're going to wait for some contributions before we do that. But yes, absolutely, we will throw in the future if you do develop something and you would like us to make it available to the community then at the moment. Just going to touch with this fire track or the community and we will set up a way of looking at that what you're doing and supporting you on that and getting it out there for community. And apart from that, this is going to just wait and see what we get. I know some of you, for example, are waiting on a single sign on packages to be added. I know that there are some people working with this externally already. So we will be offering those just as soon as those are ready. Next slide, please. And just a final note on there's a link there into the accessible development practices that obviously a whole of mood will try and work towards. So if you are developing something, the code outputs are very important that they are accessible and we check accessibility on everything now. If you want to have a look, there's a link there to our accessible coding development practices course in case you want to check the standards we're working to. Just like to say thank you. And if there are any questions. Oh, just just I would like to answer a couple of questions from the chat. Can you just allow me to read them through so we can have them in the recording as well. Starting from Jeffrey, who asked about mood net is meant only for content creators or also for consumers. And Paul has already addressed this accurately, saying that mood net is for anyone producing educational resources of any kind or sharing and curating resources. And if you are interested is another course in the educator pathway here in Moodle Academy, where you can see how mood net is used is meant to be used from the educator perspective. And we have a question from Sergio. He says that before releasing version three, you will implement authorization. I can't update to a release with open settings to any on. Or am I wrong? Yes, okay, I will ask I will answer to Sandra Bellino at the same time I would answer to Stefan Robota is the second last one commented because it's about the same topic. Yes. Obviously, we have there's no authorization authorization pattern here. That's the first thing that we will implement from tomorrow, and we already designed it. And it will be surely on more than three. The organization. I can give some just some preview about the logic of the organization system, it will somehow somehow gets sorry, it will resemble a little bit concepts from all out, meaning that will it will be based on scopes. API is will be assigned to scopes and users will be also assigned to be able to access some scopes so scopes will be the main where the main strategy for managing the authorization of the API access or packages access so every package can will be able to define its own scopes. And every package could also will be able to use other packages scopes. So the scopes will be strings in some way that are prefixed with the package name and the end with the package specific scope, the final scope. Thank you. When also asked and I think Paul already answered that about moodlet support, if moodlet supports moodlet plugin development and say that it's completely different. products. Abie says, can a plugin run as separate service on a different container. Well, at the moment, we are focusing on the on the framework on the system on this architecture and it's war and it's decided to work only as a singleton but we even we as model. We will need we will strongly need the possibility to install different well a number of a cluster of instances and also we will need to cluster eyes. The services in these instances having kind of microservices but yeah, I wouldn't only call it microservices but services oriented architecture where some instance will be enabled to perform some services. But not others so yeah cluster eyes to to to have the administrate the ID administration have the control to split the workload between different services and between different instances. So it's not now but this is something that we have in the roadmap for sure. Okay, Sergio asks, which registry software have you installed and if it's open source. Which, ah, yes, okay, this is nice. It's, I just found one that's working well. It's called the virtual. I will type it here on the on the chat on the chat. And maybe I can find also the well if you look it on Google it that's there you will find it. The Dutch.org. Yes. And it works great. It has some just some differences in some queries in the response of some queries. So it's a bit difficult to have to have our implementation for for supporting both MPM standard MPM and that should we will try to have a system that will support both. Maybe we will have the system that will support both MPM standard and that we will strive to have this. Okay, Dimitris, thanks you for the excellent presentation. Stefan, I think you already deal with that. Is there already a user role model implemented or does every user have the same rights? Yeah, I will extend the answer that I gave before. Having a scope based authorization system. User roles can be made up assigning to different roles a set of scopes. Yes. Okay. Sergio asks that should be faster to integrate an OIDC slash out to external out. Yeah, it should be quite simple because we are taking. We're taking. Yeah, the. Our authorization system will resemble the those specs. Today when asked about the moodlet forum to keep asking questions and Paul has provided the official forum from the community forum from moodle.org. Of course, you can still use the forums inside the course for things that can be dedicated to the presentation. And I guess that was all so far. That was quite interesting. Thank you so much. And just to for the conclusion. I would like to invite you to get involved in the growth of moodle Academy by contributing to its development. I will suggest topic ideas and you can go to the getting both course from the course main page from the side main page and suggest topics to be covered in the future. You can also contribute to webinars if you have some expertise and subject and of course you will receive a presenters badge, and you can also contribute to course development. And of course, again, you will gain course builder badge. So help us spread the word about moodle Academy, you can tell your friends and colleagues about the courses offered here free moodle academy. They can everybody can learn about by completing a course and even our current course the moodlet for developers will be further developed and we will have a batch as well. And of course, do tell others about moodle Academy and if you have friends were educators and not developers that might be interested in the moodle educator certification. Thank you, Alessandro. Thank you, Paul for being here and thank you all of you for joining us in today's session.