 Hi, gwaith. I'm Chris. I'm 28. I'm from Bournemouth. Google would make you think that Bournemouth looks like this. Most of the time, it actually looks like this. I help organise PHP Dorset and I'm also a member of my local WordPress user group. I work for a company called Three Sider Cube. We make apps, most famously, for the American Red Cross. Occasionally, we also need to make CMS websites. For this, we use WordPress. WordPress has a big focus on its users. It's packed full of features that make it easy to make a blog or website, sometimes even something bigger than a website. Its strength is that it's very portable and you can run it on almost any setup. It rarely bakes backwards compatibility. It covers a lot of different users' needs. In doing so, it ends up getting a lot of stick for not being easiest to maintain or maybe collaborate with multiple developers. However, it's easy to forget that it's not there to be my perfect developer framework. It's there for the user. It's all about them. That's why it's so ubiquitous. After all, if we look at the internet, 27% of it is running WordPress now. As PHP developers, we have some great tools that help us develop our applications. There's no reason why we can't use WordPress these tools with WordPress to make building and maintaining our apps easier, especially within a team. This talk is about how we bought our WordPress development in line with how we work with our other favourite frameworks. These are all suggestions, so they're not the only way you can do these things, but these are tried and tested and they work really well for me, so I'd like to share them with you. The most important tool I think that I use is version control. The most popular of which is Git. Git is vital because it helps to see who changed what and when. We can have multiple people working on files simultaneously. We can work in features in parallel and we can roll back to previous versions. All that's really important because ultimately it means we can go home on time. If you've not used Git with WordPress before, you could do a lot worse than just stick the whole thing in to Git. Let's take a look at our project here. This is a fresh WordPress install, show out the box, and here's Git, but of course it's a CMS, so it's not quite that simple. It's because of this. This is WordPress's file editor. It lets you edit things like CSS files and plug-in files. It means what's on the server isn't necessarily what's in our repo because our users can change our code base. That reduces how useful it is to have a repository. It's a really easy way to prevent this and it's by adding this line. This goes into WPconfig, which is WordPress's config file. It's a prime example of how WordPress lets you customise your experience with it. There's a ton of these settings and you'll see more as I go through this talk. This is another one, for example, which prevents automatic updates from running. Incidentally, if WordPress detects that you're using something like Git, it turns off automatic updates anyway, but I'd just like to be explicit and add this option. This is the file I've just edited. This is WPconfig and it's where WordPress keeps most of its settings. There's also some in the database. I can commit that change now and that's great. I've got all these files in here and the only files I actually want to edit are in this folder, the WP content folder. That's what I call my application. That's where the code that is going to be different for this WordPress site to other WordPress sites lives. Now, I don't want to touch any of these other files. It's really hard to see where my application code is in here for all the other files that are part of WordPress core, so I've gone and tidied this up a little bit. WordPress lets us move files and folders around. What I've done is I've created a folder called WordPress and I've moved all of the core files for WordPress into that folder. Now, WPconfig isn't a core file. It's created by the wizard and WordPress will look for that in the same folder as all the WordPress core files or actually in the folder above, so it's okay to stay there. But WordPress doesn't know where the core files have moved to. When index PHP gets hit, it will try to load in the WP head and it won't be able to find that file. I need to tell it where I've moved it to. So I need to make another change to WPconfig. This code already exists in that file. All I need to do is add WordPress to the end of it to tell it that I've moved these files. I also need to make a change to the database. So some config options are stored here and we've got site URL and home URL here. The problem with that is that these aren't very well named. I think they're quite confusing, especially where they have the same value by default. Essentially, site URL is where those core files live and I need to update that as well in the database. So where is our application code now? Well, if I go into WP content here, this is where we've got plugins and our themes. That's what our application is. And WordPress comes out the box with a ton of things like Hello Dolly is a sample plugin and it's got a load of themes of 20 appended to the start of it. So I could put my plugins and my themes in there, but I don't really want to mix my application code in with all of WordPress' stuff that it comes out the box with. So what I've done here is I've created a new folder. I've called that WP content, so I'm maintaining the naming structure that WordPress is used to, that I've got a WP content folder in the root of my project still. And I'm going to put my plugins, my themes, into here. So I need to tell WP config about this change too. So you see I've got advanced custom fields as an example of a plugin to debug bar and my own very awesome plugin there. And yes, so I just need to make a quick change to WP content. I just add these two lines and then it knows where to find this stuff. So now I have a clear separation between what's WordPress' code and what is my application code. And this is a massive improvement. And yes, I know what you're all thinking. All I've done is gone and moved the folder around. And also why did 2016 take all the good memes from us? And what does that have to do with version control? Well, now we have WordPress' code contained. We have the ability to do something that I feel the PHP community could maybe do a little less of and ignore WordPress. So here's a gitignore file and in there I've added the entire WordPress folder to that gitignore. Because ultimately I'm not going to be making any changes to any of those files. So I don't need to keep track of it in my version control. WordPress has its own version control system for that. So let's see what that looks like if I check it out from git. So I do a git clone and I get these files. But there's one missing, so WordPress is gone. Don't look too happy about that. We could work out that we need WordPress in here because we've got a WP content file. So we could just download WordPress and stick that in there. But what version of WordPress do we need? Is this a really old project? Is it going to work? The only thing we do know is that this project is dependent on WordPress. It's not going to work without it. Now if only we had a way to manage that as a dependency. What we do, and it's called Composer. So we have Composer in PHP and there's a misconception that it isn't compatible with WordPress's workflow. It is. It's just not as easy out the box as it would be with something like Laravel or Symphony because it doesn't have a Composer description file. Now there is an RFC out for it to add one. I'm not here to debate whether or not WordPress should have a Composer description file. The only thing I do know is that it hasn't happened for a while and it's probably not going to happen for a long time. But for us to be able to manage WordPress as a dependency, we need a Composer description file in WordPress. We need it to have one. We could make our own fork for each minor version of WordPress and store that in our own repository, but we need to update that every time there's a minor version. Thankfully, someone's already done this for us. This is a Composer package which is an automated fork of the WordPress core. It updates every 15 minutes and it's mirrored on packages and it has all the tags and all that sort of stuff. It's got 1 million in stores, so it's not just me that uses this. This is really popular now. Best of all, Composer will install those missing files to that WordPress folder that I'm missing. How's it do that? I need to explain a look about how Composer works. This is monologue, which is just a simple PHP library for logging. It's the most simple example I could think of. That has a type of library, so most Composer packages have this type of library. That's going to install to the vendor folder. This one has its own type of WordPress core, and that will install to the WordPress folder. It does that using something that's called a custom Composer plug-in, and it's written as part of this package. You can write your own. It's actually really cool. If you're interested in that sort of stuff, come find me in the social afterwards. Back to Composer. I'm going to initialize Composer here, and I'm going to require this package, and then I'm going to run Composer install. I get something like this in my Composer JSON file, and this is great because if I want to update WordPress now, all I need to do is run Composer update and my WordPress updates. That's added a Composer JSON file, and WordPress is back. Now we have a dependency manager. What else in here is a dependency? If we look in our content folder, we've got our plugins and our themes. I didn't write advanced custom fields, for example. That's a third-party plug-in, but these don't have Composer descriptions either. That's where WPackages comes in. This is a custom repository, like Packagist, but it's a mirror of WordPress' plug-in directory. These have their own types of WordPress plug-in and WordPress theme, and they're going to install to a folder called WPContent, which is in the root of the project, and you'll notice is what I called my new folder there. That's just going to install plugins and themes exactly where I want them to. It does that using something called Composer Installers, which basically helps Composer Install things into the right places for all of your favourite frameworks. It's not just WordPress that's worked with, Drupal, Joomla, lots of things. Because this isn't on regular Package, I can't use a Composer Require yet, so I've just typed this into Composer Jason myself. Tips on getting this right. If you go to the WordPress plug-in directory and you want to know the name of the package, it's the slug, essentially. To get the version number, go to the changelog, and you've got version numbers there. This is a good indication if you look through the changelog of whether the plugin is using semantic versioning or not, you should be able to tell what kind of plug-in it is. For themes, for example, they usually don't have any versioning, so you just have to use the desktop, the asterix. I've locked this to 4.4 advanced custom fields, so I've not put a tilde or a hat on the front of that because I don't necessarily trust this to use semantic versioning, but I know exactly what version I want this to be running on. If I did want to update advanced custom fields, I'd just change this number and then run Composer Update. I need to tell Composer where to find this package, so I need to add into my Composer file the repository of W packages, so then when I run Composer Install, it knows where to find this package. You can also do Dev packages, so now I've got that repository in there, I can run Composer Require again on the command line, and I've added the dev flag here because I want the debug bar, but I want to optionally choose whether I'm going to install that plug-in, I run Composer Require with the dev flag for my local development, so I've got that handy debug bar, but I don't want it on my production server, so I just run a normal Composer Install, and then I get just the ones which are in that required block. This is where Composer starts to become really powerful for managing our plug-ins for us. Now I have these advanced custom fields and the debug bar. They're managed by Composer, so I can ignore them for my version control. I don't need to keep these in my repository either. So I've just blank it, ignored all of the plug-ins folder here. The .git keep there just keeps the folder itself. So that handles those, but what about my awesome plug-in that I wrote myself? So there's a couple of options here. You can leave it in your repository. So it's part of my application, it's single use, so I'm not going to use this for any other website. A very bespoke plug-in here. So I've just not ignored it in the .git nor, a bit of a double negative there. So that's option one. Option two is that I can make it public, so I could submit it to WordPress's plug-in directory, but on the downside of that, it can take a while, especially if there's lots of plug-ins in the queue. You're really kind of at their whim as to when you're trying to ship things, that can take a while. It's also likely that you don't want this to be public code. So option three is if this is a plug-in that I want to use across multiple installs, and I want to be able to use Composer to pull in to my repository, what I can do is I can host the plug-in in a repository on GitHub. And that's the same for if you've got any private plug-ins that you've maybe paid for as well. They won't be on W packages, so you can use the same technique for this. So here's my plug-in in all its glory on GitHub. Note how very awesome it is. And this is good because I can tag versions of my plug-ins, and I can lock my different apps down to different versions. So to explain, if I've got version one, which was kind of awesome, and I put it onto site one, and I tagged that as version one, that's the first version, that's cool. I then make it a bit more awesome, and I get this version two, and I start using that on a second site, but maybe I've broken some backwards compatibility there, and I don't want to upgrade my first site. Well, because I've got that locked down to version one in Composer, it can just carry on using version one, and that way I don't have to maintain two different versions of the same code for the plug-in. It's all contained in the same repository, Git just takes care of that, I tag things, and then I can upgrade when I want. And by doing this, we also completely avoid the review queue, which is WordPress' own plug-in directory. So let's have a look at my plug-in a little bit closer. Here's my Composer JSON file, and in here I have just the standard stuff you need to describe to Composer what this package is. So I've got a name and I've got a description there, and the important bit here is that I've said that it's a WordPress plug-in, and I've required Composer Installers as part of this description to tell it that it's dependent on that, so that then Composer knows to just install this into the correct folder that I'm expecting it to. So now I'm back in my WordPress Composer file. I apologise if that's a bit of a jump. I've gone from the plugins composer.json, and now I'm back into my WordPress site, and this is there. So if my plug-in is public on that repository and it's mirrored on Packagist, then I can just use this straight away and that will just work. But it's likely that I'm going to have this as a private plug-in. It's not going to be mirrored on Packagist. So I need to add the repository to tell Composer where to find this plug-in, and I can literally just give it the GitHub URL and give it to type VCS, which is a version control system, and then I'll be able to use Composer to install this. The downside of doing this is being a private plug-in, you might have to play around with SSH keys so that your server that you're trying to run Composer to install has permission to check out from that repository. So it's not for everyone. But here we go. So all my plugins here are now managed dependencies. So what about my theme? Well, I only have one theme. It's very much part of this app because it's custom-designed for this app. I'm not going to be using it for a different website. So I want that in the repo. That's part of my repository, and that's fine. If I did use any third-party themes, then I could use Composer to install those, and then I can ignore them from my version control as well. And then if there's one in particular that I've written myself, I could not ignore that again. But to be honest, I've only got one theme most of the time, so I leave it in the repository. So a caveat of using Composer with WordPress in this way is that you can't just update things. What you can, your users can, they can go and click install or update that plug-in. But your repo will be out of date if they do. So you probably don't want them to. What I do is I make a new role for my clients. I'm the administrator, and I give them something just underneath that so they don't have permissions to install plugins and things like that. And there's great plugins out there that help you do that, so Members is an example, and you can use Composer to install it. So with Composer, we've defined versions for all of our dependencies. We've got less third-party code in our repository. On the downside, we now have greater reliance on third-party availability. So if a package disappears off WordPress's plug-in directory, for example, we've got a problem. We can't install our app again. But to be honest, we've probably got that problem anyway, even if we're not using Composer. So I don't see it as a big downside. Upload is one dependency that we can't manage with Composer. So I don't commit these. Again, I use getignore to just ignore that whole folder. And that's because I want to keep my repository small. But also, as soon as I've uploaded anything to my repository, my repository is out of date. Sorry, as soon as anyone uploads anything to WordPress, my repository is out of date. And uploaded files, they don't really need versioning. You just upload a new one every time you want to change the image. So I don't need Git to manage that for me. So I don't keep a copy in my repository. So that means that if my repository doesn't have any of my uploads in it, how am I keeping a backup of these? I personally use the S3 command line tool to back my plugins up to Amazon S3. And I run that on a cron task. It just runs nightly. And if you don't want to mess around with a command line, there's plugins you can use to do this for you. Humanmade have one. I've never used it myself personally, but I've heard it's very good. There are others available. And this one, for example, is available on packages, so I can just compose or require that as well. And you can start to see how using Composer can really start to speed up the installation of everything you need, all your dependencies. So if I've got uploads on my server and I've got them backed up to S3, what about when I'm working locally? If I check out my project from Git, I'm not going to have any of those uploads. Well, the simplest way, for me, is that I just run an R-sync command on the command line to pull down any files that I don't have from the production server. And I use the production server as king. That is my source of truth. And anything that gets changed in the database or upload-wise always happens on the production server, and then I just pull from it. You can use FTP if you don't want to use the command line to use the synchronised command in that. That works as well. With S3, there are other cloud storages available, by the way. This is just the one I use. We've got a smaller repository, and we're not keeping version control over our uploads. So we've got faster clone and deploy times as well, which is a nice win, especially if your images are rather large in your project. And we've got remote backups of our uploads. With databases, version control is tricky, so we could do something like add a MySQL dump to each commit. There's actually a plugin called Reviser that tries to do this, but I don't think it's needed. So WordPress has an excellent post revision feature. You can go back and look at different versions of the post you've made. That's all stored in the database anyway. So all we really need to do here is back the database up. And again, I use the S3 command line tool for that. And then when I'm working locally to get a copy of the database, I just do a MySQL dump on the server, copy that down, and then install that onto my machine. If you're using WPCLI, for example, there's some nice command line tools that will make that even easier for you. Or if you don't want to use the command line, you can use PHP MyAdmin or any FTP client to... Sorry, MySQL client to do that. There's a potential issue with this, though. Moving these databases around, I've got different settings that I need for different environments. So by environments, I mean I've got a production server and I've got a staging server, and then I've got my local machine, which I'm developing as well. And they're all going to have different settings. Some of these are stored in WPCON figures we saw earlier. A lot of them are stored in WPCOptions, which is in the database. And for every environment, these need to be different. So between my staging and my production site, site and home, for example, are going to be different. Now, if I'm syncing my production database over to my staging database to keep that up to date with the latest changes, I need to repeat this task every time. I need to go and edit these. And there is an admin screen for that. You can go to options.php in WPCAdmin and change some of these settings. But you'd have to do that every time you sync your database. So here's a better solution. So you can define some of these settings in WPConfig instead, so we can have it in our code. And if these are defined, then WordPress doesn't go to the database to look up these values. It just takes it straight out of this file. That has the added advantage as well, that if your users, for any reason, went and edited, say, the site URL in the database, it doesn't matter because it reads from the file instead, and they can't change that. So I've just moved the problem, really, from the database over to my code, because now I have to handle different versions of my code base for different environments. And this will mess up my version control if I'm having to constantly change this round or put comments in and things like that. Now, I could do something like this, so I could define an environment variable on my server. So that's the vhost in nginx. And then that exposes an environment variable to PHP that I could then switch on. And you can do things like check the IP address as well, but I don't find those particularly reliable ways of doing this. The environment variable is definitely the best way to go if you're going to do this. But there's lots of these settings. There's a whole heap of them, actually. They're all going to be different for the different environments that I need. On top of that, we also have the added problem that we've got this. So I've got my database credentials in the wp-config file, which I'm then going to commit to my repository. And if you take anything away from this talk, I want it to be this, you should never put your passwords in code that you commit to a repo. What you've got to think about is could your codebase be made open source at any moment? Or could you bring on a freelancer to help work on your project without having to give away all your secrets? Let's put it another way. If I go to github.com and I typed this into the search, am I going to find your password? And this is just an example I mocked up. But I guarantee if you go to github and you look for this, you will find people's passwords. So there's a PHP library for defining environment variables. It's called .end, and if you've used anything like lava, it will be familiar to you already. It has the added advantage that you can define environment variables without having to edit anything on your server. You can just do it in your code that you upload. And we can require this package with Composer. So Composer require, PHP.env. And then that will install to the vendor folder. So this isn't a WordPress plugin. This is just a standard PHP library. So it's going to go into the vendor folder. And to use .env, you need to create a .env file. It's a well-named plugin. Sorry, well-named package here. And inside that is literally just a key value pair of all the secrets that I need. Or anything that's going to be different for different environments. So this is just a standard PHP library. It can be different for different environments. Like my password, for example. So to get this to work, I need to autoload this class in to be able to use the class. So at the top of WP config, I just slap in the Composer's autoloader. And that means that I can start calling the .env library. And I call the static load function there. And I load the .env file. You can actually call these whatever you like. You can pass that in as a variable. Or use .env by default. And then I've got all my settings in here. And instead of defining the values in here, all I'm doing is referencing that environment variable. And you can do this a few ways. You've got $server, $env, or getenv, pick whichever. It doesn't matter. They all work. And another advantage with .env is that it gives you the ability to do this. So the required function is really nice in that you can tell it what you expect to be in your .env file. So if there's anything missing from that .env it will throw a .env exception. Which just makes it really easy to debug why your site's not working. Because you can see it exactly. It actually tells you the thing that you're missing. And I ignore it. Because I don't want to... The whole point of this was I'm keeping these passwords out of my repository. So I created a .env file locally. And then I also went and made one on my production server. And again on my staging server. And I did this manually. But I only needed to do it once. If I want to edit any of these files at these values it's really easy to just go in and change them. And if you're using provisioning scripts like Ansible or Puppet or Chef you can generate this file using variables from your vault. And I'll go into provisioning in a little bit. But for .env it's easy to locate and it's easy to update. We've got a a configuration for each environment. And it's not in source control. Which means we're ready for open source at any point. And it's really easy to store outside of your web route. So by default WordPress just installs to wherever you install it to. And all those files are web accessible. If you've got access to change the document on your server you can do something like this. So I've created a folder called web and I've made that my document route. And then I've moved all the web accessible files into that folder. So everything that's now at this level is not web accessible including my .env which is really important. But also my composer file and things like that is harder for someone to sniff exactly what configuration I'm using. Inside there I then have what I need to be web accessible. So to summarise we're only keeping what we need in our version control. We've got dependencies managed we've got backups of our uploads and our databases and we've got isolated configurations for all of our environment. And most of this applies even if you're just making a PHP project it's not even WordPress specific this is just good stuff to do. And you're probably asking yourself how am I going to remember all of this stuff? I can see some people at the front looking a bit like this. Well that's where Bedrock comes in. So Bedrock is a WordPress boilerplate that I use and it does everything I've just mentioned out of the box except the S3 backup stuff but as I say there are plugins that can do that for you. Now it does require some server configuration to get it to work mostly changing the document route. And that's something I don't always have the liberty of doing. So as a result I don't always use Bedrock. It depends on the server it depends on the project depends on how much access I've got to these changes. And that's the reason this talk isn't just here's what Bedrock does because I like to apply some of this stuff where I can. And when I have worked on projects that are quite locked down I've been able to use Composer and I've been able to get that split between my application code and what's WordPress but I haven't been able to do some of the .n stuff but that's why I've gone through the different steps of doing this. With Bedrock you've got a lot of clever people working on this stuff and they're keeping it up to date all the time and that's a really good reason to use it as well. If you do use Bedrock there's a couple of naming differences so WordPress here and WP content they rename these so they're actually called WP and app in Bedrock and I like the name app it's my application code it's quite a nice name for it. It does have a bit of config you need to if you're going to change the names of these and this just goes into the bottom of the Composer JSON file don't worry about trying to remember this Bedrock ships with this out the box. The downside we're having named that folder app is that it can cause some problems if you're using a plugin that has some hard coded links to WP content I mean it's probably not a good plugin if it is doing that but if you need that to work the easiest way to maintain everything working when using Bedrock is just to make a sim link from WP content and then everything will carry on working and the nice thing about the sim links is that they get stored in the repository so they'll work everywhere including in a virtual machine for example so when developing locally you'll likely want to use a virtual machine I use Vagrant to manage my virtual machines to explain what a virtual machine is quickly it's simply put it's a machine it's a virtual machine it's an emulated computer that runs from inside your actual computer so you can store software onto the virtual machine instead of onto your physical machine why do you need one well the problem comes is when I'm developing a site that has different software versions so I'm going to use PHP as an example of software, there's lots obviously your web server, Apache engine X things like that but as an example PHP 7.1 is on my computer and WordPress works there so then I deploy to my server and that's running on PHP 7.1 and everything just works fine I then go and work on a legacy project and that's running on a server that's running PHP 5.2 maybe I've used something like a return type or something because I'm used to writing PHP 7 now and then I get a fatal error exception if I really want to make sure that what I'm working on is going to work on the server then I'd have to uninstall PHP 7.1 and install PHP 5.2 on my computer to do that I don't want to uninstall and reinstall PHP all the time so this is a much better way of doing it so by using a virtual machine I've got a virtual machine that has PHP 7.1 and a virtual machine that has PHP 5.2 and all the other differences between the software configurations so they match what I've got on my remote server so when I'm developing locally I know that my site is going to work when I deploy it it also unclutters your machine so you don't have to have all that software directly on your machine and when you delete the virtual machine all that goes with it, that just disappears so that's great we've got our software versions contained so that's nice and it's as similar as possible to production that's really the key here is making sure that you know everything's going to work between your different environments on the downside the share file system runs slow and when I'm editing PHP files and then I go and refresh in my browser I've actually been too quick to go to the browser and I get an error where it's loaded half of the PHP file and then it just stops and it throws an error and says half completed words so it can be a little slow and it's not quite as cool or as hip as Docker but I don't know much about Docker at this point it's also very memory hungry so you'll probably be wondering if you've got say 10 or more virtual machines for 10 or more sites why you haven't got any RAM left but as I say I've having a virtual machine identical production is really why it's worth using and how do you ensure that they're similar so this is where provisioning comes in so I use Ansible the chef and puppet are also alternatives and to explain what Ansible does it's a script that I run that tells the server what to install on it so here I'm telling my virtual machine hey go install PHP 7.1 then I can run the same script for my production server as well and I go hey you have 7.1 and another one and another one it will do exactly the same thing every time I run it so this means I can provision service with a single command which is just a joy to watch if you've ever seen it you've got very descriptive configurations in Ansible that's why I like it the best out of the three I think it's just really clear and easy to see what it does id and potency so every time I run this I'm going to get the same which means I've got reproducible servers so if my server disappeared off the face of the earth one day I can get my server back in less than an hour because I can just run the script against it to build a whole new server and then I can get my backups and my uploads out of S3 and deploy my code from my git repository and I'm ready to go again now originally I wrote my own Ansible scripts to manage my WordPress installs but it was a lot of work to keep that up to date and that's where Trellis came in so Trellis is another project by the same people who run Bedrock and it comes with a vagrant file as well as Ansible scripts so you've got your whole developer environment there for you and it has multi-site which is cool and it's got WPCLI out the box it's got a lot of nice sugar in there and it's got deploy scripts that have build hooks which are really nice for your gulps and your grunts and things like that I'm not really that front-end-y but front-end developers love that and it's got an active open-source community again on the downside it usually does more than you need so it's like WordPress itself it's trying to cater for a whole range of use cases so you will find that those Bavarian scripts are putting a lot of tools on to your server that maybe you don't need and it's really fiddly to update so is Bedrock and this is where I don't like them as much because I found the best way to update them is to do this which if you get through strong you might be able to do my head around it I had to add an upstream of Trellis the Git repository for Trellis so that gives me an upstream and then I can fetch from from the master I can fetch the latest code from there and then I do this weird sort of Git merge thing it seems to work but the problem with doing this is if you're your Trellis install you've customised it because you wanted to do provision some more extra things or change the way it works for quite a customised install it means when you then get the latest code from Trellis you're going to get merge conflicts things aren't going to work out the box and you have to go and sort those out so Trellis is great for generic apps if you're just running a simple WordPress blog or something it's great to just use to to get yourself set up with your own server provisioning as I say, if a highly customised build you might want to start from scratch and write your own Ansible and there's Ansible Galaxy which is a bit like Composer in that there's lots of pre-written scripts for things like EngineX or PHP that you can pull in and put together whether you should use Trellis or not I'm on the fence pun intended my last section here is autoloading so we've got an autoloader that's already in there and that gives us a lot for free because it means we can use anything on packages now or anything that isn't for example we can use Twig Twig is my absolute favourite thing to use with WordPress it makes templating just a joy and there's a plugin called Timber that abstracts some of the loop and stuff away from WordPress that I don't quite understand which is nice because I don't need to understand it it's abstracted for me and I pull it in with Composer and I just use it Guzzle for HTTP requests again another library I use a lot when I'm interfacing with APIs and things like that Monologue you've finally got a missing PSR3 logger in WordPress Sentries great for logging these are just all packages that I've used before whoops if you want nice error handling PHP unit for testing any of the symphony components you can start using IC now we can start using our CMS like we use all of our other frameworks so whilst we're working with WordPress we start to feel like modern PHP developers once again so I've been Chris Sherry you can tweet me at tweeting Sherry or you can find me on the PHP Dorset Slack channel thank you so much for listening I hope this talk is really helpful and please let me know if you have any questions do we have any questions? Hi I'm Rob I'm 32 PHP developer and somehow I've found myself running a WordPress team I feel your pain This was about nine months ago but I saw one of your earlier talks and I owe you a big thank you because we've basically implemented everything that you've done and I cannot thank you enough I'd have thrown myself out of a window if it wasn't for what you've done there and it's nice to see the update you've done some more work since I saw the original talk yeah there were a few mistakes so and I would anyone who's not doing this with WordPress should be doing exactly this this is brilliant and also currently looking for more developers for my team so if any of you want a job and want to work like this with WordPress rather than old WordPress come and talk to me but I do have a question which I think you touched on the end because the point we've got to is we've got to that point roughly I think we're just slightly behind where you are like we're using vagran we use scotch box we're pulling in things like eloquent now so we can play with databases a bit better but the the thing about twig we've hit a bit of a brick wall with the themes because the themes in WordPress they don't follow separation of concerns they've got mixed business logic and view could you tell me a bit more and everyone else a bit more about how you've used twig and how you've implemented twig to achieve maybe more of a separation of concerns have you used the Timber Starter theme at all? no so if you go on github there is a Timber Starter theme which gives you twig templates to get you started basically they're just really bare they just do things like loop over posts and things like that it's a really good starting place to start off with and it's got the controllers so like page.php and single.php archive.php and interfaces with twig really nicely there so that's a good place to start there's also a project called Lumberjack which Adam's going to smile at me for it's a project by his company which takes it a step further and they've taken what the Timber Starter theme does and they've kind of boosted it with some more stuff that just works really nicely out the box so I recommend checking that one out as well any more questions? I should just want to thank you for your kind words as well that's what makes putting all the hard work and prep into making these talks worthwhile it's amazing to hear thank you just a small question do you disable auto update for your WordPress site? Do you allow your users or sub admins to update WordPress itself? So for my professional projects for what I do at work we update them ourselves we don't give the users any access to do that sort of updating and that's because when there's a new version of WordPress out instead of just trusting it to work which most of the time it does but there's always a case that it might not is we can update locally we can test it locally then we can deploy it to that update to our staging server and we can test it there and then when we're finally happy that it hasn't broken anything and all our tests pass as well if we've got any tests we then merge it into master and then we deploy it and it's very controlled in that way that said I have a couple of personal projects which I maybe don't keep quite as much of an eye on or it's they're not as business critical as what I do for work so there they get tiny amount of hits compared to the sites I do for work and there I do find that my clients or I say clients my friends and family who I've made these websites for they get annoyed by seeing that WordPress is slightly out of date and they'll they want to click that button to update it and I do let them do that and then I just go in and I pull the files down from the production site and I see the diff of what's changed which is usually just that WordPress is updated I update WordPress on Composer make sure there's no files different there and then I commit that so I've got the latest version of that there was something else I was going to say on that point but I've forgotten it Thank you so projects you have dependencies plugins and stuff that you bring in how do you manage those ones that are core can't be turned off you've got some plugins like Google Analytics which you only want on production but there's like 8 advanced custom fields how do you handle that to make sure they can't get turned off I'm just going to go back to the point I've remembered that I was going to make which is if you use Bedrock I'm not sure exactly where it does it but it will basically hide the WordPress needs to update the button from the users so they don't see that WordPress is outdated which is quite nice because then you don't get those calls of people saying oh my WordPress is outdated and obviously if you follow WordPress enough you'll be subscribed to some sort of email chain or something like that where you know when WordPress has been updated for your question Adam with must use plugins so Bedrock has a must use plugin of its own which is an auto loading plugin which will the thing with must use plugins is if you want to use them they're basically just single PHP files you can't have a whole folder in there and what Bedrock has is this own must use plugin which will effectively allow you to treat normal plugins which are in folders like must use plugins and they actually will then appear as must use plugins if I just jump out of here and I go and find a slide for a second to bear with me this one so in here if you want a a must use plugin what you can do is you can add an installer path that is Web app MU plugins and then the name of the folder and then in the section at the end there is an array there that will take it says type of WordPress plugin you can also do type MU plugins because there are some MU plugins that you can get off the WordPress plugin directory but you can also just define the name of packages you want in there so I could do type WordPress plugin, comma and then Advanced Custom Fields for example and I can put that in the MU plugin bit of this which means that it will then install it like an MU plugin but it's actually a plugin it's kind of a little hack around WordPress but it means that they can't be turned off ultimately though I don't think you should be giving your users the ability to turn off plugins and things like that another solution I've done which is a little bit simpler is I wrote a little plugin as an MU plugin so just a single file PHP plugin which literally just goes on and it activates all the plugins so as soon as WordPress runs it just activates all the plugins so I can't actually turn any of them off that was nice for a project that I always wanted all of the plugins on if that answers your question