 All right, so the topic today is using composer with WordPress. If you are not too familiar with what composer is, I'll kind of walk through that a bit. The thing to note here is, if you've got a question as you're going through, feel free to ask it. We can do that via the chat box over here, or if you want to interrupt me, that should be fine, too. If you just want to ask it. Anyway, so my name is Micah. And you can find me on the internet at WPscholar.com or just Google WPscholar in general. You should find me. So we're going to just kind of, let's see if I can get the slides. There we go. Kind of jumped in here. So obviously, to give a little bit of background, we want to cover a little bit about what is composer. So basically, composer is a project level dependency management tool. It's a CLI tool, and it's specifically for PHP. So if you're familiar with things like NPM, which is the node package manager, which is basically a dependency management tool for JavaScript, this composer is essentially the PHP equivalent for that. So why should we be using composer? For one, it eliminates duplication. So for example, if you have a particular set of code that you want to reuse, composer allows you to have a source of truth for that. So you'll have your own repository where that can live and then can be versioned. And then that way, any time you want to load it into a new project, you're pulling it from that source of truth instead of copy-pasting, where you end up with three different copies of it in three different projects, all at three different states, because you fix random bugs in each section there. It gives you some consistent versioning. So it allows you to say, I'm going to use version X of this and version X of that. And then if somebody else on your team goes to install things, they're going to get the same versions as you installed. So important to note that. And then it's going to make your code more reusable because, again, you're not having to remember which project you use that thing in. You'll have your repository where code specific to whatever it is that you've built is going to live. It's going to give you an easy way to kind of see what dependencies exist in a project. So you'll know you can open up the composer JSON file and you can see exactly what dependencies there are and what version rules and constraints are there as well. Let's see, slides keep losing focus. So some of the features of Composer, automatic package installation, so all you got to know is the name of the package and it can install it automatically. Bulk package updates, so if you want to update all the dependencies in your project, that's a simple command away. Class and file auto-loading, this is kind of the magic that makes Composer work. Composer takes all the code and puts it in kind of like this black box and we're really not supposed to reach inside the black box and try to load code or do anything like that. So the way that Composer works is it gives you essentially a PHP class or file auto-loader so that all your code can be loaded automatically at the time that you need it, at the time that you call the class or need the file. It handles recursive dependencies. So if you have multiple levels of dependencies, you don't have to worry about those things getting out of whack. It can do platform checks. Within the WordPress space, like if you're releasing a WordPress plugin, for example, that you've built using Composer, you may want to turn off the runtime platform checks just because everybody's platform's a little different. So unless you have hard requirements that you definitely want to check for, you might want to turn that off because if a platform check fails, it will make the site inaccessible. So probably don't want that to happen. Package discovery makes it easy for you to find packages that other people have written. But again, in my opinion, if you're a developer and you haven't been using a tool like Composer, you definitely should. It's going to make you a much better and much more efficient programmer, both because you can use other people's packages and because you can reuse your own packages pretty easily. So the installation process is going to be a little different depending on what type of machine you have. It can be installed on Windows and Linux and Mac, but the process of doing that's a little different. So I'm not going to get too bogged down in that. You can go to getcomposer.org and you can click on the Getting Started. They do have a download link. Don't be fooled by it. Click on Getting Started and then look for the install method for your particular machine. And that's usually the best place to kind of start by getting that installed and set up. So if you don't happen to have it installed, I recommend you go ahead and just kind of maybe do that while you listen. If you do have it installed, then maybe you can try out some of these things as we walk through it. So the first thing after you get Composer installed is you're going to want to run a command called Diagnose. So Diagnose is basically just going to check your system for common errors and things that misconfigurations that tend to happen from time to time as you're installing Composer. So again, so when you see these slides like this, where it says Composer or something, that is a command. So Composer is always going to be the command you'll run. And then the sub-command is going to be after that. I've highlighted it in this case just to made it bold in this case so that you can easily see what the focus is as we're changing commands and adding flags and things. You'll notice that we will highlight those for you. But yeah, Composer Diagnose is going to be very helpful. A lot of people don't know about this or do it, but I'd recommend that be the first thing you run after you install it. So then we want to kind of jump into a little bit about how Composer works. So Composer starts out with creating something called a Composer.json file. So this Composer.json file is going to live in the root directory of your project, whether that's a plugin or a theme or a WordPress site or some other PHP application you're building. You'll need a Composer.json. We'll show you how to generate one of these later. But if you look here, you can see it's basically just a JSON file. The first thing it has in there is name. And so we have WPscholar slash composer dash package. So every Composer package is going to have this naming convention where you have the vendor name first, then you're going to have a slash, and then you're going to have the name of the package itself. So typically, if you go and put a new repository up on GitHub and you do set up your Composer.json, the name would match the username, typically the GitHub user name is going to be the first part. And the second part is going to be whatever you've named your repository. It doesn't have to be, but that's kind of the most common naming convention. So if you're not sure about that, that's usually how I do it. You give it a description, a license. Here, we're defining GPL 2.0 or later. And then you can put multiple authors in here. You can add name and email. There's also, I think, Homepage, which they use for a website. And there's even a role field, I think, where you can say developer, designer, however people were involved in the project. And then we have the Require section. So the Require section is where the real magic happens, because this is where you're going to say, here are my dependencies. These are the things I'm using on my project. And here are the version constraints. So these aren't the exact versions. These are just the version constraints that say, OK, well, if you're using anything up to Symphony's YAML package version 6.0, anything before 7.0 is basically what that rule was saying. That's what we want to use. So all those rules get defined there. And then the other file, this one is going to be auto-generated by Composer, but it is a ComposerLock file. So while you're in your Composer JSON creating general rules about the versions that are allowed, the ComposerLock file is going to store the exact versions of a particular package. And it's going to document them here. So the ComposerLock file is what ensures that if you run Composer install, the next person who runs it is going to get the same thing because the exact versions are stored in this file. So this isn't a file you'll edit, but it's a good idea to commit this file to get repository with your Composer JSON so that anybody else who pulls the project down and runs the command to install all the packages will get the same packages and not varying versions just because it's trying to pull from the JSON file. Because if the lock file doesn't exist, it'll install whatever it can from the JSON file, which is, again, general rules and not hard versions. So just be aware of that. And then the general file structure here. So we have our Composer package. And then we have this vendor directory. So the packages represents our repository. So the vendor directory would live inside of the root of our repository. And that's the black box that we don't want to reach directly into. We want to use the conventions that Composer gives us to autoload files and things like that. So we have the index.php file here represents the actual PHP files that you might have the Composer JSON and lock file set alongside of that. The vendor directory sits in that same root directory. The structure of the vendor directory, just so you'll have an idea, there is a file directly inside of that directory called autoload.php. So this is a file that you'll actually need to load so that Composer can do all of its proper autoloading. So that's the only file that you'll go into the vendor directory and require in your code. The bin directory is used to store executables. And so, for example, if I were to install WP CLI, normally you would type WP to run that. In this case, if you install it locally in your package, you'll want to type vendor slash bin slash WP. And that would run the locally installed WP CLI, for example. There's a Composer folder in there. That's always going to be there because that will contain the dependencies that Composer needs for itself to do its own job. But here we can see that the one thing that I did install was the symphony YAML package. So inside the vendor directory, we have a folder specifically dedicated to a specific vendor, which is in this case would be symphony. And then the individual packages they have underneath that are also directories, which contain the actual code. So the YAML file folder is going to contain all of the code for that YAML package. You'll notice that there's this polyfill C type thing that also ended up in there. That's a recursive dependency, not one we explicitly added to our project, but one that got installed because of YAML package, depending on. So let's see. Yeah, so this is the one line of code that you do need to make sure you have for Composer to work. So you'll have to require that vendor autoload PHP file. So typically, you'll add this as like first line of code in your index PHP or whatever PHP file that you happen to be using to kick things off. And then as long as you've included all the packages you need, you can just call the classes and functions and whatever those packages provide without having to do a specific require for those files or anything like that. Well, so speaking of which, in WordPress, if you are working with, say, a plug-in or theme, this will go into that main plug-in file or your functions PHP in your theme to make sure all those things get loaded. If you're working on, let's say, you're trying to use Composer to build out an entire website, this line would actually go in your wp-config file at the very top, just to make sure everything gets loaded. So before we get too much further, I want to talk a little bit about semantic versioning and some of the versioning rules that Composer allows. So as far as semantic versioning, the idea here is that we have three-digit number separated by dots and each number represents a specific type of change to a project. Not everybody follows this, so it can be a bit of a trap sometimes if people don't follow it, but I think the majority of people now see the value in it and do follow semantic versioning. If you don't follow semantic versioning for your own stuff, I would highly recommend it. The idea here is that the very first number in your version number is the major version and that is something you'll increment anytime you make breaking changes in your application. Now breaking changes basically means anything that relates to your public API, things that other people, you know, if you change some functions inside of your package and it's just, you know, they're all internal private things, then it's not really a breaking change, but if you are pushing out a change in the way that somebody calls an API or, you know, you change the name of a class that people might be using, that would be considered breaking change and would require a major version bump. So the next number is the minor version, so that's something you want to increment anytime you add new features that are not breaking changes, right? So they'll be backwards compatible. So yeah, so we have the major version, minor version, and then finally we have the patch version. So if you have like some sort of bug fix, maybe like a security patch, something like that, that last number would indicate that type of an update. So no new features in that scenario, new features that are not breaking changes would be the minor version. So that's kind of the gist of semantic versioning. So now we're going to kind of shift a little bit and take a look at the ways that Composer lets us define our version constraints or rules inside that Composer JSON file. So obviously we can say, I want this exact version. Composer tends to frown on this because of the fact that it's very restrictive, right? So if you have someone who has project A and another person with project B and they all have different dependencies and then maybe like you restricting that very specific version locks things down in a way that there's no way that project A can make things compatible, but maybe project B could make it compatible because they have different things installed. So just be aware, probably not a good idea to lock it down that much. But then we have version ranges, right? So you could say, well, anything that's greater than or equal to version one, but still lower than 2.0, that's what I want. So you can define a range like that. And this is kind of the syntax here that you would use to do that with the comma separating those. So the other option here is to do like a wildcard version. So in this scenario, the 1.0.wildcard is gonna say, okay, any version of 1.0 that has like a bug fix or security patch, we want to allow it, but we're not allowing the version changes that would entail breaking changes or new features. So it's just those patches. Then we have this tilde next significant release rule. So basically what this is saying is only versions up until the next significant release are allowed to be installed. And what does next significant release mean? In this scenario, the tilde is going to allow changing of the last number to find up until the next version is defined, right? So like it'll allow you to iterate through from number two to number three to number four to number five. But if it ever gets to 2.0, it won't allow it. If I define this rule as 1.2.3, then it would allow me to bump the three up and up and up, but not bump the two, the 1.2 into a three. So it's always gonna take into account that last number. So it's a little bit of a nuanced rule there. The more reliable and the default for a composer is this next major release version. And so you use the little carrot symbol and then you can do like 1.2 or even 1.2.3. And then it'll allow any changes all the way up to a 2.0, which would obviously be a breaking change. And so it would stop it before that happened. So that's the default. And that is typically the general recommendation for that, but you can define those rules a little bit differently if you want. There are some stability flags. Now these would be placed in the same place you would put a version rule. So you could say at stable, and this would allow any version as long as this is a stable version, right? So like if I had 1.2.3 or even 2.0 or 3.0, it would allow it. So it would always get the latest stable version, but what it wouldn't do is get like, I don't know, 10.0-alpha or beta or RC or something like that. Then we also have this at dev, which will basically pull whatever the most recent code is from the development environment. So in other words, if you have a get repository and you're pulling in this package, it's gonna pull from master. So even if there's not a tagged version of it, it'll pull from whatever the most recent master branch or main or whatever you call it. So yeah, so using composer. So we're gonna take a look at using composer from a few different standpoints. So basically just kind of walking you through the common use cases that we might have in general versus in WordPress and how we'd go about, you know, running the commands and doing all those things. So first things first, you've got some code, you wanna reuse it, you wanna create your own package. So you wanna, you know, first thing you're gonna do is you're gonna create a get repo for it to go into. And then of course you're gonna have the code on your machine and so we're gonna step into what do we do next? So on your local machine where you have your code, it'll all be in a folder, right? So you'll have your package packaged up inside your directory structure there. And then you'll from that root directory type composer init. And so this is going to actually walk you through step by step how to create a composer JSON file and that will look a little bit like this. So in the scenario where, you know, this is the generated JSON file down here towards the bottom. So these are kind of the questions that you're presented with. What is your package name? And again, you're probably gonna use your GitHub username and your, whatever you named your repository on the site on GitHub, put whatever description makes sense. Typically a composer will automatically grab your, if you're using get and you've put in your name and email, you know, registered those things so that they'll show when you do commits. Composer will grab that automatically. So if, like in this case, you see it in gold, you can just hit enter and it will automatically fill it out. So it does the same thing with the vendor name and package name as well. It's just grabbing my GitHub username and then the name of the folder that I happen to be running the command in. You can choose a package type by default. The package type is library. So if it's left empty, it's considered library. You can have a project that would be more like a, let's say a WordPress site. If you're trying to use composer on a WordPress site, you'd probably call it a package. And then there's other types as well. We'll get into a little bit later, the fact that there are some WordPress plugin and WordPress theme types that you can use. You know, you'll define your license and then you potentially could do some interactive definition of your dependencies. I usually opt out of that and I like to run the commands individually for whatever I need after that gets generated. But yeah, so it's just gonna use short answers and you'll have a composer JSON file there. And you can see in this scenario, the require section is empty. So I'm gonna go back and run some requires to add items in there. So in general, you should never actually edit your composer JSON directly. There'll always be a command that will update it for you. So, but yeah, so this is the anatomy of a package name, right? So you got your vendor, like we said, it's a GitHub handle and then you have your package name, which is usually the repository slug. You can, you know, use anything else, but the fact that you've already got that name reserved on GitHub usually means that nobody else is gonna use that same name. So let's see here. Yeah, so once you have composer set up, you know, how do you work with it in an existing project? So what are some of the things you might wanna do? Well, first you'll probably wanna pull in some code that's not yours that will help you speed up the development process. So you're gonna go out and look for packages. You could do that from the command line, but just typing composer search fill in the blank. And then that will list out some packages and have some links back to those packages on packages.org. Packages.org is the website where you can go and also just do a search there. If you prefer to not do it from the command line and you can find packages that would pertain to, the functionality that you need. So once you find a package, you're gonna run composer require package. And of course, package here is just a placeholder for a full package name. And so that would be the vendor slash package name rule there. So you composer require whatever package you want and it will add a rule to your composer JSON file based off the current version of that package. And it will install it into your vendor directory. So at this point, you have it and it's already defined for you in your composer JSON file. You can specifically define a particular version by just doing after the name of the package colon and then the version name or version that you want. So now this would be a version rule. So you could use an exact version, but it's better to use more like the carrot Persian or some other one of those rules that we were looking at earlier. When you go to require a package, you have the option to make it a dev dependency. So if you don't add the dash dash dev flag on the end, it's gonna be a production dependency. And if you do add it on the end, it'll be a dev dependency. And there we'll show you a little bit about how you can do an install for your local dev versus a production environment. So one of the things you might want to install on a production environment, let's say if you're building at a WordPress site, you might wanna require the Yoast SEO plugin. So that would be a production thing. You don't want it to not be on production. But for dev dependencies, you might say query monitor, which is a dev tool but you really don't want it on a live site. So you might add that as a dev dependency, just as an example. If you added a package and you realize it doesn't do what you want or it's the wrong one or you misspelled the name or something like that, you can always run composer remove, type out the package name and it'll get rid of it. And then the composer install, this is the command that you'll run to install all your dependencies. So if you've set up a project and you've done your requires and you've got it all packaged up and shipped off to your little repository, of course, we haven't officially released that yet. We'll walk through that in a bit. You don't have to run composer install because you literally ran all the commands and they installed each thing one at a time. But if somebody else on your team goes and pulls down your package and they run composer install, that's what we'll make sure that they have everything that they need. And then of course, if another team member updates a package and then you need to make sure that you have all the latest stuff, you just type composer install and if there's something new, it'll pull it in automatically. So important to note that. If you're deploying to production, you'll wanna run that install with the node dev flag and that will ensure that anything that's a dev dependency gets stripped out before you go deploying your code. So let's say you do have your code and it's in a Git repository somewhere and you've run your composer in it and gotten that whole thing set up. What does it look like to say I have this repository, I want this code in this project? So first things first, we're gonna add our Git, on GitHub for example, you have that HDTPS or SSH URL that you use when you clone a Git repository. You will use that, I recommend the SSH if you have SSH keys set up, but basically you'll run the composer config command. I usually do repositories.package because that is where all of these, basically what's happening there is you're telling composer to look not just at packages.org for things, but also this URL. So this URL just happens to be your Git project URL. So you'll run that fill in the blank with your own Git URL and that will make sure that composer will also check that location for your package. Of course, if your package is there and you don't have a composer.json file, then it won't actually be able to do anything with it. So you do need to make sure you run composer.init in that Git repository and have that composer.json file there. And then once you've done that on your project, on your local machine or where you're pulling this in, you're gonna run composer.require and then the username slash package or vendor slash package. And you're gonna run that to pull in your project. So again, when you've generated that composer.json, whatever the name is for that json, for your package, so that vendor name package name, that is what you'll use here. And because you've named it that and you've pointed composer at that repo, it will read the metadata from the composer.json and know that when you're doing a require for this package, that it should pull it from there. And of course, if you are in development, you might wanna do a colon at sign dev just so that it pulls from master. If you haven't tagged a release or anything like that. If you have tagged a release, then you could just call in this and it will pull in the most recent stable version by default. So I've pulled in custom code into my project. I've pulled in other people's code into my project. What does it look like to manage a project, make sure things stay up to date and that kind of thing. So in this scenario, we wanna run composer update. Composer update is in a command that you run normally. Composer install is the one that you run to just make sure everything that you should have is there. But if you know some things are out of date, like let's say if you're doing a WordPress site and a plugin is out of date and you've loaded that plugin via composer, you can run composer update and it'll pull in the latest version. But again, it's gonna follow your rules in the composer.json file, meaning that if I have a plugin version 5.0 and it has a 5.1 update, when I run composer update, I'll get 5.1. But if I have 5.1 and there's a 6.0 update and I run composer update, I'll get 5.1. Because again, my rule is generally gonna be that carrot sign, you know, 5.1 and that will allow all the updates up until but not including 6.0. So just be aware of that. So composer install, the first time you run it, here kind of behind the scenes, what it's doing is it's saying, let's read that composer.json file and it will create a lock file. If you have a lock file, it'll only read the lock file. Your composer update will only read the json file and it'll ignore the currently installed stuff and then use your rules to determine what to install. So it is still possible that after you run composer update, things might not be entirely up to date, but there's a check we can do for that. Just a side note, if you wanna update a specific package and not everything you can do that, you just have to provide the name of the package. But this command, composer outdated, is what you'll run to find anything that is out of date. So this will include revealing to you, if there's a 5.1 with a 6.0 update that you're not gonna get when you run composer update, composer outdated will show it to you. And so if you do need to explicitly update from say 5.1 to 6.0, easiest way to do it is just run composer require package name and it will install the latest version because it's treating it as a new dependency. So unless there's some conflict and reason it can't actually update to 6.0, the composer require will always pull in the latest. There's also a composer audit command. So if you're concerned about potential security issues, a lot of those things are tracked and reported and the composer audit command will highlight those things for you. So it's good idea, particularly if you've got some sort of automated deployment process to at least run it. So those things kind of are in front of you as you're looking at your code. So what does it look like to set up a WordPress site? So everything we've covered so far, it's standard composer, it could be a layer of old projects, it could be a WordPress plugin, it could be a WordPress theme, it could be a whatever, right? But in this case, we're gonna kind of step back a little bit more, say, okay, what does it look like to set up a WordPress website using composer for dependency management? So first we need to install WordPress and we're gonna install WordPress as a dependency. And I know it sounds weird because WordPress is the thing that we put all our stuff into, we don't put WordPress into our stuff normally, right? So the key here is just separating out WordPress from everything else and making sure they're not nested in each other. We are letting them run alongside each other. So because WordPress allows you to have an alternate directory structure, this is what makes it easy for us to do this with composer. So when we run composer require, and this is the John P. Block slash WordPress package, which is essentially a WordPress installer, it will put WordPress into a WordPress folder inside of your website project folder. So you have WordPress in its own folder and then we're gonna put all our other stuff in a separate folder. Typically I'll have like a content folder off to the side where I'll put plugins and themes and that kind of stuff into. So the next thing we're gonna do is we're gonna run that composer config command again. And this time we're gonna do repositories.wpackage and then composer. So this is registering, essentially it's registering wpackages.org as a composer repository. So basically it's saying, in addition to packages.org, we wanna look at wpackages.org. But again, you can go and browse and find plugins and themes and stuff on there. But basically any WordPress plugin or theme that is installed on the .org directory for WordPress plugins or themes is essentially composerified. And there is a way that you can use wpackages to pull those things in. So obviously we just need composer to check there to see if a package name that we're trying to require happens to live there. So we're gonna run composer require composer installers. So composer installers is a special composer package which basically extends the functionality that is default functionality of composer to allow for additional project types or library types or whatever you call it. Package types is what I'm looking for. So it allows you to have other types and also kind of helps manage the location in which those types end up because a lot of projects WordPress is obviously an easy example but there's plenty of other PHP projects out there where things have to be in particular folders for them to work correctly. And of course WordPress themes and plugins are no exception. Themes go in the themes folder, plugins go in the plugins folder. If they're not there, they don't get loaded and WordPress won't even recognize it as a theme or a plugin. So running this will just ensure that if you have a WordPress plugin or WordPress theme package type, it gets handled appropriately. So the next thing is in our composer JSON file, we're gonna add this little extra blob that's gonna go inside with all the other content that may already be in your composer JSON file. And so there's a few things here. One, if you happen to want to put WordPress in a folder that's not called WordPress, like in this example, I like to use just WP. Again, because it does show up in the URL when you go to your WordPress admin, it'll be something like myside.com slash WP slash WP admin. So it is a little different. Great for security because it obscures a little bit, but I like to type WP instead of WordPress so I could keep it short. So I can add this little WordPress installer rule in there and it will allow me to customize the name of the folder that WordPress is in. So like I said, I usually have a WordPress folder and I have a content folder. So the content folder is to where I want all my other stuff to go. So there is a WordPress MU plugin type, a WordPress plugin type and a WordPress theme type. And these installer paths that you're seeing here are basically saying, in the content folder, there's an MU plugins folder and inside that we're gonna dynamically insert the plugin based off of the plugin slug into a folder. Now, of course, MU plugins are typically standalone files, but that's a little different. But the plugin folder or slug name for a normal plugin would go into that content plugin, plugins and then whatever the name of it like Yoast SEO or something like that. But all that gets handled automatically. So when you require a particular plugin, if the type is properly defined and you've defined these rules, it's gonna automatically end up in the right place. So because we've kind of moved things around a little bit, we do have to set up some constants in our WP config file, just so WordPress knows where things live. So apps path is usually, you know, dir slash, actually I need to add a trailing slash on this WP because apps path is typically has a trailing slash, but in this case, we're doing a slash WP, which is where WordPress core, the files for WordPress live. The WP home, technically you don't have to set that. You can just have that in the admin area, but usually if I set site URL, I like to set WP home just for consistency. It also prevents somebody from accidentally changing values in the admin and breaking site. So I just defined a WP home and then WP site URL. So WP home is the front end of your site, right? Like what URL do you want to see your site on? So we're not, we don't want site.co.dot slash WP, we want our actual domain, right? So we wanna keep that the same, but the WP site URL is the place where WordPress files live and because we put it in a slash WP folder, the URL is gonna be, you know, hdbssite.co slash WP. The WP content directory, again, is no longer slash WP dash content. We're just gonna call it content. And then we're gonna have our plugin and MU plugin and theme folders and stuff inside of that. So we can relocate our content directory just by defining that constant there and then telling it it's in the content folder. And likewise, the content URL at our domain with the content path added to the end. So once you've done that, I'm gonna tell you the easy way to do it. So I built a nice WordPress site scaffolding tool in Composer. So Composer has this great little command called create project. And running this command right here will actually give you a fully set up WordPress website using Composer. So the command is Composer dash dash remove VCS. So basically what's gonna happen with that flag is after Composer pulls down the WordPress site scaffolding and it runs Composer installed to set everything up, it's still gonna have that version control from when it got cloned down. And so the remove VCS flag just removes all of that so that then you can link it up to your own custom Git repo for the project that you're working on. But yeah, so it does create project and then WP forward slash WP site that is the specific Git repository I've set up where that site exists. So if you go to github.com slash WP dash forward slash WP dash site, you can go there now and you can look at the general structure and setup of my scaffolding for a WordPress site using Composer. But running that command by itself will just set you up. But once you're set up, you still will have to install the themes and plugins and things that you wanna use within that site, right? So WordPress will come with specific themes by default and I think it, well, technically it comes with a few plugins by default, but because we're doing WordPress in a separate folder and then we're saying our plugins folder is over here, you can't really have two plugins folders. So no plugins are installed by default in a Composer setup. So to require a specific plugin, you'll run Composer require and then WPackages does the prefix dash plugin. It could be dash theme, but in this case, we're doing a plugin. So WPackages dash plugin slash the slug of the plugin. So if it's like Yoast plugin, technically the slug is WordPress dash SEO. So that's what you would put in the, in there and that would install the Yoast plugin. So, and again, that just pulls from WPackages, which is the Composer-ified version of all the plugins on the plugin directory. They're basically the same thing for requiring a theme. So you've got, you know, WPackages dash theme and the theme slug to install a theme the same way. And then as far as creating a WordPress or plugin or theme as a package, this is what that would look like. So it's very much similar to kind of a just a generic package. You'll run Composer init, that generates your Composer JSON file. You will customize the package type. So once that Composer JSON, well, in the process of running the Composer init, you can define your type as WordPress dash plugin or WordPress dash theme. Or if you forgot to do it, you can always just edit it manually in your Composer JSON file. But usually I try to avoid manually editing the file. And then the next thing you're gonna do is you're gonna actually ship your package, right? So like you want to make your plugin or theme available. So the assumption is that, well, we have two different types, right? So we've got our public repositories and private repositories. So if you have a private repository and you just want to use it, the process that we showed earlier, where you're adding your git URL and requiring your package that way, you can do that. If you have a public repository and maybe it's a plugin or a theme, but it's not like, you're not putting on WordPress.org, you can submit it to Packagist and it'll register it into the greater Composer repository. And then, so you can go to Packagist.org, click the submit button and then put in the URL and it will automatically add it to its database of things. So if you're just shipping a plugin or theme to WordPress directly, it'll automatically get pulled in via that W Packagist. So you don't have to like ship it to Packagist. But if you're just releasing like a, some other package that's just like specific functionality, maybe it's not a theme or plugin, you can release it this way of doing it via Packagist. So, and of course, once you've registered it with Packagist, you can always run Composer Require, the vendor slash name and it will pull your package in. So I have a special note section. These are just like things you probably didn't know about Composer, but it's really cool and really handy. So I'm happy to run through those, but we do have like eight minutes left. So if people have questions, we're gonna kind of go through those. We already have one asking if we can elaborate on how to set up a project as a WordPress plugin using Composer. So might be a good scenario where we hop out of this, hop into the terminal here real quick and we can kind of walk you through that real quick. So let's see here. Let's do this. Let's do, let's create a new folder. My plugin. So for creating a plugin, you know, it's called my plugin. That's the plugin slug. I'm just gonna open, sorry, I'm gonna do code here. So this will open BS code at this plugin folder and I will drag that over here. So we have a plugin folder. So first thing we need is a, you know, a primary file that's gonna get loaded. So we just add a new file. We'll just call it my plugin.php. And that should have added it there. Yeah, create file. So here we're gonna do our, you know, php and then we're gonna have our plugin headers. So we'll have like plugin name, my plugin. I won't fill out the rest of that, but this is basically our plugin here, right? So we wanna make this composer friendly. So let's see here. I don't use, well, no, that's not what I wanted. That's right. We'll use this terminal here. So I'll run composer init and this will detect the folder name. So it's, you know, detecting my GitHub handle. And it is, oh yeah, this is really small, probably isn't, let's see here. Let's make this just a little bigger. Whoops. Yeah, so we'll hit enter, but that'll set the package type, description, my cool plugin. And then the author will hit enter. Minimum stability, normally you don't need to set this unless you're doing like requiring code that's not stable, but it's better to use those stability flags I showed earlier and not to set minimum stability. So I recommend you just skip that over every time. In this case, this will be a word press plugin. And then, you know, we'll do GPL 2.0 or later. And then I don't wanna do any kind of stuff here on the fly. So once I've done that, we end up with this composer JSON file. So if I then say, you know, get init, that's gonna create a Git repo. So if I look at the files that I have now, I've got a Git folder, composer JSON and a plugin file. And then I would just commit this up to a repository and then I could do that config command that, you know, where we pull the URL from GitHub. And then I would just do a require wpscholar slash my plugin and it would load that from that repository. Let's see. Oh yeah, thank you for pointing out where the terminal thing is there. So what if we have the composer JSON? How do we set the type? So again, if you followed the process here, we did fill that in here as part of the package type question that the composer init command gave us. But again, if we forgot and we're like, oh, well, let's say maybe this was a theme instead, we could manually come in here and do theme like that. Now let's say we messed something up and forgot a comma and now it's not valid JSON. You can come over here and you can run composer validates or even shorthand composer valid and it'll tell you, oh, shoot, you messed up your composer JSON file. So you need to put that comma back in. So we can come over here and throw that comma in and then if we rerun that, it'll, well, apparently I didn't fully fix it, did I? It's not contained valid JSON. I think I fixed it up. Oh, I didn't save it. Yeah, again, PHP storm is what I usually use at autosafes for me. There we go. Composer is valid. So I got a question, can you repeat when that runs? So when what runs, I'm not sure what you're referencing there for the plugins. So you're saying, oh, the composer JSON with a list of plugins. So yeah, just another quick, quick thing. Let's do this. Let's back out of directory, make a new directory, call it my site. Well, actually we don't even need to do that. We just need to back out of directory which you've already done. And then what we'll do is we'll run that composer. What is it? Remove VCS, create project, WP forward slash WP site. So that is gonna clone that repo down. It's gonna run composer install for that particular repository. And I even have it set up to where after it runs the composer install command, I have some custom scripts that we'll hook in and it will create like a assaults PHP file that lives outside of the WP config file. And also uses, this actually uses something called a .env file, which is a bit more of a best practice as well. But yeah, so we'll just give it permission to run that composer installers and to use the WordPress core installer. And so this is gonna pull in WPCLi and one of the extensions for WPCLi. You can see it ran a custom script and it said that it generated the assaults. So now if we open up that in VS Code here, this is what you end up with. So that is, that does not look like, oh yeah, we didn't change into the, hold on. Didn't change into this directory. So we put this in the WP site directory. So if we open that, this is what we end up with. So here we have our content folder, which contains soon as VS Code finishes loading there. There we go. Our MU plugins folder, plugins folder, themes folder, uploads folder, index PHP. And then alongside the content folder is a vendor folder, which contains all the things. So you see I have, there's a WP scholar folder, which is my vendor folder where my packages would live. And then inside of that is this PHP .env package that I created. So all those things on the vendor, and then WordPress files all live over here. This is really great, especially if you're trying to do a search for like specifically some function in WordPress and you don't wanna get a whole bunch of convoluted functions from other plugins, that's separate, right? You can run a search through this folder and get just WordPress stuff. And you can run through this folder and get nothing but plugin stuff, which is great. This alternate directory structure also gives you a really good idea of when a plugin is poorly written because those plugins will break because they didn't take into account this structure. So the better written plugins are the ones that actually work correctly. I think more and more plugins actually work correctly this way. So it gives you a .env file. And so this will actually allow you to define a lot of the information in this .env file. And yeah, so it's got your get ignore and all the other things in here. There's this register theme directory, which just ensures that from the WordPress directory where the themes here are here. It also includes these themes in addition to whatever themes you put in your themes folder here. So if we do wanna add a WordPress plugin, just as a quick example, composer require and then we're gonna do wpackages dash plugin. Slash, let's do WordPress SEO. And so what we should see is the WordPress SEO plugin end up in this plugins folder, which we can see that happening now. And here's where the Yoast plugin lives. And the reason it got put there is again, because in our composer JSON file, if we'll let us scroll down here, we've added this little extra. So hopefully that clarifies things on the plugin versus website as a whole situation. But yeah, feel free if you've got more questions or something that we can't answer here to just like reach out. There's a form on my wpscholar.com site you can fill out and reach out to me. And I'm also on WordPress.org Slack as a WPScholar if you happen to be in there. But yeah, I think we're definitely out of time now. So I think we'll call it, but I will, yeah. So there is the learner survey link just got dropped in there. So if you have like just a few minutes to fill that out, we're trying to get as many people to fill that out as much feedback as possible. And then for these slides, I think Wes is going to get that link from me and we'll post it on the meetup page. Or I think I can do that myself too, but anyway. So appreciate everybody coming out and have a good day.