 Felly, yn cael gwelio'n gyllideb am ddiolch yn rhan o'r ddaf. Mae'r lego eich bod nhw'n gweld bod y byddwn yn dechrau. Yn cael hynod o'r llego i ddweud, felly mae'n gofio'n i'w gweithio. Felly, mae'n... Felly, mae'n gweithio'n gweithio. Felly, mae'n gweithio'n gweithio'n gweithio'n gweithio. Mae'n gweithio'n gweithio'n gweithio'n gweithio'n gweithio. felly rwy'n mynd i wnaeth ymddangos yma. Tynna'n meddwl yn fwy fx Battery, Sysad Menyn, Traepler leaders i'w dweud o drwng. Rwy'n meddwl bod arno iechyd yn ylam gwybod yn Manchester o'r Remed Klar a os oedd a gweledol Rydydd yma ar ei wneud yn ymddangos hwnnw, a oedd oedd yn bija eu hunain yma ar y Gymraethol. Byddai ydych chi'n gweithio ei rôl sydd yn iawn, efallai gweithio'r cyffredin wywiau y teimlo. Ac mae'n meddwl ar yw sydd ym Mhwynt iawn, mae gwychio eu cyffredin i'r cyffredin yn ni. A byddai ymddangos ni hynny, oedd y gwestiwch os yw i'n meddwl o gyfrifiadu gyfer Gweithio. Ymddwn ni wedi bod yw'r gweithio y ddechrau? Rwy'n rwy'n gweithio ar y cyfnodau Gweithio. Rwy'n gweithio ar y cyfnodau Gweithio, 8 oed yn y ffodol yma, a 6 oed yn gweithio'r cyfnodau Gweithio fo, 4 oed yn gwneud, a rwy'n gweithio'r cyfnodau Gweithio, a'r cyfnodau Gweithio ar y cyfnodau Gweithio, Felly, mae'n gwneud bod ychydig i'w'r cymdeithasau. A wedi cael y myneddol arall y parwyr yma, mae'r adonau yma yn adrodd i'r adrodd i ymddangos, mae'n adrodd i'n adrodd i'r cyfnod i ymddangos i'r llwyddoedd yma, a'r adrodd i'r adrodd i'r adrodd i'r adrodd i ymddangos, mae'n cyrchaf arall ymddangos, i gael i ymddangos sy'n edrych. Mae rydw imbryd gweld ei nid yn cael meddwl, fel han Llywodraeth a Llywodraeth yn gyfnod o grannu â'i lleoliau. Felly mae eisiau ein rydw i yn cael meddwl ei wneud i chi helpu a rwy'n meddwl ei wneud i chi hefyd. Yr rydw i'n mynd â'n gwneud i gyfrifeddaeth.Teimlool, mae'n holl gwych ddechrau ar ddigon. Felly mae'n meddwl i chi ar ddigon, mae'n roedd yn bryd yn cael meddwl i chi hefyd, ac mae'n fydda Lywodraeth yn datblygu i'r rhan. ond we have a couple that are still learning after several months of trying to get rid of all the problems. So this talk is really built from born improvements of frustration really, seeing all these problems coming in and thinking right well, let's look at solving them. It sort of stems from what I think is the ability for people to sit down and get going on Drupal sites, which is great. Drupal is a tool like any other. It can be used well and it can be used badly. Actually in the PHP, this is sync, which is a good thing about PHP, it's easy to learn. The bad thing is that it's easy to learn. So there's no barrier to adoption really, which means you can get up and run it quickly. But there's no barrier to making bad decisions and creating things that are un-maintainable. I think it has been a bit surreal, one of those things. I said that. I was really going to title this talk Drupal the right way, but I still thought it was a bad title. So these are the main points I think that are a problem in Drupal. So some of the file architecture stuff, what you should be doing in your custom code, is configuring Drupal and some country modules to help you anyway. So a Drupal file structure, what we do access, and I think lots of other Drupal things adopt this, is use this structure. So we've got the sites folder and the all folder, and then inside modules we split up into country and custom, and all our custom code goes into custom, which makes it really easy to see what the custom code is doing. It also helps to analyse that code much easier and figuring out what you're doing much easier. Contrary to that is having a folder list with hundreds of modules in it, and then trying to find the one module that you know is custom and differentiating that between a country module. Believe me, going through each individual info file is not a present experience. So, again, we also use this sites default file, so we never change that directory structure, it keeps things nice and consistent between dev and staging and production. That brings us up into multi-site setups. So in Drupal it's perfectly possible to do this kind of thing, where you've got sites and then the domain name and a folder structure. So you can put your files order in there, you can put modules inside your individual sites files, and even individual settings files. It's a nice idea, but in practice I found it just creates this unmentainable mess. The main problem is updates. So if you have a module that's run across all the sites, for example views, if you update that module and you're running a five-site setup, and one of the sites doesn't take that module update correctly, then unpicking that can be out of the work, and it's also not easy to test all this integration locally, so doing this online is not such an experience. So we tend to avoid this. If you see a site setup like this, we'll start migrating away from it, which is possible it just needs a bit of the database work, because lots of file paths will be set like that. So themes, I always see lots of logic in themes, even like database calls and things. If you think of a theme layer in terms of like MVC, so if you're familiar with that model, which is Model View Controller, model would be your entity or your node or whatever, view is the theme and the controller is what many hook or the group called grouping engine in Drupalight. Drupalight actually forces you to stop using logic in your templates, so the tweak templating engine will force you to step backwards and so you need to use preprocess hooks to get all the right data structures in place before it goes into your theme layer. This is a sort of problem as well in themes, or even modules themselves. So node ID 1234, what happens if you delete that node? Oops. If you've got block IDs hardcoded in your custom code or you've got template files that are hardcoded with block IDs, it tends to be a bit difficult to migrate them into new nodes and things. So if you actually have to use specific values like you've got a very specific task you wouldn't do, then try to use configuration options, like the variable set and variable get things. Really easy to do, you can even just dump them in your settings file and it will carry through there. But it means you don't have to hardcode things if you don't have to. Also the problem here is let's say you pull the site down from production and you're working on it locally. By the time you move that code back into production again, those IDs are going to have changed because clients add new nodes, they add new text on new terms, in which case as you're migrating into production, you need to migrate all your IDs across as well, which can be a pain, believe me. A module file structure, I actually have JP Stacey's in the room because this blog post link at the bottom is actually really, really good. If you're thinking about how a module itself is put together, most menu Drupal hooks come with a file prompt in Drupal 7. It makes it easy to split things into different sections. In your hook menu, you can say, right, well, my admin page is going to admin.inc and that kind of stuff. JP Stacey's blog is really good to explaining how to get that involved in your module development. Name spaces are also important. So just to avoid function classes really, Drupal 8 solves this by using PSI4 and custom classes in the namespaces in terms of PHP namespaces. It's still important to try and name things correctly. I've come across modules that have little or no documentation to them. So in for files like this, it doesn't tell me what module does. If I'm looking at the module screen, there's a big list of modules. I can tell it does tooltips because that's written in the module title. I have to say it again. But it's more than that. It's more sort of, add a readme file, add some instructions on how to get it installed. Install.txt is also useful. If it's on drupal.org, update the module page so you've got something there you can read as a resource. If it's not intuitive how you set the module up, then you'll put that in a documentation. So changeload.txt, so if you go to a Drupal site and type in changeload.txt, you'll sometimes find that it tells you the exact version of Drupal that's been running. It's not necessarily a bad thing, but in my opinion it gives you a little bit too much information about what's going on inside the system. The best way to get rid of these is restrict them by a web server configs. You can remove them by the hacked module, which checks to see if there's any code changes inside Drupal. It complains about that. That's one way to do it. Alternatively, you can just delete them during your deployment processes. I'll come to an example of that later, actually. So custom code to understanding how Drupal is put together and understanding how it can be overwritten is really important, so understanding the tool itself is definitely useful. I do see a lot of people rewriting things, so I've seen the book module being rewritten from scratch. Why not use the one that's in core? Cache modules being rewritten, solar modules being entirely custom-built from scratch. If the control module is out there and it's been used, great, use it, but then understand how you can override those currently if you have to do something really custom. That means it. I'm a big believer in reinventing the wheel often. Rebuilding things, finding different approaches, but it should probably be on your own time, rather than client-paid work to do something that shouldn't necessarily have to be done. It's one to coding itself then. So don't hack core. Surprisingly, I do see it quite a lot, even if it's just like little changes here and there, but it's definitely happening. There are a million good reasons not to do this. It surprises me every time I see it, but that doesn't just mean Drupal core. That's also contrary modules, so I'll see views being hacked in weird ways. So there's an argument that you say, like, if the module's broken and there's a patch available on the internet, on the Drupal issue queues, you can patch it. I see that it's sort of a last resort approach. But if you're going to have to do that, then document the changes somewhere, even if it's just like a patches folder that you drop all the patch files in, so you can see and review them. But just basically do it the right way. So learn about hooks, learn about child themes, learn about overrides. It's all important in allowing you to update and maintain your sites. Version control is good. So if anyone here is not using version control, you can get started really quickly. Get's really good at getting started straight away. You don't need to use get hope or a bit bucket straight away. You can create a local get repo and then push it up when you're ready. But just understand that having that backup in place is really useful. There is some arguments around commit messages and things, so if you're going to write what you've done, you should probably give an indication of what you've changed and why you've changed it. So when you're reviewing the patches later or the commits later, you can see what you've done. So it's going on from that then. So we've got version control branches. So get branching is quite cheap, so you can branch off the code and start working on your own thing. You can use a get flow or a variant. We tend to use the approach of an access where the master branch is basically a copy of the live site. So we only actually write to the master branch when we're ready to deploy and then it gets deployed. So if there's any indiscrepancy, then we know someone's not done the job properly, which doesn't happen much. So what we do is then branch off into a dev branch and work on that, and that becomes the updated copy. Then we're already moving back into the master branch. If it gets more complicated, so there's lots of features going on, we'll do get flow, which is sort of a branch for each feature you need to implement. But it's not necessary. It's probably good for big teams and big agencies. So I've described, obviously described working here, your commit missions have said that. Don't add databases to your get repo. It doesn't really help, especially when your database is, you know, the problem there is that your databases, as soon as a client changes anything, it effectively negates the need for a database because it isn't much anything that's on the site. You can, there's arguments that you can create like a staging database that looks like the live site, but you should be reproducing the site through things that features, you know, sort of conflict changes rather than a sort of blank database. Surprisingly enough, I actually saw this recently of someone adding the user files directory to the get repo, which meant that every time I had to do a deploy, I had to do this complicated, juggling around of the user files to try and, because effectively, they are then a get controlled resource. So every time the user uploaded a file, it saw that was a change, which made merge conflicts quite interesting. So we've had to re-engineer that. Settings.php is debatable. There are config stuff you can put in your settings file. Things like varnish settings and cache settings can go in there. Probably a good idea to do that so that you're replicating the live environment, but just try not to put in database passwords and user names. This block at the bottom is what we use at Access, so we include that in our settings file, and then we have a local settings file that overrides database parameters. This code actually exists in Drupal 8 now, so that's the standard for Drupal 8 as well. So using ID, maybe, moving up, I think it helps me in my day-to-day work, not just in terms of syntax highlighting, but sort of code navigation, debugging, auto-complete, auto-formatting. Just sort of telling me, like showing me where the problems are around the code as I'm writing it. So it's better to detect the problems before we actually commit them into the system. What ID you use is up to you. I don't dictate to my team what ID you have to use, but NotePad isn't enough for TextMate. Not TextMate, the other one. It comes with Mac. So I use PHP Storm, but MetBeans eclipse easily as capable tools. It's basically the code navigation and debugging tools that I enjoy in PHP Storm. The environment you use can have an impact on how you build sites. So the idea is to replicate your production environment as close as possible when doing work on local. It basically stops stupid errors coming in. So that can be just the path that the site sat on, but it can be windows versus Linux, file endings, that kind of stuff. Mump-wump solutions don't really cut it, in my opinion. Shame it's plugged for favourite boxes in Vlad here, but the idea is that if you're going to be working, you're going to be launching a site on a Linux environment, you have to be sure that it will work, you don't want to get to the go live and find out that there's loads of problems with it. Also think about your PHP settings. So obviously you need to make sure that the file upload limits are the same as you would on the live site. That way when you're using the site, you can adapt to problems quite quickly. Come onto PHP itself then. So obviously syntax errors should never make into production, but that includes notices and warnings. If you understand how Drupal 7 at least will, how it executes an error, it'll go through the code, get to a certain point. If it finds that it can't find an index of an array, it'll jump off to this thing called Drupal log error, write something into the database, which is the watchdog table. Come back to where it was originally and then continue the code. That's fine if you've got one or two errors on the site on a page, but if you're looping through things, you'll find that you've got watchdog errors coming out, out your ears, and it slows down the site basically. If you're writing to a database over and over again in a page load, that's going to slow the site down. You tend to want to avoid that sort of stuff. Don't just use the At symbol to suppress warnings. There's actually performance implications around that. Try and catch blocks are useful, especially with things like saving entities. You can catch the errors as they happen and try to adapt to them. But don't forget about the actual error output in Drupal, except that your error is to be only visible by the admins. The error log gets truncated after a certain amount of time. Just make sure it's long enough for you to go back a few days and make sure that things are good. Coding standards. It's good to pick a coding standard and stick to it. It just makes the code a little bit more readable, in my opinion. Some people think it doesn't, but the coding standard is basically... It can be simple as a number of spaces and codes, so if you've got an if statement, it's if, space, and the bracket. It might seem like a trivial thing, but if everybody in your team is writing code with the same standard, it just makes portability much easier. We actually have a continuous integration environment called Jenkins. Quite a popular system at Access. So it ought to check the code in the dev branch as we're doing the work. We'll check for things like syntax errors as a default, but it also goes through and checks for coding standards just to make sure there's no glaringly obvious errors. The code module has everything you need to look at coding standards inside your site. So let's look. I don't want to get too blocked down in how to write code, because that's not really what this talks about, but I just wanted to note on cyclomatic complexity, which is sort of an easy way to understand how code is executed. So basically, it's the number of paths of execution through a code log. For example, this one here, the if statement, has a cyclomatic complexity ratio too, because it can go either to do something or do something else fairly straightforward. Anything above 10 makes life difficult for you, because it makes the code really complicated, trying to figure out all the different paths that the execution can go through the code. So basically, high number is bad. Nice and easy metric there. The way you set your error bars is up to you, using a tool PHP MD or PHP Mestetect will easily show you where your problems lie. PHP Mestetect actually will show you a few other things as well. It will highlight any unused variables, so if you create a variable and then never use it, it will show you that in your outputs. It can tell you about excessive function lengths. So if you've got a function that's hundreds of pages long, that's obviously unmaintainable, so it will advise that you should be refactoring that. Essentially, when writing code, you should think about the next person to write it, even if that's yourself, because I know that I'll write some code, and six months later I've got no idea what I've written before. But when writing complicated code, there's basically one rule I live by. There's always code as if the person that ends up maintaining your code is a violent psychopath who knows where you live. That keeps you in check, I think. Even if that's yourself, because if you know you're going to be writing code in six months' time, a little bit of code etiquette, I suppose, helps you sort of plan for the future. So if you're writing comments and nice verbose variable names, it makes the code a little bit easier to understand when you next look at it. A little note on Drupal tests. So since Drupal 7 has a simple test bundled in with it, Drupal 8 uses a combination of simple tests and PHP unit, but the idea is that with PHP unit you're testing the code itself, whereas with simple tests you're testing the entire application. So every time you run a simple test, it installs Drupal as a base value. It can make writing the test a little bit complicated because you're starting off a Drupal site with nothing in it. You just need to make sure all your taxonomy terms or your users or your roles are in place before you start, which can take some time to get that set up. Once you have it in there, it makes writing more tests much easier and it makes refactoring things a lot easier as well. If you know you're going to change a load of code in a module, writing a test to make sure that the known output before and after are the same is all that's always useful. A slight note of configuration. So this is sort of a bug there for me is the idea of content types. So a content type for me is not a template type. It's a sort of functional thing that contains data. So I'll come to a site and I'll see this sort of thing where they've got press release, news article, and a front page news article, which essentially have a title on a body and nothing else. Why are there separate content types? I don't know. But I'll see this quite a lot and it's not just one or two. It'll be proliferated. So I'll see multiple content types that essentially have the same fields in them, but in a slightly different order where they're doing slightly different things. At the end of the day, they're just being printed out into different lists, into different views. In my opinion, that makes things a lot more complicated. So you should think about creating functional content types. So if you've got a news article, just use a news content type and then use taxonomy terms or just fields to sort of segment them into different places. So CSS JavaScript navigation. Amazingly, I see this turned off all the time for some reason. So what this does, if you don't already know, is it takes your styles and your scripts on your sites and it compresses them down to one or two files. Which is great if you've got running a lot of modules. If you're running views and all the other modules associated with that, you can look at the page itself and you can see about 15 or so JavaScript files. You turn on the CSS JavaScript aggregation and they get reduced down to a couple of files, which makes sure it has loads of really good benefits. My only advice here is turn it on before you go live. If you turn it on production and it somehow breaks because there's some weirdities in the aggregation going on, that's sort of embarrassment really. So just turn it on in preparation for go live. Just a little note on when you're editing content. So I see this quite a lot where I'll go to a node, I'll click Edit and there'll be 50-odd fields all on a big list with no sort of differentiation between what they're for and what they're doing that's just a big list of fields. A content type can be quite complicated. If you look at an event, you've got the venue and you've got the times and all sorts of stuff. If you use the field group module, you can split those into sections which makes editing content a lot easier, which you also try to avoid using a limited cardinality where you just add another one, add another one, add another one, mainly because that just pushes the length of the page up. We always think about the interaction of the users with the site. Drupal has a sort of a bandwidth reputation of being unusable and I think that's sort of where this comes from. A couple of things to watch out for as well. If you're making a gallery, my advice is to create a gallery content type and an image content type and then link the two together rather than allow users to add multiple images in a field inside a gallery content type. Mainly because saving that page can be quite complicated. I have experienced just recently actually where I had to increase the PHP file upload limit to about 200 megs just so we could save a single page, which is insane. That should never be that high. Permissions. Drupal generally has a bad rap with usability. So what we tend to do is give people the minimum they need to do their jobs which makes the user interface and what they're seeing in front of them a lot easier which is especially important for new users because introduce to a new system if you're presented with the views UI system. I don't know what we would do with that really. So try to hide a lot of the admin stuff away from people. But also count that, don't have too many super-usic accounts. Drupal is actually quite bad at logging what people are doing so if they're deleting nodes or deleting users it creates an audit nightmare because you can't see what people are doing. It's just sort of restrict people down to what they have to do. Peachby filter. Do I need to say why this is bad? I do see this turned on every now and then. Trying to unpick a view that's got a Peachby filter code in it can be fairly complicated until you know which bit of the views UI you need to click on to find out the right bit of code that's been executed at that point. Basically, if you need to override anything in Drupal you do it the right way, use hooks, use preprocess hooks. Do it as it should be done. Renning cron. So in Drupal 6 there's a module called poor man's cron. That was sort of ported into Drupal 7 so you can get your users to run cron. I would suggest you don't do that, especially on big sites because every now and then a user will get a 5 seconds, 15 second page load, not particularly brilliant and there's no need for it really when you can run it behind the scenes. We use this module called Elijah cron which helps split the cron into separate bits. So if you've got, for example, caching you can set the cache to be cleared every hour and the XML site map, for example, to be recreated every day. There's no need to recreate it every time the cron runs or things like that. Or you can check that it's even viable every cron run. So this is a graph, this is time of execution before and after I turn on the Elijah cron on a site and just shows you how much of an impact it has on what we're running. Updates. So obviously when you're updating a site you throw your modules in there but that's not the end of the story. It's essential that you run this update.php or as an alternative update db. If you don't do that you can need problems. So let's say, for example, that you've got an update for a module and that adds another column to a database table. Not necessarily a problem but if you start, if that module then relies on that column being present and you don't run this step then you're going to lead into areas and things, weird things going on on the site. So this is one of the things we always check for when we're doing an audit of a rescue job and it's always, always, always there. So it's probably why it's a rescue job is because of these problems basically. Sort of a little thing really is if you turn off a module and install it, especially if it's not needed, this is another screenshot of a rescue site. This was about 50 modules long. So it obviously installed the module, had a play, turned it off and just left it. Unfortunately what that does is leaves a load of tables, a load of variables lying around the database that aren't really needed. Not necessarily a problem but I don't need to be there. So the only install hooks will delete the tables and get rid of all the old stuff that isn't needed. So just before we finish, a few control modules that are useful. Or need pointing out. It's over with other views. It's now in triple eight. But I do see them being used in weird ways. So I'll see. Instead of using the views arguments to make a list of news items with different taxonomy terms, they'll create a new view for every taxonomy term changed. Which means in your admin interface you've got hundreds of views listed out in a big row. Not particularly brilliant to administer, but it helps you if you understand how views works and use the right context filters and things to produce the right content. Remember also about views caching. You can cache views, but be careful about caching. If you've got a view, for example, that produces user content, so content delivered for that user, and on global caching, then the first person that sees that view will be rendered for that user. And the next person that sees that view will be rendered for the original user. That was a complicated problem that we found recently. But basically people were getting access to night pages because they were trying to go into the wrong user account page. Not a particularly huge issue, but fairly easy to solve. Also views is quite powerful, but remember there's a right and a wrong way to override it. The wrong way can easily cause errors in security holes and things. Views is basically a portal into your database. So if you don't escape things properly or create a view that's quite fragile, then the second you change anything on the site, that's going to break. It's not going to be happy. Path Auto. Amazingly, I've still seen Node 123 with paths out on the internet. Path Auto is really used to use, install it and it will take the title of your node and make it as the URL, which means you get nice, friendly URL paths instead of just Node 123. Context. So this is sort of a module that reacts to different components based on paths and views and taxonomy terms and stuff. But in my opinion it's a much better, a much more finessed controlling of the block placement in Drupal 7. For example, if you put in Drupal 7 in a block interface, if you put a block in a region that it's there for everyone, you can ever change it to a different region with context. It will only appear in that region if the active context is present and you can also change it into different regions as well. The good thing about context as well is that it's exportable. So you can set up all your block placements and export them as code into things like features, which I'm going to come onto. But it basically means you can recreate the site again on your dev environment without too much trouble. Advanced aggregation. So the CSS and JavaScript aggregation, this is another layer, isn't necessarily plug-and-play after a permit, but it can be useful in reducing the size of your CSS even more than it previously was. Also g-sits the code to make it easier to transport. UI modules. So lots of modules come with these UI modules. No need to have them on really, especially in production. I mean, I said earlier that the UI system is quite complicated for any user, so you can just hide that away from them. I don't need to say that. Develop. Lovely module. Really good in development when you're producing a site and writing code. Why would you leave it running in production? I don't know. It has no added benefit that I can see. Also DPM. DPM does a Dupal print message with a print R inside it, so it gives you a nice interface. Our Jenkins code analysis tool actually scans for DPMs in the codebase and will fail the build if it finds any. Because basically if you have those in your code you can turn develop in your site or break in interesting ways. Stagefile proxy is a nice way of working locally without having to download the entire user file structure. Especially if the user file structure is 80, 90 gigs, there's no point in waiting all afternoon for that to download. You can just tell them in this module and you start downloading the files as and when they're needed. Obviously no need to have this on in production, so turn it off when you deploy. Finally, features. Lots of different things can be packaged into features. I won't go too much into the ins and outs of how you do that, but it's a good way of packaging things together. The idea is to package like things together. For example, if you've got an event, content type, then you might want to package the view or some context with it as well so that everything acts as a single entity. Spotting problems. This part isn't about pointing, sharing, basically. It's just to show how easy it is to see problems like the ones I just addressed on sites without having to log in or do anything, just looking at the source code. For example, opensource.com. JavaScript and CSS aggregations turned off, but not CSS. I don't know why. They use the Panopoly distribution, which means that their modules are in weird places, but because the CSS aggregations turned off, I can see exactly where each module is stored, so I'm not particularly brilliant. Let's just go into that for everything. If you look at the changeload.txt, it says it's running Drupal 7.24, which is pre-Drupal Armageddon, Armageddon. I'll leave it to you for a user exercise to see if that's actually vulnerable. Belgium.b launched quite recently, really, and it does loads of stuff in the right way, but for some reason, they've got CSS and JavaScript aggregation turned off. I'm not sure why. Maybe it's indicative of why there's been a lot of downtime on the site recently, because they're trying to come with added traffic. It does a load of stuff right this site. It's got changeload.txt isn't there, and all the sort of right things are in place. I've just gone into the Drupal showcase and found this one. It's quite easy to see. This is a Drupal site multi-site setup. I'm not sure if it's multi-site setup itself or if they just stored files in a different directory, but it's easier to spot this kind of thing going on the internet. I want to go on record to say that I absolutely love Elite Dangerous, but their community site is fucking metrocious. CSS aggregation is turned off. There's no path auto. It's this weird multi-site setup, and you can clearly see it's taken the bootstrap theme directly off the internet and just hacked it because it's running live code. If anybody knows who runs that site, just get them to give me a shout. It tries to be up the wall, because every time there are news features, every time they create a new news item, and they share it on Facebook, that link is just no-rhydex, why is it? It's brilliant. There we go. Just some top tips to take away with you as we finish. I think they're slightly over on me. Essentially, have a GoLive plan. Turn on JavaScript aggregation as you go live. Before you go live, sorry. Think about turning off modules. Think about uninstalling things you've played with and didn't quite work. Internally, think about the experience of your users, including all of your content editors in your site admins. Don't try to massively overcomplicate simple things, so coding example there, but if the user wants to do something, don't get them to jump around different hoops. Try to get them to do it in one place, and then whatever they've done there should be pulled into different locations. I have seen people create a node at a single page, and then they have to go somewhere to put it in a block and then somewhere else to put it in a menu and just have it on the same page. Don't use specific templates. Try to generalise your system. Generic templates are much better. Think about the long-term life of the project. Don't think about getting it launched. Think about updating it and maintaining it in the future. Any changes you might have to make in the future. Fundamentally, learn the system, really. You're using Drupal as a tool, so understand the ins and outs how it works and how you override anything. That's essentially it. I think we're massively over, but any questions? Yes, that's right. It was a third-party site from another agency, and that was the first thing we did, was say, right, you've got user files in here. Let's get ignore them. There's no need to have them in there. Sorry? Things like... That's not a bad idea, actually. Because it can't be deployed as well. In terms of the CSS JS application here, I think there were a couple of cases when somebody tried to switch it on as per whatever it is, and management and whatever, go with the idea that you copy everything at once. Of course, the reason it didn't work was that somebody's CSS file or some JS file was badly formatted or... That's generally the problem, isn't it? So, is there a good option for finding... So, if you upgrade your JS and it breaks, as I was told, of finding the problem quickly without having to go from any bucket? As part of our Jenkins tool, we use JSLint. Which does some JavaScript checking to make sure that everything is syntactically correct. But I'm not quite sure here you'd check to see where your problems are. Presumably, it would be from your custom code that you're entering, rather than from anything else. Right.