 WordPress, I'm actually gonna have a lot of slides with code and I'm gonna go through them quickly. So I recommend pulling up the slides if you wanna look at them later or look more at an individual slide. But here we go, there's me. I started using PHP in 2002 and then in 2006 I found Django and this is actually the way back machine for the Django website. You probably couldn't tell besides the latest release being 0.95. Over for 110 communications and we make client websites. We have about 20 live Django client websites for clients. Many of them started a while ago before 1.0. All of them are at least Django 1.6. I say at least because I made sure to upgrade a few of them to 1.7 now that it's out. And actually a lot of them can run against master without warnings, which I'm pretty proud of. So we had a situation, we had a five-year-old WordPress site with a modified theme we built back in the day. Wasn't that fun to modify the theme and it wasn't that fun to support. It's WordPress, wasn't quite that fun. WordPress is built in PHP. And then we also had a Django website for them that handled like an internal directory. And there are problems mixing WordPress and Django. A lot of the problems are with WordPress. All of this is a WordPress. Frequently get hacked and you'll get spam on your site and advertising and if you leave your WordPress site around it will probably eventually get hacked because it's a very popular product and people find vulnerabilities and then write a bot that'll search websites for that and then you'll get hacked automatically and won't even be targeted. Plugins are not fun. No one likes buggy plugins. WordPress has lots of plugins and it's not fun to debug things in PHP. There's no pretty Django tracebacks. PHP in itself is a problem. The quote is, I don't know how to stop it. There was never any intent to write a programming language. I have absolutely no idea how to write a program language. I just kept adding logical step along the way. It says a creator of PHP. So once you try Python, you just don't ever want to go back to PHP. Templates are interesting. It's no fun to mix PHP templates and Django templates. Although someone found a way to run arbitrary PHP code in Django templates. Why would you do that? I don't know, but someone wrote a package for that. Multiple databases are also not fun. Having two multiple databases, one for Django, one for WordPress. It's not that much fun. It's twice the work pretty much everywhere. This next slide isn't really working, but that's okay. I'm worried about mixing PHP and Python in Apache. I talked to Graham Dumbleton about this. And he says it actually is not as bad as you would think. And he actually wrote up a whole blog post yesterday right before his talk explaining how to do it. And it's kind of funny. Like while I was talking to him, he wrote 10 lines of code in modWiskey that actually makes it a lot easier to use PHP with modWiskey as funny as that sounds. So my solution is let's use Django for everything. This is what the website looks like now. And convert the blog to Django. At least so I started looking, okay, what Django blog application should we use? We got a lot of options. Which one do you pick? Or do you even use one? You can also just make your own blog model. You have full control and it's actually kind of fun. A lot of people do this. It's a good like starter project if you're interested in learning more about Django. Run your own blog for a while. You'll learn a lot and it's like real, something really you can do to learn Django. But when you do it, you got to decide, okay, what fields do I want? Do I want a title field, a slug field? How do authors work? What sort of fields do I need in my blog model? There's an unlimited number of options. How do you decide? Sometimes it's even harder when you're working with a client. Like okay, what do you want on your blog model? It can take some work to figure out, but it's possible. And how much work is it gonna take to migrate existing content into your blog model? This is some code I wrote four years ago to migrate a bunch of data into a blog model that I made. Actually, yeah, we forked it from one of the other ones. And how do you edit content? So initially, if you just make a blog model in the admin, you're gonna get a field that looks like this. It's just raw HTML. Is that what you're gonna give to your client if you're doing client websites like we are? Are you gonna install and configure TinyMCE for Wizzy Big Editor? Figure out all the configuration and install it. Work out all the bugs. Or do you use CK Editor? As far as I can tell, their documentation is really bad. But it's what Drupal uses. Or do you just teach them markdown? So markdown, a lot of us like markdown, but are you gonna teach the client how to use markdown, hold their hand through stuff, tell them how to make links and such? Or do you teach them rest? Here's another way. You gotta decide all that. And it could take days to figure out, make those decisions. How are you gonna work with images and videos? So uploading an image, get it right in the blog post. Do you resize it? Do you wanna allow embedding YouTube videos and such? There's a lot that can go into it. Django, this is DjangoPackages.com and that has a bunch of competing options. So you could pick one of these, install it, and configure it and make sure it works together. And then there's just like, whenever you're building something, you could just keep on building features. Do you wanna do a read more split where you have a bunch of text on your homepage and then there's a read more and you click it and then there's the rest? And do you wanna make a way in the admin to specify where that split is? Are you gonna do comment moderation? Are you gonna use discuss? Are you gonna do comments in Django? Are you gonna do autosave? I've had someone use one of the Django admin before and they're like, so do you autosave at all? Because I just wrote a bunch and I think I lost it all. There's also, are you gonna do revisions so that if you don't accidentally, if you do accidentally delete something out, you can go back and get previous versions of stuff. Are you gonna do a thumbnail for each post? Like on the homepage, you know, you want like the image for the post, but your post actually has a bunch of images in the content field. How do you pick the right one and how do you make it look right? And then you can have like a media browser. I think there's a bunch of Django plugins. I can also do that, but you gotta kind of install it and make it work with your WYSIWYG editor and you may want like a pop-up where you can browse all of the possible images and it can just kind of go on. So you could do all that using Django, but how long is it gonna take and are there gonna be bugs? You know, we do client work so you gotta estimate out how much it's gonna take, but I think there's a way to keep it simple. What if we keep the WordPress in the admin? So we're migrating from an existing WordPress website. What if we keep WordPress for editing content and then use Django for actually serving that content out and Django is actually the public-facing side of the website. The admin is just for whoever's actually editing content. What if we keep that as the admin for editing stuff in the database and use Django to actually serve that content? Apparently WordPress actually has a kind of decent editing experience. Has WYSIWYG editor that's already been picked, installed. Has autosave revisions. It has a media library. It has a custom key value metadata. This is kind of cool where it's like I just need another field. It's not handled in there. WordPress just kind of has this thing built in out of the box where you can add name and value pairs. Can be really handy. It has built-in comment moderation and it's getting more and more mobile friendly. And it looks pretty good. It has good CSS. So it all just works together out of the box. There are not that many bugs and they spent years improving the user interface and probably will continue to, kind of like this connection lost feature where it's like backing up in the browser just in case you lose a connection. The POST module, the POST model has aged well in 13 years so they came up with something, found all sorts of problems with it and keep revising and revising and revising and tweaking it. And I don't need to think about what fields I need if I can just use that. It's pretty mature and it works. I know it works because at least three people use it. So in general, it's kind of a time saver so I don't need to worry about bugs in the admin. TinyMCE has already been installed, fully configured. I know it works. The fields have already been decided. I'm sure a lot of you want to do customization and get it, have full control and get it exactly how you want but sometimes you actually don't care and you care more about the front end and how it looks. It's also really easy to migrate from WordPress. You just start using the database and you don't have to write a bunch of database migration code because the models are exactly the same. And it means I have more time for the front end and other sections on the website. So you can get something up and running fast and it works and I can work on, I think we also did another section of the website that we actually did use Django, use the admin and everything and I had a lot more time to work on that section of the website because I didn't need to worry about all the individual WYSIWYG issues in the admin for the blog. It was just kind of fully featured out of the box and you're probably saying, but it's PHP, yuck. Do you want me to just go through all bad PHPs? I think you can do it if you keep it simple, follow these rules. So you can keep WordPress running using this thing called PHP FPM, fast CGI process manager, which is really simple. You just hook it directly up to Nginx. You just install, on a boot to or W and you just say, so you have to get install PHP FPM and then you also got to install my SQL and I'll read through quickly the Nginx. Pretty standard, you got your server name and then the client max body size for gigabytes that means basically allow uploads to the website, don't block them. You get these weird errors if you don't. Stick all your PHP files in slash path slash two slash PHP. I don't know if anyone actually goes through examples and then creates like a path folder in the root of their file system. That's actually just a placeholder. You can put that wherever you want but I'm sure some people actually create path. Anyway, try files means like first check to see if there's a static file matching the URL. If not, pass it to index.php. This allows pretty URLs and then finally, if you do hit a PHP file, pass it over to fast CGI. Fast CGI by defaults listens on this socket at least in the latest version of Ubuntu. It just doesn't let a Unix socket Unix socket and works. You can configure FPM if you want but it just works out of the box as it is for starters. And if you're not using Nginx, why not? It's really good. I highly recommend it. This is a scary feature WordPress updates itself. So the security issues that I used to run into WordPress will now actually automatically install security updates when they come out. And they'll even have a button. There's a reinstall now button. There's a, you can also hit the button to upgrade to the next major version. Totally scary but apparently it works. I have doubts but I think apparently it works. But so once you have that just don't touch WordPress. Don't install any plugins. They'll open you up to problems. If you do have to, you may need to but like you gotta fight and try not to do plugins. Also don't write any custom PHP. You'll need to maintain it. This is the PHP hammer. So don't write any custom PHP code because you have to maintain it and debug it and it's not fun. You have to do, you have to configure WordPress. That's WP config.php but besides that I recommend not doing any PHP code. Turns out you can just consolidate WordPress's database with Django's database. So I use MySQL. Of course you've only used Postgres but if you wanted to do WordPress you gotta use MySQL. So I'm just dumping the WordPress database into the Django database. The WordPress database uses these WP underscore prefixes so you're not gonna get any table clashes and it's actually a lot easier to maintain it back up than just one database because it's one website now. There's a project called Django WordPress that you can add to your installed apps and your URLs and it'll actually just start handling your blog and it understands the WordPress database and it'll serve up your content. It has database archives and such and you just write the templates. I looked into that and actually I decided, there's actually, I bet I could just do this from scratch and you get a little bit more control and it's actually kind of fun and it's really not that much work. I assume half of you just went to the talk on InspectDB and inheriting a database. That's basically what we're gonna do. Basically what I did was dumped, ran InspectDB, dumped it into models.py and got something kind of like this. Which works. Although I did have to set up foreign keys, that was probably the biggest thing. I also figured out there's a pretty simple, you can set up a simple many to many for categories and tags. That worked for me. And just set up all the foreign keys, link all the models together because InspectDB doesn't handle that quite right out of the box. Once you have that, queries are really simple. You just filter by posts as opposed to revisions of posts or images or pages. So I want posts and I want the ones that are published. Now I have post objects. Django just knows it out of the box. Django has our assassin atom feeds out of the box and it's really simple. One thing I ran into is WordPress sticks in these crazy short codes for like saying, yes I want an image here and there's some information about it. And I wrote some really hacky, messy code to get that. I bet there's ways to improve it but this is just regular expressions and splits. It's totally ugly, don't use it. But it's possible. Comments are really simple. I just use model form and say I want the author, the email address and the actual content of the comment. You can also add in the author URL. WordPress has handy fields for collecting the IP address and user agent. So hey, why not? And then it's just a basic model, basic model form saving and creating and then redirecting. So disadvantages, PHP, right? We all use Python because it's simply better. I can't support every possible feature of WordPress on the Django side but I can support them as I need them. So there's like widgets. They're available in WordPress admin. I don't actually have the front end for that but I can support them later if needed. And the database can change over time. Though it's actually been pretty stable recently. I think it's been like two years as they made a database change. And it's simple. So I can get the website up and running very, very, very quickly. And actually I can even shut off the WordPress website and the Django website is still there. So WordPress just edits the content. Django serves the content even though it's read only the website's still there. And if WordPress goes down, that's totally fine. And I'm always free to ditch WordPress and use the Django admin later. So I got stuff up and running now and we find actually we're quite limited by what's going on here. I can always start using real Django for the admin also. Good and here's a, so that's most of what I have to say. Lunch is happening soon but why not a cat photo and then a couple totally random anecdotes on web versus application. This is just totally off topic but it's something I've been thinking about. There's a distinction between what's the difference between a web application and web content. So content web pages should work without JavaScript. They're served by get. They generally don't change per person and the content usually shows up in Google search results. Google indexes content. And generally they read only the user. You're like you find something on the internet and you read it. And generally things are easy to build and easy to cache because they don't change much. Web applications on the other hand are usually behind login. They're usually invisible to search engines and they make use of like post and other HTTP verbs. So like a REST API. There's plenty of talks on the REST API. That means you're building a web application. And it's usually okay to acquire JavaScript and actually you're usually JavaScript heavy and using Angular.js and such. And it's user specific. The user's editing things and changing things and working with your website. And it's actually a lot harder to get right than content. In my opinion, it's a lot more work to allow the user to edit things versus just user reading things. So in my case WordPress is the application and Django serves the content. And if anecdote, I have 15 seconds for a really crazy idea. What if we rewrite the WordPress admin from PHP and use Django for it? So like keep the JavaScript and the CSS in sync with WordPress and then we build like this compatibility. You build a compatible backend that uses the WordPress API and enjoy life PHP free. It would be a lot of work. Crazy idea. I don't expect you to understand it. But I think it's cool and that's all I got. Thanks. I think they're just digesting. Yeah, I went really fast. So I have a client who has a WordPress site and has hopped from host to host just for performance reasons. Find someone who caches differently or something. I suspect using Django and Nginx that becomes a non-issue. Is that your experience? As far as caching goes. Just per, I mean, the speed of serving all the content. Yeah, yeah. I mean, if you were serving Apache directly and being at some host that uses Apache, Nginx is gonna be way faster assuming it's serving static files properly. It's also really easy to set up. I really like WordPress has, sorry, Nginx has proxy underscore cache, which is a directive and you can basically do full page caching on whatever is coming back from Django, which I think is really cool and there are lots of options of how to speed up the website and I imagine especially because if you do do it from scratch and using Django, you can have a lot more control of what are the database queries being run and such. So you have used caching doing it this way? Say that again. I said you have used caching doing it this way? Yeah, I have, yep. Yeah. I was just wondering if you'd ever looked into like combining the WordPress multi-site stuff with Django or wear that? Yeah, I have. I don't know, I've looked into WordPress multi-site and it's like is this something also worth doing and as far as I can tell WordPress multi-site is kind of just a big hack and even in the WordPress community, it's like it kind of works and kind of doesn't. One actually real issue is WordPress multi-site will put like a table prefix on everything. So each site will have the same, will have separate database tables just with a different prefix and I think that would require some hacks in order to get working correctly with Django because you can't really just duplicate models with different table names that really confuses Django. So I just try to avoid it and rather just do a separate database if I'm doing multiple. So Django has the great authentication back-end abstraction and I was just wondering if, so you could probably theoretically use Django to authenticate against WordPress. Do you know of any ways you can get WordPress to authenticate against Django or? Right. Yeah, so that's one thing too is like I'm just kind of assuming that the person's gonna need to log into two places, have two different usernames and passwords. That's one of the downsides. I'd recommend, I think I once, we once had a case where we like installed an LDAP back-end to try to get WordPress and Django to share usernames and passwords. It really wasn't fun. It's a lot of work. I'd rather go the route of having Django use the WordPress user model as a custom user model. I haven't actually tried it but I bet it's theoretically possible and then you're actually using the same username and password and reusing it. Thank you. That's awesome. I know everyone hates PHP and everyone hates WordPress. No one more than me. But the place that I work runs almost 200 different WordPress sites, busy WordPress sites out of a single WordPress install. Wow. Not using multi-user. And the key is no plugins. They write everything themselves. So if you need to functionality of a plugin, they just write it themselves. Super secure and it's really stable and really fast. And when an update comes out, they can run it and they know that it'll work because there's no, they know where every... They know every line of code. What every so-called plugin is doing, right? So they just, they're up to date all the time. It's super secure. And I'm the guy that's always trying to, I'm writing the Django stuff and I'm always messing around with the database. So I'm gonna, I need your card. It's quite a buggy. Cool. So the last thing you, WordPress seemed to really favor Apache because it comes with the HT access that you need to run. Was it easy to just convert over to Nginx? Yeah, and WordPress is also, just like we're discovering Nginx, WordPress is also discovering Nginx and they have documentation of how the perfect way to set up Nginx is. I just used, I kind of copied just like the bare minimum of what you would need to set up WordPress with Nginx. And there's a couple more things you can do to tweak this and make it better, but generally WordPress is like supports Nginx more and more. That was gross to go back to my SQL. But thank you. I think it's lunchtime, everyone. Thank you so much, Colin.