 Welcome. So, my talk today is on using Composer with WordPress. So, just out of curiosity, how many people have actually heard of Composer before? How many people actually played around with Composer? And how many people actually use it regularly? Okay, good. And we got a good crack. So, my handle on Twitter is WPScholar. If you want to, you can ping me on there. I'm also on Slack under the same handle. Not sure if anyone's really been mentioning this at all, but every single talk has its own channel in Slack. Mine included. So, if you need to follow up questions that you didn't get to ask or what not after we're done, you can just post in there. And I'll be monitoring that and we'll be able to respond to it. All of the slides are on this link. You don't have to worry too much about typing it. If you just go on Twitter, it went out about four minutes ago. So, you should be able to find that, except I didn't put the right hash in there. So, you'll probably have to go there. Okay. So, the hashtag I forgot. But, so anyways, so we'll be talking about using Composer with WordPress. And if you go to that link, the slides are up there. It's not the first time I've given this talk, but it is the first time I've given it in Atlanta. And there is actually a video just in case you want to rewatch it. There's also a forum there if you're interested. I've got a learning Composer email course with step-by-step email instructions. So, you'll kind of get an email kind of explains Composer. And then another one, you know, kind of showing you how to set it up and takes you step-by-step through the process if you want to do that. And there's a few other links to resources that you won't find unless you go there. Some people who are also good advocates of Composer within WordPress have some great stuff that you can find there as well. So, basically, we're going to start out with what is Composer. Essentially, if you've ever used, how many of you've ever used a tool like NPM or Bower or anything like that? So, essentially, that's the same kind of thing except it's for PHP and not for JavaScript, right? So, it's a dependency management tool. So, what it does is it'll actually allow you to manage your project dependencies as well as your version. So, when I say project dependencies, there's some tools out that allow you to kind of globally manage dependencies. Think things like Pair and things like that that will allow you to set up some global things. Composer allows you to set up global things as well, but it's more useful to have project-specific dependencies. So, if you have three projects that all have the same dependency but different versions, you're not stuck with having to change out versions of that thing. So, why use it? So, that's kind of the most common question when you have a new tool. Everybody wants to know why it's important and how it could really help them in their workflows. So, the first thing it does is it helps you eliminate duplication. It basically provides you with the ability to have a canonical source where your code can live. So, now instead of having multiple repositories containing similar code, you can actually give it a home and just point all your projects to that particular code base. It allows you to have consistent versioning. One of the things that we ran into with a project that I started, I worked on when I first started doing development, we were trying to create a product, essentially a platform for law firms on top of WordPress, and as we got more and more sites that were using it and new features that were being developed, it kind of got to the point where, A, we almost had multiple versions per each client because they all had different feature requests. But the reason for that was mainly because it was really hard to track what version of the code each client had. So, it got to the point where we actually had multiple versions. It got to be quite a nightmare. One of the other things it helps with is actually encourages you to develop in a modular way. And in doing that, it encourages you to reuse your code and it makes it easy for you to do that. So, it will kind of run through what some of those features are. So, the first thing that it does is it allows you to have automatic package installation. So, you can type a simple command, it will go find that thing and download it at the most recent stable version. That's kind of what it does by default. You can change those versions and that kind of thing. But it will actually just go find it and automatically download it, install it, save you the trouble of having to go hunt it down, especially if it's something that you use often. It allows for bulk package updates. So, let's say you install 10, 15, 20, 100 dependencies. It will actually, with a single command, go and update all of those to the most recent versions or whatever your rules happen to allow. One of the biggest benefits is that it allows, it has auto-loading built-in. So, when you include a dependency, normally in PHP, you have to drop a file somewhere, then you have to include that file and then you can start writing code against the code that is in that library or code base. In Composer, assuming that the package is set up correctly, you can actually just do a Composer require and it will include that thing in your project. Anybody else who copies your project down will easily be able to get those things. But the coolest thing is that you can just start coding against that code base. You never have to do an include or require or any of that. It just works and it gets loaded exactly when it's needed. So, if you don't happen to call it in a particular page load, then it's not going to get loaded. It also does recursive dependencies. There are some contacts where you can run into a little bit of trouble with it. But for the most part, it works really well. And if you have multiple packages that require the same dependencies, if there's conflicts, it will let you know and that kind of thing. Package discovery. So, it gives you an easy way to find out about new packages that are available. So, if you know you're trying to do something specific, you can actually do a search and easily find most of the time something that would meet your needs. So, first I want to talk a little bit about what it takes to get it set up. Composer is one of those tools that I've used. And of all the tools I've used, I'd say it's probably easiest to set up. It's very little trouble that's ever given me. There was a little bit of a learning curve initially, but it's the smallest learning curve of anything I've probably had to learn. And it's an extremely useful tool. So, if you have never tried it, at least download it, install it, play with it, it'll be worth it. All you have to do is go to the website, click on there, Getting Started. They have an install method for Windows and then for Mac and Linux. And you can get that set up in just a matter of minutes. Once you... It is a command line. So, if you're not familiar with the command line, don't be intimidated. It's a simple thing. But once you get it installed, you'll actually be able to run a command called ComposerDiagnose. If there happens to be some configuration issue, this command will let you know. And it will make sure that you have all the appropriate tools. It uses Git. So, Git is kind of a requirement. So, if you don't have or use Git, you'll want to make sure that you have that. I was telling a few people the other day that if you're a developer and you don't use Git, just be aware that when I talk to people who are looking to hire developers, I tell them not to use developers that don't use version control. So, if you don't use version control, I want to think about it. So, using ComposerDiagnose. So, what are the commands? How does it work? What does that look like? So, ComposerInit is basically a command that will generate what's called a ComposerJSON file, which is really just a configuration file where you can set some details about your project and kind of declare what your dependencies are. So, once you run this command, it will auto-create that file for you and whatever directory you're in, which usually would be your project route. ComposerValidate will check your Composer.JSON file and make sure it's valid. So, if you have gone in there and manually edited something, you can run that command and if there's some sort of JSON syntax error or you use things that aren't really supported, you may have some thing that sounds close to what it should be, but it's not quite there, this command will help you diagnose those things. As far as actually creating and declaring what those dependencies are, ComposerRequire and then the name of package is going to essentially install that thing and it will also add it to your JSON configuration file. So, that one command will download, install and add this to your configuration so that next time you have maybe somebody else takes your project and downloads it, they can actually get the same version of what you put in there. If it is possible to have dev dependencies, so if you've got a package that you use in production, you want to do it as a regular dependency, you can pass this dev flag on the end here and actually have a package that is only installed for development environment. So ComposerInstall is what you would run to actually download and install all the dependencies that are already configured in your JSON file. So, if that's already been set up and somebody's done the project setup, a new developer could come in and just run ComposerInstall and they're going to get all those PHP packages and libraries that you had configured for this project. And again, if you are trying to do ComposerInstall for production, you just pass this no dev and it will strip out all the dev dependencies that might be declared. So by default, if you run ComposerInstall as a developer, you're going to get all of the production packages as well as the development packages. But in this case with no dev, this will be a production build. And then we have ComposerUpdate and there's a difference between ComposerInstall and ComposerUpdate. And I'll go into a little bit more detail on that a little bit later. But basically this just checks all of the things that are dependencies to see if there are any updates available and if there's updates available and you can also set some rules around whether you want certain updates. So if those rules are met and there are packages to be updated, it will actually vault update anything that you have declared as dependency for your project. If you're already familiar with like Bower, how difficult would the learning curve be for this kind of thing? So I have found that MPM and Bower are actually not as robust as Composer. There's some things about Composer, which I'll explain a little bit later, that those package managers don't have, which allows you to do some more interesting things. They give you a little better control over your dependencies. But ultimately, if you've used those before, there's not a huge difference. So learning curve is not that big. So you can also update individual packages by running ComposerUpdate and then the name of the package. And that way, if you just wanted to make sure you update a single thing, you can do that. ComposerRemovePackage will delete the package from your code and will also remove it from your Composer.JSON file. If you are looking for a specific package or are just trying to find something that's related to, I don't know, CSV parsing or something like that, you can do a ComposerSearch package. Or you can actually go on the website packages.org, which is the website which is an online repository of all their packages that are available. Anybody can actually register their own packages on Packagist. And you can do a search on there as well. And we'll search through all the descriptions of the packages that are available and you'll get a nice long list of things that are related that you can then explore. So, again, with Packagist.org, in order for Composer to actually know about a package, generally it has to be on Packagist.org. However, it is possible for you to register your own repository, essentially, which you can do kind of on a one-off. So, you can do Composer, Config, and it's a little bit of a long-command repository's package name is what I usually do. And then you say get and then the github path to that thing. And essentially it registers that with Composer that this is another place you should check for Composer repositories that we may have. And so, generally you do this per each private Composer repository you have. So, a lot of times on Bitbucket or something, I'll have something I'm not wanting to publicly register. I can run that line and then do a require for that particular package and it'll work just as if it were on the Packagist.org website. So, basically, when this runs, it will either, if it's HTTPS, it'll actually ask you for your password when it runs the Composer install. Or if you're SSH just because you already have those keys on your machine, it'll work. So, along as any developers that are running this have that SSH access, which is usually the route I go, then it will work. But it also makes it nice and easy to share a repo and if nobody has access to that particular thing then that could be a problem. So, that would be a way to keep something private but within a team. Right. Exactly. So, custom repositories do require a Composer based on file. So, you will, in your private repository, need to actually do that Composer hit so that there's enough information there when Composer does come and check this private repository for it to know what the package name is and know that that's a Composer thing that it can pull into whatever project you want it in. But that's a pretty simple process. So, let's kind of take a step back for a second and look at versions and what you can do with that. So, in your configuration, typically you'll have a package name and then you'll have a version and the version is very important and there's a few ways that you can define that. So, the first one here is the exact version which should be pretty obvious, whatever exact version you want installed, you just put it in there. Tools like NPM and Bauer, you have to be a lot more explicit about your versions than you do necessarily sometimes with Composer depending on how you set things up. You can also define a range of versions. So, something like greater than or equal to 1.0 but less than 2.0. So, that kind of restricts what version. So, it's going to expect kind of this minimum version but then there's also this maximum version. So, you can also have a wild card. So, the wild card allows you to have, in this case, the 1.0.star will allow you to essentially get all those bug fix changes that may happen which are usually what that last number represents. And then there's this thing called next significant release which basically says I want anything that's 1.2 or greater but not 2.0. So, it's kind of that same range but it's an easier way to define a specific range. The other cool thing that you can do is you can actually just use stability flags. So, you can just say for a specific repo instead of saying a specific version, you can just say I want this particular package at stable and that will actually, based on semantic versioning which we'll go into in just a second, it will make sure that it gets the most recent stable version of the code. You can do RC which stands for release candidate. So, if you specifically tag things in that way it will restrict to that or stable. You can also have beta, alpha and the loosest version would be dev which basically gives you anything. Whatever is most recent doesn't matter. It will give you that version. So, semantic versioning is something that Composer uses and is kind of hardwired into the way that well not so much hardwired into the way it works but using semantic versioning in your projects will make using Composer a delight instead of just a little bit confusing. So, in semantic versioning and this is kind of the quick version but the first number basically represents the major version and essentially this is only incremented when you make a breaking change. So, if you are releasing something and it breaks older versions you would increment this. As you'll probably know WordPress doesn't actually use semantic versioning. They typically bump with each new version that second number but of course their goal is also to maintain backwards compatibility but that's not always going to be the case with projects. So, this number increments when you make a breaking change. The second number is incremented any time you add new features. So, anything is backwards compatible. It doesn't break anything that you currently got. You increment this middle number. And then the last number is the patch version and is used any time that you essentially have bug fixes. So, bug fixes, new features and any kind of breaking change. Even if it's a bug fix, if it breaks backwards compatibility that first number is the one you would change. So, I want to go a little bit more details on how Composer works. This would be the part where if you use NPM Empower you can start to realize a little bit of difference. So, the first thing is composer.json file. Essentially, if you use the commands this thing will get auto generated. Many times, particularly within the context of WordPress where you'll have to make a manual edit. But for the most part all of this is created automatically. You can see up here we have a name which contains the name of the package. The first part of that is what's called a vendor. So, it's basically a namespace handle essentially that you use for any packages you put out. So, for example, most of the stuff I put out on GitHub or wherever is going to have the WP Scholar namespace and then ComposerDemo would be the name of the actual thing that you want to install. But, you know, if somebody else has something they call ComposerDemo then they would use their handle and so it would have a unique name. Then the description pretty obvious. You can set a license, author information you can also do things like for public projects you might define where you go for support where's the documentation, things like that. And then down here at the bottom is the require. So, these are production requirements you see here which is the symphony yaml library and you see the wild card so it's basically 2.5 and any bug fixes that may come along. The composer.lock file Reading this is really not all that important. Basically it's important to understand what the lock file is and why it's there. And this is the one thing you don't get with NPM or Valve. So, when you run NPM install for the very first time it reads your ComposerJSON file figures out what your dependencies are and installs those things and then it will create this lock file and this lock file basically gives you explicit versions a reference to the explicit versions that are actually installed in your machine at this moment. Now, if you commit this Composer.lock file into your Git repository what will happen is the next time somebody runs Composer.install they will get these exact versions regardless of what the Composer.JSON file says. Which is good because when you're working on a team you don't want to run for example if you did this with Bauer you had kind of this wild card set up and there were some bug fixes that came down the road somebody could get a different version if they run Bauer.install at a later time especially if you and as you get more loose in your definition of what can be installed then you start to run into a lot of problems with tools like Bauer and NPM that's why you have to be more exact but in Composer you can actually just say this is a recent stable version whether it's a bug fix or whatever and it will give you the exact same version every time until you run Composer.Update at which point it ignores this lock file, goes back to the Composer.JSON file and checks for whatever the most recent version is and it will update this file again with an exact version so long as the team lead only runs Composer.Update then there will be an issue where somebody is getting newer versions of code and it's breaking things because this person ran this command later than somebody else after the version came up you mentioned something about you could actually assign like an update and it would you explain the update thing so there's two different commands there's update and there's install so essentially install will always and Composer.Update will always install exactly what versions are defined here and Composer.Update will ignore the lock file and always go to the JSON file so if you have this range of versions available that are allowed to be downloaded and installed if the whole team ran Composer.Update depending on when you ran Composer.Update potentially different versions and then developers are working against different versions of the code which obviously never is well I got to present any way that they you want to have the same update to go to all developers in the team and you create like is there some way that you can be able to say create command that will update the lock file so the question was is there a way to send a notification or an update to the team let them know that there's been a change to the lock file so basically the process is that anytime you pull down new code you should probably go ahead and run Composer.Install that way the entire team is always getting latest so you can set a process where you tell your devs to do that every time if they forget then that could mess things up but a lot of times you can use tools like Git has post-receive hooks and things like that and you can use tools like Gulp and stuff to automate so that every time they pull down they don't have to run anything Gulp just sets up that post-receive hook and then when you do a pull in Git it automatically will run this behind the scenes and no one even has to push it so the vendor directory so the vendor directory is essentially where all of your packages go so when you do require dependency by default it will end up in this vendor directory that sounds like a bad thing at first but you also have to remember that Composer auto loaders means you don't have to know where exactly that code lives you just start using it so it can drop the code here and you can just code against it and not even worry about where it is but it will all live in here so if for some reason let's say you're doing a WordPress plugin and you have libraries and they need to go with the plugin into WordPress.org you can commit the entire vendor directory into your project and that code will ship but a lot of times you actually want to get ignore your vendor directory because the repository itself doesn't need to contain code that you're not actually going to directly change you want to change it on its original source if it's your code or if it's third party code you're not really going to change it so why do you need it in Persian so essentially the vendor directory is a black box where your code lives and you can just start loading against the known dependencies the only thing you do have to do is just make sure that the autoload file that gets created for you after every time you include a new dependency this file gets updated for you you just have to do a require whatever the path is vendor slash autoload.php and that basically for any package that has autoloading will make sure things work perfectly so how do we use Composer with WordPress so Composer again is a generic php tool so if you do general php work it is awesome but specifically when in the context of WordPress one of the use cases is you have a custom plugin or theme and you want to use dependency management to make sure that you don't have to write all the custom code that this other library provides you and again in this case you would actually commit that vendor directory where all that code lives so that it would actually be available for those that install the plugin or the theme the other use case is a client website or application so this is generally something that is professionally managed the client is hands off but when you do turn the project over you'll probably want to make sure that that vendor directory is there maybe in the repository if they use the repository or typically if it's you deploy it to the site you'll probably package it up in a way that they get the full code base so as far as WordPress goes the first thing you'll need to do is Composer require and WordPress is a dependency because you're creating WordPress site you need WordPress for to run or an application you need WordPress for it to run if you're doing a WordPress plugin or a theme then WordPress is assumed it's already running this wouldn't be a dependency so this is more for your custom site use case you do a require for this particular package John P. Block slash WordPress essentially this is a Composerified version of WordPress itself doesn't support Composer but John Block actually created a repository where he sucks in the most recent versions of WordPress and make sure that you can use it with Composerified I can post the link in Slack after but yes they will be so then the next thing you'll need to do is actually make sure you set up something called WPackages as a custom ComposerRepository source so essentially Composer uses packages.org by default for all the packages somebody created something called WPackages and basically what it is is they've taken all of the themes and all of the plugins that are available on the WordPress.org repository and they've made it available in a Composerified version or form so for example things like Yoast SEO you can actually just run Composer require WPackages-plugins slash WordPress SEO and you'll get the Yoast SEO plugin in your project and you can even do an at stable version and then anytime you run ComposerUpdate it'll go find the most recent version and install your project how frequently is that update and is it pretty close occasionally there'll be a little bit of lag between a new version coming out and it actually being here but for the most part it's not that long so it stays up to date pretty well the other thing you'll need is something called ComposerInstallers so you'll run ComposerRequire, ComposerInstallers and basically what this does is it's a tool that actually works with a number of different platforms WordPress just happens to be one of them and what it does is it will allow you to have, because of the way WordPress works if I do a ComposerRequire for say the Yoast SEO plugin if it goes in the vendor directory then you can actually activate that plugin in WordPress because it's in the wrong place so what this will do is it will actually allow you to define where plugins need to go where themes need to go and also where immune plugins must use plugins that need to go and basically after you've done all that you'll stop by your composer.json file and you'll define a few little things and as you can see what we're doing here is we're defining the WordPress install directory so we're going to use an alternate WordPress directory structure so things play nice with Composer and WordPress works the way it should so we're actually creating a special directory called WP where we want WordPress to live and then we're also referencing where exactly we want our plugins to go, where we want our themes to go and where we want our immune plugins to go so if we have a Composer package right, so think Yoast SEO if we want to install that as a package when we use W packages that particular packages has a type property which is defined as plugin or WordPress plugin actually and what we're doing here is we're saying anything with the type of WordPress plugin drop it in our plugins directory in a folder that's named after the so that properly sets up all your dependencies in the right place and anything that's not a WordPress plugin theme will go into the vendor directory so yeah so multi-sites work the same way, you can define where you want things to go and they'll go there so if for some reason you've gone in to your WP config file and said all of my plugins live in this other directory you would just update your Composer file to that location and now all your plugins are going there instead of the normal places they might have and could you define the location in the JSON file right? correct yeah that's actually what we're doing here so this JSON file lives in the root of our project and this is just the relative path from the root to where those things live so this is the alternate directory structure for those that might not be familiar essentially what we do so public HTML is just kind of like the web root and normally in a typical WordPress install you'll actually see WordPress in that Public HTML directory that's where your WP content, WP admin your WP config and all that stuff will live in this case what we're actually doing is we're saying WordPress is going to live all by itself in this WP directory and then WordPress by default will actually go up one level if it doesn't find a WP config file and look there to see if there's one so you can actually have your WP config file outside of that WP directory and you can set everything up there and so what we're doing and you don't actually see the WP config file in this particular setup at the moment but I think it's just because I failed to get in that screenshot but basically the vendor directory that's where all of your non WordPress libraries you might be using would end up and then again that content directory which we've called it content it could be WP content or my stuff or whatever you want to call it essentially we've referenced that as the content directory and we've defined that in our WP config file so that WordPress will now check here for anything that's a plugin or a theme must use plugin if you use that etc. that I like to do is make it easy to bootstrap new projects so you know running all those commands that you need to do to kind of get things set up to use the composer with WordPress takes a little bit of time and I like shaving things off my workload and saving myself as much time as possible so there is this command called composer create project where you can have a package of your custom creation or something somebody else has done and basically when you run this command it will download this particular package in this case it will need to be registered at packages.word and it will download it and actually run composer install against that package so whatever composer setup needs to happen for that it actually runs it everything that it just downloaded so to kind of give you an example I have something called WP skeleton and when you run composer create project WP scholar slash WP skeleton what it does is it has all of the WordPress configuration setup and it clones that down into whatever directory you happen to be in it removes version control but it keeps things like the getting file which are already setup for this particular configuration and it runs composer install which will get things like WordPress itself the composer installers and all the things that are needed for this to be ready to go for WordPress site so you can run that single command it will essentially set you up for a WordPress site using composer the directory structure will already be set up and all you have to do at that point is you can start you can navigate directly into that new directory you can run WP composer require and then any plugins or even things that you want to install and it will automatically check that WPackages repo because it's already setup for this thing that I created so you're basically ready to go if you run this one command to start using composer WordPress really quickly and really easily if you happen to be a little more advanced then you like to use something like say VVV for your local development created something called VVV Skeleton which is essentially the same thing except it also does your VVV project setup so you can run this single command it gets WordPress project setup ready to go create your VVV configuration files you can then run require for any plugins you might want reprovision your virtual machine and then you've got a working site you go to the domain and load it up and set up your database and whatnot so that is what I've got are there any questions so we have a question so when you do a composer install can you do that again or no you can run composer install as much as you want so let's say you just copy down a project somebody else and you run composer install it will it will fetch whatever is in that lock file so if you run it again it just double checks to make sure that you haven't deleted something out of your project and be that you've got all the same things that a lock file requires do we say the lock file would that be like the big difference that's like the big difference between the composer and the power correct, so just to repeat the lock file is the big difference between using tools like MPM or power add it exactly because they don't make any changes to it so if you've added stuff to what folder to one of the folders and here's an example in the WP Copy folder maybe this folder is managed by I run that I run the work in blue or what's it gonna be just to repeat the question is if I actually go in and change something in a directory that is managed by composer what would happen so if you let's say WordPress is a dependency and you've required via composer WordPress itself and you go in and you actually hack away at WordPress essentially what's happening is when you run composer install it's checking the composer.json file just to make sure that that file indicates that you're using that package at particular version and it usually uses get to kind of help with that so if you go in and make changes to within a file that is actually a dependency itself usually those things won't get changed you can go in and completely delete the WP directory where WordPress is and it will actually reinstall it if you run composer install and it happens to be missing so if you were let's say thinking maybe you got hacked and you just want to make sure that everything is the most recent and maybe you're using composer on the production side or whatever the case may be you could just delete it and then rerun composer install and then we just reinstall everything so but let's say if you are using composer with WordPress and so it's actually automatically installing plugins in the plugins directory but you have premium plugins which aren't composer-ified or whatever and so you're actually just dropping them in and committing them to repo any changes that are made there aren't going to be impacted by anything that you're composing. Is there a way to register packages that are locally held on the system like proprietary development that aren't registered out on packages or something like that? Correct so that's where let's say you have Bitbocket and you've got a repo there you can run composer init on that particular private repository and set up the package name and any meta information in there and then in the project where you want to include that repository you would run the command to essentially register that repository to get repository and then you would do a normal require for the name of the package that's defined in that remote composer config and it will work as if it were on packages You mentioned like that different WordPress directory setup do you experience any caches in terms of having things set up that way? Yeah so the question is are there any gotchas with having a directory structure for WordPress and so the gotcha is really makes it really easy to find plugins that are not properly coded because there are a lot of plugins that expect a very specific directory structure the one that everyone typically uses and when they're coded wrong and you move something around that plugin will break cycle crack and it's a real good indicator to me that that was not well coded and that I should just find another plugin or write one or at least go to the plugin offering like hey you're doing it wrong WordPress does have other ways that it works and you need to make sure that your code is compatible with these alternate structures but yeah it does happen and sometimes the reality is that you actually end up usually with better code How common do you find that? It's not terribly common and again that's kind of one of those things where not too many plugins necessarily you know usually I don't know it can happen relatively often but I'm very thinking about plugins so it really doesn't happen very much to me I guess I don't know so I guess your mileage may vary depending on what you use Any other questions? I was wondering about host hosting what hosts do you know that you suppose are on so so yeah so I guess one of the things that is notable is that different toasts, Pantheon actually it doesn't allow you to do it alternate directory structure but I still use Composer with it within WordPress I just do it a slightly different way so instead of the way their stuff works is that everything has to be in the repository for it to actually run on Pantheon but I'll still use Composer and I don't include WordPress and see WordPress is already set up on Pantheon so I just do the actual plugins themselves and map it within that directory structure and it works fine but yeah I think I think most other web hosts will allow you to do whatever you want but Pantheon has a really advanced file mapping and a bunch of different things that they do and they currently don't support alternate structures but I think they might be doing that somewhere if there's no other questions again if you think of one after the fact just hit me up on Slack or Twitter and I'll get back to you thanks