 Good afternoon everyone. Day three. Next thing is the lightning talk after this. If you actually have a lightning talk up on the board, please make your way straight over and assemble in the room for track one, but please don't go in if they're still talking. After this talk. Yeah, that's because the lightning talk. Leave now. No. But that shows Robert is awake. If you're not so awake outside it's really chilly. Good chance to freshen up. Let me introduce Will. Will works for Catalyst. He's going to talk about mezzanine and yeah, take it away. Cool. So yeah, I'm, hi, I'm Will Hughes. I'm a primarily a Python dev for Catalyst. I do a bit of everything though, a bit of rails when I'm absolutely forced to, but Catalyst Christchurch. We've done over the last couple of years. We've built three mezzanine sites for clients. We've got a fourth one on the way once they finally sign off on it. But we also do quite a bit of Drupal. Probably a bit of an understatement. We do an awful lot of Drupal. And part of that's led us to try and work out if there is any alternatives to Drupal or complimentary products, which led us to start investigating mezzanine, which led me here. So in a nutshell, mezzanine is a toolkit built on top of Django designed for building sites with editable content. It's calling it a CMS isn't really quite accurate. It's not a system. It is a toolkit, a set of APIs, a set of tools that's built on top of the Django toolkit that just makes all of that stuff easier. It ships with a reasonably opinionated base template that you can use to get started in the same way that Django itself ships with a reasonably opinionated base template. You're free to just discard that if you don't like it. It's BSD licensed, same as called Django. It supports Django 1.7 and 1.8, so you've got LTS support in there for Django. Python 2.6, 2.7, 3.3 and 3.4, so all the Python that you love. It is maintained by a guy called Stephen McDonald currently working for Google, but does a bunch of other stuff in his free time. How he has any free time, but yeah. mezzanine.dupo.org is the website for that, so if that's nothing else, if you go to sleep now, that's the important stuff. Getting started with mezzanine is really, really, really similar to getting started with Django. If you follow any of the Django tutorials online, you install some dependencies, you make a virtual environment, you install mezzanine or Django into the virtual environment, and then you use mezzanine project to instantiate that opinionated base template. That is what gets you started. That's a great way to start learning. Personally, I find that base template, it's not that great, but if you're just starting it with mezzanine, this is a really great way to get started. The libjpeg there is required for Pillow, which is the fork of the Python image library, so if you want to be able to actually upload jpegs, not exactly an uncommon format, you need libjpeg. Features. You can preview unpublished content, useful. It's got a really neat inline editing system. I'll show you that later. If you're logged in as an administrator, you just get these little edit buttons, you change it, you hit save and you're done. It has native support for multilingual sites. It gives you complete control of the markup of your site. It uses the Django templating engine, Ginger, and gives you a system for completely customizing how the markup on your site is done. Not terribly relevant for me, I'm mainly a back-end dev, but the front-end developers I work with really, really like this because it makes styling things so much easier if you're not working around a markup scheme that's imposed by another system. It enforces a strong separation of the site structure and the site content. Quick show of hands says people worked with Drupal at all here. Drupal doesn't do this. In Drupal, everything is in your database, basically. You can do some stuff with features to define your content, structuring code, but for the most part, everything exists as objects in your database. Even configuration items are objects in your database. I'll come back to that a bit later, but that's a really, really strong good feature that lets you follow good engineering practices when you're building them as an insight. It's got a really, so it's really nice for developers. It's really nice for content admins as well if you've got people who are trying to admin the site who are not technically, you know, not sort of really hardcore devs. It's got a nice interface they can use, not as nice as Wagtail, but I have to admit I'm sorry, but it's pretty nice. Out-of-the-box support for discuss has an external commenting system or a kismet if it wants to use its own internal commenting system or you can just throw it all away and build your own. It doesn't require that you use its systems and support for Google Analytics, which you don't have to use either. As I said, build on top of Django, all the Django features you love. So part of the reason why I like using Django, don't know about you guys, but Django is part of a bigger ecosystem. There's core Django and core Django is great, but it doesn't do absolutely everything for you, but there are a huge variety of modules that do things that you might find useful. Mezzanine taps into this ecosystem really well that reusing components like Django modules that are not explicitly designed to work with mezzanine is really, really straightforward. So for instance, mezzanine has a built-in search system. It's kind of naive. It's not terribly performant. If you've got a tiny little blog site, it's great. It just works. You don't need to worry about it, but if you're building something bigger, if you're building something complicated, it doesn't really work for you very well. For instance, one of the sites we built in Christchurch involved a document library for this organization that had something like 10,000 publications in it, 10,000 PDFs that they wanted full text search over, be able to categorize and tag and all this. Mezzanine core just can't do that. Haystack is really good at this. Haystack is an interface into a bunch of different search backends like Solr, Wush, Elasticsearch, all of this stuff provides like an ORN interface into that. So it's really, really straightforward to just add Haystack into mezzanine because it makes life really easy for that. Django Compressor, the base template has support for this. If you're not using Django Compressor on your Django site, please, please use Django Compressor or something like this. Pipeline's great as well. It's a system for asset concatenation minification. So your style sheets, your JavaScript, all of this, bundling them up into a single style sheet file, a single JavaScript file, running them through a minifier, you know, I'm on cell data a lot of the time. I don't want to have to download 40 style sheet files at a few K each with a TCP connect round trip for every single one of them. Please, please, can get the name. Cartridge, also another Steven McGraw special. It's an e-commerce system built on top of mezzanine. So you've got the layers of tooling building up there. I haven't really had a chance to play with it. It looks really, really cool if someone wants to pay for some R&D time. Come talk to me afterwards. So once you're getting started on a new Django project, new mezzanine project, mezzanine is just Django. So if you're already doing Django, just keep doing what you're doing. There are a lot of ways of deploying and configuring a Django site. Being a bit more helpful, the way that I like to do my Django personally, my mezzanine, is your site should be at least one, maybe several Python modules. You should build them into wheels. You should stick those wheels in a virtual environment on your UAT staging prod servers. Use something like config parser to load up settings out of an I&I file or JSON file, whatever. YAML also works. Engine X and Unicorn, if you'd like a patchy, use a patchy. I find it a pain. Mezzanine specifically, I find it really helpful to split the site into two Django apps, one of which is for the site content, site structure, things like different page types and all that. And then another separate module that is just your theme. This way, if people come and say, you know that site we built for you, yeah, it's great. We've changed our branding and we kind of need you to completely redo the visual design of the site. You can build a separate thing and then just swap them over. The demo has an example of how to do this. There's going to be a demo. Let's have a demo. Acme widgets. This is something I cut together in a few hours, a few days ago. All the code for it I will post links to at the end. So this is just a standard page. You've got a menu. You've got a side menu. You've got a bottom menu as well. This is what a default basic, unconfigured mezzanine site looks like. You'll notice users at my blog that my blog looks a lot like this because I'm not a visual designer. I'm a back-end engineer. So I mentioned an admin interface. If you log in, if I can type, yeah, I'm running in debug mode. Don't judge me. No. I'm not that crazy. Okay. So this is what the admin interface looks like once you get into it. It's Grappelli. People have used Grappelli before. It's a slight fork of Grappelli. There's some problems with core Grappelli that doesn't quite play nice with the way that mezzanine devs want things to work. So they've forked it and they do contribute patches back upstream. It's never this slow. It's always fast. So the core basic mezzanine, you get a page tree. You add pages. You have different types of pages though. This worked perfectly. Why did I do a demo? You have different types of pages. So these pages here, this page here is just a straight, rich text page. All you've got is a title. You've got published status, date, and content. TinyMC4, which is what I'm talking about, making it nice and easy for people to edit. It's a nice, fizzy wig. You've got buttons. You can edit the markup if you want directly. And you can tell what menus you want it to show in and then set some extra metadata if you really want to. But if you don't like this, that model, you can add new types. So I've defined an employee type. This is a fairly common pattern we see with a lot of clients that they want a type of page where you've got, this is our CEO, and our directors, and this is a little blurb about them. This is what position they've got. This is a photo. So you can take the default rich text page and subclass it and add new fields, and you can add a text field and a photo field. And then it's got a built-in media browser. So you can upload media and you can create directories and all of this great stuff. And you can set permissions on the photos and uploaded files and all of this. You don't have to use pages though. If you don't want something that's part of the page tree, and I'll talk about this a bit more later, you can just define standard Django models, but instead of subclassing model, you can subclass displayable and then you get the URL, you know, you get the metadata, you get the published status and all of that for free. So that's about what I'll... So if you're logged in and then you jump back onto the site, you get this little yellow thing here and you can hit the button, and then you get editing boxes. And then you can just start, you know, so there's a spelling mistake there. We'll see, it isn't spelled like that, it's got a capital O. I'm going to fix that. I'm going to hit save. And that's really nice and powerful and we find that really easy to use for the content admins. So that's the demo. So I talked about two types of content in that, that you have pages and then you have just objects. So pages are great for when you've got a really small amount of stuff, you know, you've got 10 or 15 staff members that you want to feature, you've got a few, a couple of different types of things that you do. So you've got these pages, they're the things that appear in the menu. You can manually control their position in that menu, which means you have to manually control their position in that menu. So if you've got hundreds of objects, you probably don't want to have to manually sort them into an order, you're probably better off using an object and I'll talk about that in a bit so that, you know, you can let the machine do that and then you don't have to manually do it. So you implement this by subclassing as a model, mezzanine pages, models page. You don't need to write your own view logic, mezzanine just deals with that for you. You, for the most part, don't really actually have to write an admin either, it pretty much just deals with that for you, I'll show you that later. You can also just use the rich text page type, which I showed you before, you don't have to define your own types, the basic basic mezzanines that you don't even have to get into this at all. So that's what models looks like, right? That's what the model for that employee that I showed you before is, you're subclassing page. The rich text that I'm subclassing there as well gives you the content box with the WYSIWYG and then you just use char field, file field like you do in just plain Django. File field is actually a slightly different type of file field, mezzanine has its own file field that looks an awful lot like the Django file field so that you get the media box there. That's all you need to do for the admin is you just tell it that you want to use the page admin, that makes it sharp in the page tree. It automatically works out what fields it needs to stuff in where you can't override the ordering of those if you want, but don't always have to. And then you're templating. Because you have complete control over the markup, you do actually have to exert control over your markup. So for pages, you want to extend the pages page template. It gives you a lot of sensible defaults and then you overwrite the bits that you need to have changed. You also want to load up the mezzanine tags, tag libraries that I'll talk about in a sec. This is using the default templates. The base template is a bootstrappy template, gives you a bunch of different panels and blocks that you can stuff content into. If you don't like bootstrap or if you don't like the way it uses bootstrap, again, you can just override that template. You can set it up however you want. So I'm going to put in the right-hand panel. I'm going to put in an image. I'm going to take that employee image photo field and I'm going to make it a thumbnail because I don't want someone to come in and upload a 2 megabyte PNG file that's thousands upon thousands of pixels wide and I'm just going to thumbnail it down. And then in the main block, I'm just going to put the content there. I'm going to pass it through rich text filters first. You can define functions that will pre-process the content. So for example, on my personal blog, I've got a filter that I wrote that will use BeautifulSoup to inspect the content field of a block for looking for pre or code tags that have a class highlight. And then it runs them through the highlighter on the server. So you don't have to do that client side. I'm having that done on the server. And then Market is safe so that you tell it that you are expecting there to be tags in this code. The editable section there as well is what gives you the little edit tag. It's a mezzanine template type. The page tries to do something clever with the templating in that it will try and guess which template it should use. Note that I never explicitly told in the admin or in the model which template I want to load that object with. So it goes through and it looks down. It will take the slug which was like the title. It derives from the title of the page that it uses in the URL. So it starts pages, page slug, pages in that case employee. Then it starts to recurse down and it will look up the page tree where it happens to find that page object and it will start looking back up. So if you've got about us directors, the big boss, it will look along that path to try and find a template that it can use. And then if you can't, it just gives up and uses pages page which is for the most part blank. Django debug toolbar makes it really easy to debug these things. That's why I had it installed on the example. Really quickly object based types. When you expect to have a whole bunch of things, for example pages of the publications that I was talking about before, those were an object because you don't expect someone to drill down through a menu to find one of 10,000 publications. You expect them to search or you expect them to hit an index page and then find their way from there. So instead of using subclass and page, you subclass displayable and then you have to define your own view logic. Models looks an awful lot like, again, just the standard model, except you have to define a get absolute URL method. That's what Mezzanine uses for the view on site links in the admin. The admin, this is one of the things I don't like. The overriding the field set order thing is really nasty. It's a bit of a clutch. I think there are suggestions on the mailing list about better ways of doing this that might end up getting implemented in later versions of Mezzanine, but at the moment it's a bit gross. And then the view is a standard Django template view. The only thing that's really different here is if you note where I've got context widget equals and then looking up, trying to find a widget out of the view quags, I've been using .published for self.request.user. The base Mezzanine displayable class has a few fields that control visibility. So you have is viewable by staff only field, requires login field. You have a when you want it to appear on the site, when you want it to expire off the site, and whether it's a draft or not. The .published uses those fields and then looks up and says, right, for the request user, are they staff? If not, and it's not a published thing, we're going to bail out. No, you can't see that. If you are staff, then yeah, we'll let you view it. If you're not staff, but it is published, then yeah, sure, you can have a look at this as well. So instead of using .objects, you've used .published. The thing was that editable object, if you set, that's what it's using for the editable interface. Cool. And then the template looks pretty much the same as it was with the page. So comparison. Not going to try and compare this to Wagtail. I haven't had any chance to actually look at Wagtail. So I'm probably going to be, so I'm going to be talking about Drupal a little bit. That's what I've had most exposure to. You can minimize your exposure to Drupal. Please do. It's like the play. You just don't want to even. Structure is not content. Config is not content. The settings for your site do not live in a database. They should not live in the database. This is the thing Drupal does that just drives me mad. Try taking a Drupal site that has been on UAT and the customers have been at it and have fiddled around and added stuff and deleted stuff. And then you go in and you set up a new feature and then you want it to exist on the production system. How do you know you can't, the answer is you can't. You can't know that when you copy that database across, all you're getting is the settings changes because the settings changes in the content live in the same database. And even in some cases in the same table in the same database, it's maddening. Mezzanine enforces a really strong separation between the configuration of your site, which is Python. It lives in your version control system. You can test it. You can run it through your continuous integration infrastructure. And the content, which is in a database and that they are separate. They never the two shall meet. You can take a database dump and a get tag of a Mezzanine site and deploy it to 50 servers and you can be sure that they will always have exactly the same configuration and content and structure. You can't do that with Drupal. You can't always do that with WordPress. This is one of the really great benefits we see with Mezzanine. You have no risk of accidentally polluting a Prod site with test data. How many times have you gone on to a website, someone's blog, and seen the pages of Laura Knipsom because someone's taken a UAT dump, loaded up into production. You have control over your market. If you want your Mezzanine blog to be haiku compliant, you can do that. That is a thing that is technically possible. I wouldn't recommend it. But if you want to do that, you can. It gives you control of your markup that uses the Django templating system. It doesn't enforce a structure. The downside of this is that it doesn't enforce a structure. You have to kind of know how you want your markup to be laid out. The default template does suggest a sensible approach. But again, you don't have to use it if you don't want to. It's really easy to drop Mezzanine onto an existing Django site. If you've got a site that's got a few static pages that you've coded up in templates, it's about three hours work to make them a dynamic, editable things on your site. The template tweaking is the hardest part. The actual Django site of things is really straightforward. Mezzanine, the things that Mezzanine doesn't quite do well, versioned content. This is a bit of a pain point, personally. There is no support in core Mezzanine for having a page where you can edit it and then rollback changes. There isn't a generic solution either that I found. I'm hoping, really hoping, someone's going to come up to me afterwards and tell me that I just haven't been googling right. But as far as I know, there's nothing that exists in Mezzanine. There's something that Drupal and WordPress support out of the box. The documentation. Mezzanine suffers the curse of a moderately successful open source project. The documentation is sparse. I think is probably the right way of putting it. It's there and it will help you sometimes. A lot of the time it is easier to just go look at the source code. You can just go look at the source code, though. It is really nicely well-written, clean. Don't use Mezzanine with an organization that has a two-week turnaround for getting approval to deploy new code onto production. Because your config is your code, you're going to be changing your code a lot. If it takes you two weeks to get approval to put a new version on the prod servers, you're going to have a bad time. Maybe Drupal might be more appropriate. In summary, Mezzanine is pretty much just Django, but easier if you're running a content management system. It's really quick to get started. It separates your structure from your code. It's got a really strong ecosystem because of being able to borrow from Django's ecosystem. There also are a lot of projects that are Mezzanine-specific that make life easier for Mezzanine sites. You've got the pages, the objects. I'm about to get pulled off. You can use it with your existing Django app really easily. Please come and help us write some documentation. We are trying. We're getting there. It's getting better. Those are the URLs. I'm Will Hughes. Questions? Thank you very much, Will. That's right. Yeah, so please don't store your configuration in the database. Minify or you're not making friends. Questions? Just a quick one because Lightning talk is just about to come up. Comprehensive talk, then. If people want to talk to me offline, I'll be hanging around outside. Cool. Excellent. Thank you so much.