188
Content Management That Won’t Rot Your Brain Sean Cribbs

Content Management That Won't Rot Your Brain

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Content Management That Won't Rot Your Brain

Content Management That Won’t Rot

Your BrainSean Cribbs

Page 2: Content Management That Won't Rot Your Brain

complicated

http://flickr.com/photos/koolgary/2460635163/Content management on the web can be pretty complicated.

Page 3: Content Management That Won't Rot Your Brain

hundreds

http://flickr.com/photos/carowallis1/485124848/There are hundreds of open-source content management systems to choose from,

Page 4: Content Management That Won't Rot Your Brain

in-completion

http://flickr.com/photos/yakobusan/2436481628/all in various states of completion.

Page 5: Content Management That Won't Rot Your Brain

un-intuitive

http://flickr.com/photos/mashed_potatoe/65823367/Most of them have unintuitive user interfaces,

Page 6: Content Management That Won't Rot Your Brain

tangled

http://flickr.com/photos/randomurl/440190706/tangled content models,

Page 7: Content Management That Won't Rot Your Brain

ugly code

http://flickr.com/photos/flickerbulb/187044366/

and opaque, poorly-architected and undocumented code that refuses to yield to customization attempts.

Page 8: Content Management That Won't Rot Your Brain

content model

These include abominations like ezPublish, which is so in love with its content model

Page 9: Content Management That Won't Rot Your Brain

content model

that it seems they implemented the editing interface in the content model.

Page 10: Content Management That Won't Rot Your Brain

huh?

http://flickr.com/photos/fdecomite/402499198/Good luck figuring that one out.

Page 11: Content Management That Won't Rot Your Brain

pluggable

http://flickr.com/photos/studiosmith/2085278030/Or Xaraya, that despite its ultra-pluggable code modules with proscribed interfaces

Page 12: Content Management That Won't Rot Your Brain

bridge to nowhere

http://flickr.com/photos/garlandcannon/3048731338/doesn't seem to do anything it advertises.

Page 13: Content Management That Won't Rot Your Brain

template surgery

http://flickr.com/photos/soldiersmediacenter/1148977208/Or Joomla & Mambo, which require template surgery to create a custom look and feel

Page 14: Content Management That Won't Rot Your Brain

everything to everyone

http://flickr.com/photos/twose/887903401/while trying to be everything to everyone.

Page 15: Content Management That Won't Rot Your Brain

FTP is so 1971

http://flickr.com/photos/daveseven/167903362/Why is it so hard to publish a web page that I don't have to use FTP to edit?

Page 16: Content Management That Won't Rot Your Brain

webstandards

Why can't I use HTML, CSS and the other web standards I know and love?

Page 17: Content Management That Won't Rot Your Brain

ideal CMS

So what would I want in my ideal CMS?

Page 18: Content Management That Won't Rot Your Brain

#1 : simple

First, it would be simple to use and understand.

Page 19: Content Management That Won't Rot Your Brain

meta is overrated

I'm not impressed with hyper-abstract meta-content models, just make it work.

Page 20: Content Management That Won't Rot Your Brain

#2 : standards markup

Second, it would let me write markup and presentation in any format and structure I like,

Page 21: Content Management That Won't Rot Your Brain

design freedom

giving me the freedom to design my site the way I want.

Page 22: Content Management That Won't Rot Your Brain

#3 : powerful tools

Third, it would have simple and powerful tools built-in to make most content-generation tasks a breeze,

Page 23: Content Management That Won't Rot Your Brain

PHP not required

without needing plugin modules.

Page 24: Content Management That Won't Rot Your Brain

#4 :clear code

Fourth, it would have a well-architected code design

Page 25: Content Management That Won't Rot Your Brain

easy customization

so I could understand and customize it easily.

Page 26: Content Management That Won't Rot Your Brain

drum roll please

Fortunately, there's a CMS that lets me do all these things.

Page 27: Content Management That Won't Rot Your Brain

It’s Radiant!

It's called Radiant, and it's written in our favorite language, Ruby.

Page 28: Content Management That Won't Rot Your Brain

DHHAPPROVED

And yes, even David likes it.

Page 29: Content Management That Won't Rot Your Brain

#1 :simple content

model

So how does Radiant meet my expectations? First, Radiant's content model is easy to understand.

Page 30: Content Management That Won't Rot Your Brain

Pages

Every Radiant site is made up primarily of Pages,

Page 31: Content Management That Won't Rot Your Brain

acts_as_tree

which are arranged in a tree, much like a directory/file structure.

Page 32: Content Management That Won't Rot Your Brain

has_many :parts

Pages have many content pieces called parts,

Page 33: Content Management That Won't Rot Your Brain

logical pieces

which let you break your pages into logical sections

Page 34: Content Management That Won't Rot Your Brain

content_for

think "content_for" blocks in Rails views.

Page 35: Content Management That Won't Rot Your Brain

Page-Types(STI)

Any page can have a special type, essentially a subclass of the Page model,

Page 36: Content Management That Won't Rot Your Brain

page-level plugins

that acts as a localized plugin, modifying the front-end behavior of that page.

Page 37: Content Management That Won't Rot Your Brain

Layouts

Pages also have layouts,

Page 38: Content Management That Won't Rot Your Brain

design details

which let you abstract common design details, just like Rails layouts,

Page 39: Content Management That Won't Rot Your Brain

Content-Type: text/html

and also let you specify the content type - be it HTML

Page 40: Content Management That Won't Rot Your Brain

Content-Type: text/xml

XML

Page 41: Content Management That Won't Rot Your Brain

Content-Type: text/css

CSS, or whatever.

Page 42: Content Management That Won't Rot Your Brain

Snippets

To round out the system are Snippets,

Page 43: Content Management That Won't Rot Your Brain

render :partial

which are kind of like Rails partials

Page 44: Content Management That Won't Rot Your Brain

repetitive

small pieces of common or repetitive content

Page 45: Content Management That Won't Rot Your Brain

contextual

that can be rendered in the context of many pages.

Page 46: Content Management That Won't Rot Your Brain

Filters

Pages and snippets can use text filters

Page 47: Content Management That Won't Rot Your Brain

TextileMarkdown

etc.

that let you write content in shortcut languages like Textile or Markdown.

Page 48: Content Management That Won't Rot Your Brain

template language

This is all tied together with a template language

Page 49: Content Management That Won't Rot Your Brain

Radius

called Radius

Page 50: Content Management That Won't Rot Your Brain

non-evaluating

that keeps code well-separated from your content.

Page 51: Content Management That Won't Rot Your Brain

#2 : complete design

control

Second, Radiant lets you design your site the way you want.

Page 52: Content Management That Won't Rot Your Brain

any text

It doesn't care whether you're publishing HTML, CSS, Javascript, plain text or whatever.

Page 53: Content Management That Won't Rot Your Brain

(no binary)

You probably don't want to put binary data in a page, but any kind of text is OK.

Page 54: Content Management That Won't Rot Your Brain

tags expose functionality

Most built-in and plugin functionality is exposed through template tags, so you don't have to worry that some feature will produce bad markup;

Page 55: Content Management That Won't Rot Your Brain

write your own markup

you can write the markup yourself.

Page 56: Content Management That Won't Rot Your Brain

#3 : powerful tools

Third, Radiant has powerful tools

Page 57: Content Management That Won't Rot Your Brain

over 50 tags

about 50 built-in template tags to help you accomplish many content-generation tasks.

Page 58: Content Management That Won't Rot Your Brain

navigation, sucker

You can use tags to generate navigation

Page 59: Content Management That Won't Rot Your Brain

row-striping

stripe table rows

Page 60: Content Management That Won't Rot Your Brain

feed me, Seymor

collate content into a feed

Page 61: Content Management That Won't Rot Your Brain

no logo for you!

http://flickr.com/photos/rafastarix/2729553586/

or display the big company logo only on the homepage.

Page 62: Content Management That Won't Rot Your Brain

#4 : clean code

Last but not least, our reason for being here

Page 63: Content Management That Won't Rot Your Brain

well-architected

Radiant is well-architected

Page 64: Content Management That Won't Rot Your Brain

developer goodies

and has plenty of goodies for developers.

Page 65: Content Management That Won't Rot Your Brain

show me the code

Since this is a technical talk, I'm going to gloss over the details of using Radiant to create a site and focus on how we can customize Radiant to our own needs.

Page 66: Content Management That Won't Rot Your Brain

Extensions

To this end, Radiant has a souped-up plugin system called "extensions"

Page 67: Content Management That Won't Rot Your Brain

plugins + awesome

which picks up where Rails plugins leave off.

Page 68: Content Management That Won't Rot Your Brain

merb-slices

Extensions are more like `merb-slices`

Page 69: Content Management That Won't Rot Your Brain

Rails Engines

or Rails Engines than plugins.

Page 70: Content Management That Won't Rot Your Brain

app/controllersapp/helpersapp/modelsapp/views

An extension can have its own "app" folder with controllers, helpers, models and views.

Page 71: Content Management That Won't Rot Your Brain

db/migrate

An extension can define database migrations

Page 72: Content Management That Won't Rot Your Brain

public

public files

Page 73: Content Management That Won't Rot Your Brain

vendor/plugins

and even its own plugins.

Page 74: Content Management That Won't Rot Your Brain

TATFT

Most importantly, you can "test all the time" in your extensions

Page 75: Content Management That Won't Rot Your Brain

RSpec

because Radiant provides a full RSpec harness

Page 76: Content Management That Won't Rot Your Brain

dataset :pages

a bunch of test datasets

Page 77: Content Management That Won't Rot Your Brain

@page.should render(“foo”)

and some nifty matchers to help out with Radiant-specific stuff.

Page 78: Content Management That Won't Rot Your Brain

class FooExtension < Radiant::Extension

In addition to the directory and file structure, every extension is expressed as a singleton class

Page 79: Content Management That Won't Rot Your Brain

def activate

that can provide some startup code in the "activate" method

Page 80: Content Management That Won't Rot Your Brain

define_routes do |map| map.resources :fuzzy_bearsend

route definitions

Page 81: Content Management That Won't Rot Your Brain

description “My first extension.”url “http://foo.com”

and some metadata that is displayed in the user-interface.

Page 82: Content Management That Won't Rot Your Brain

TIMTOWTDI

Depending on the scenario, there are a number of different ways we can customize Radiant to accomplish our goals, all of which can be nicely packaged up in extensions.

Page 83: Content Management That Won't Rot Your Brain

I could easily fill many hours talking about all the ways to tweak Radiant with extensions, so I'm going to give you the 10,000-foot view of the primary techniques.

Page 84: Content Management That Won't Rot Your Brain

#1 :new tags

The first and simplest way to add functionality is to define new Radius tags. As I said before, Radius is the template language used to expose dynamic functionality to the designer and content editor,

Page 85: Content Management That Won't Rot Your Brain

<r:awesome />

through the use of these 'r'-prefixed XML-like tags.

Page 86: Content Management That Won't Rot Your Brain

(not) XML

The tags seem to imply an XML-structure, but I assure you they are strictly not XML and are really just interpolated in-place.

Page 87: Content Management That Won't Rot Your Brain

<r:

Radius tags are composed of four parts - the 'r' prefix;

Page 88: Content Management That Won't Rot Your Brain

<r:children:each

the tag name, which may be colon separated;

Page 89: Content Management That Won't Rot Your Brain

<r:children:each order=“desc”>

the attributes;

Page 90: Content Management That Won't Rot Your Brain

<r:children:each order=“desc”> foo</r:children:each>

any nested contents, and a closing tag. A few notes on these tag names: Radius will execute the definition of each of those colon separated names in order and determine which definitions to use based on context.

Page 91: Content Management That Won't Rot Your Brain

<r:children><r:each order=“desc”> foo</r:each></r:children>

The colon-separated version is just a shortcut for nesting them, so this snippet is logically equivalent to the last one we saw.

Page 92: Content Management That Won't Rot Your Brain

<r:children><r:each order=“desc”> foo</r:each></r:children>

Also, the last named tag in the colon-separated list gets the attributes passed to its definition.

Page 93: Content Management That Won't Rot Your Brain

<r:stylesheet url=“/mine.css” />

So let's make a tag that generates some content - say a stylesheet link, and we'll make the tag look like this.

Page 94: Content Management That Won't Rot Your Brain

module LazyTags

First, we'll make a module in our extension to hold the tag definition.

Page 95: Content Management That Won't Rot Your Brain

include Radiant::Taggable

Include "Radiant::Taggable" and we're ready to start defining tags.

Page 96: Content Management That Won't Rot Your Brain

tag ‘stylesheet’ do |tag|

Next we'll start our tag definition with the `tag` keyword, the tag name, and a block yielding one parameter.

Page 97: Content Management That Won't Rot Your Brain

url = tag.attr[‘url’]

Inside our tag definition block, we'll grab the 'url' attribute off the tag,

Page 98: Content Management That Won't Rot Your Brain

%Q[<link rel=”Stylesheet” type=”text/css” href=”#{url}” />]

and interpolate that into the proper place in the HTML `link` tag.

Page 99: Content Management That Won't Rot Your Brain

end

The return value of the tag-definition block is what is rendered, so we're done.

Page 100: Content Management That Won't Rot Your Brain

def activate Page.send :include, LazyTagsend

Last, we mix the module into the Page model in the 'activate' method of our extension, and we have access to our new tag definition.

Page 101: Content Management That Won't Rot Your Brain

|tag|

The yielded 'tag' object inside a definition is very powerful.

Page 102: Content Management That Won't Rot Your Brain

TagBinding === tag

It's your access to the contextual parsing environment, including what page is being rendered, the request and response objects, and any variables set by surrounding tags.

Page 103: Content Management That Won't Rot Your Brain

tag.globalseverywhere

Its primary properties are 'globals', which gives you access to the global environment, including the current page being rendered;

Page 104: Content Management That Won't Rot Your Brain

tag.localscascading, contextual

‘locals' which is a cascading symbol-table of sorts, contextual to the current parsing environment;

Page 105: Content Management That Won't Rot Your Brain

tag.attrHash

'attr', a hash of attributes placed on the current tag;

Page 106: Content Management That Won't Rot Your Brain

tag.double?<r:foo>text</r:foo>

'double?', which is true when the tag contains other tags or text,

Page 107: Content Management That Won't Rot Your Brain

tag.single?<r:bar />

and 'single?' which is true when the tag is self-closing.

Page 108: Content Management That Won't Rot Your Brain

be kind, I’m sensitive

Because many tags are sensitive to their surrounding environment, you can easily do things like iteration, changing some locals property on each step of the iteration, and causing contained tags to use that property.

Page 109: Content Management That Won't Rot Your Brain

children.map do |child| tag.locals.page = child tag.expandend.join

This is essentially what the `r:children:each` tag does - iterate on each of the children, changing `tag.locals.page` on each iteration, then joining the output. To trigger rendering of a tag's contents, we just call `tag.expand`.

Page 110: Content Management That Won't Rot Your Brain

tag.render(“title”)

You can also directly invoke the rendering of another tag using `tag.render`. The result will be returned to you as a string.

Page 111: Content Management That Won't Rot Your Brain

tag.block

One neat trick is capture the contents of a container tag and reuse it in multiple places with `tag.block`.

Page 112: Content Management That Won't Rot Your Brain

<r:navigation urls=”Foo:/foo |Bar: /bar”>...</r:navigation>

The built-in `r:navigation` tag uses this to render navigation links depending on whether the current page matches the URL being output.

Page 113: Content Management That Won't Rot Your Brain

tag.locals.hash = {}tag.expand# ...

First, it sets up a hash that can be used inside nested tags, then renders its contents.

Page 114: Content Management That Won't Rot Your Brain

tag ‘navigation:here’ do |tag| tag.locals.hash[:here] = tag.blockend

The contained "navigation:here" tag assigns its block into the created hash.

Page 115: Content Management That Won't Rot Your Brain

# for each link...if url == page.url tag.locals.hash[:here].callend

Then the "navigation" tag calls the "here" block when the passed URL exactly matches the current page's URL. It uses the same technique to render prefix-matching and non-matching links by capturing blocks.

Page 116: Content Management That Won't Rot Your Brain

#2:Admin UI

So now that we can customize page output with tag definitions, let's look at the next big area of customization -- the admin UI.

Page 117: Content Management That Won't Rot Your Brain

class Widget < ActiveRecord::Base

Let's say you've built a model for widgets

Page 118: Content Management That Won't Rot Your Brain

<r:widgets />

and some Radius tags to display them in a page,

Page 119: Content Management That Won't Rot Your Brain

CRUD

and now you need to create an interface for CRUDing them.

Page 120: Content Management That Won't Rot Your Brain

map.resources :widgets

The first thing you might want to do, after creating your controller,

Page 121: Content Management That Won't Rot Your Brain

Add “Widgets” Tab

is to add a tab to the interface so your widgets are navigable.

Page 122: Content Management That Won't Rot Your Brain

Extension.admin

Radiant exposes an "admin" object to every extension that lets you tweak the interface

Page 123: Content Management That Won't Rot Your Brain

admin.tabs.add “Widgets”, “/admin/widgets”

and easily add tabs. As well as letting you simply add tabs,

Page 124: Content Management That Won't Rot Your Brain

:before => “Layouts”

you can also specify where they occur in the tab order

Page 125: Content Management That Won't Rot Your Brain

:visibility => [:admin]

and who can see them. But that's just a simple case of how to customize the UI.

Page 126: Content Management That Won't Rot Your Brain

a dash of spice

Often what you want to do is just add a little piece to one view or another.

Page 127: Content Management That Won't Rot Your Brain

widget list

Say you need to be able to see your widget list while editing a page.

Page 128: Content Management That Won't Rot Your Brain

fine-grained regions

Luckily, you can inject a view partial into any number of defined "regions" in the view template you want to modify, without overwriting the whole thing. This is enabled again through the admin object.

Page 129: Content Management That Won't Rot Your Brain

app/views/admin/pages/_widget_list.erb

To add our widget list, we just put it in the app/views/admin/pages directory,

Page 130: Content Management That Won't Rot Your Brain

admin.pages.edit.add :form_top, ‘widget_list’

and add it to the proper region like so. In this case, we’re adding it to the form_top region of the edit view for the pages controller.

Page 131: Content Management That Won't Rot Your Brain

include_stylesheet “widgets”include_javascript “widgets”

Inside your partial, in addition to simply rendering, you can add stylesheets and javascript files to the head block in the layout so you can make your widget list look awesome.

Page 132: Content Management That Won't Rot Your Brain

brute-force override

If you don't like the finessed approach, you can brute-force override any view template,

Page 133: Content Management That Won't Rot Your Brain

application.html.haml

including the default layout,

Page 134: Content Management That Won't Rot Your Brain

extensionsbefore core

by putting one of the same name in your extension, since extension view paths are searched before Radiant's built-in paths.

Page 135: Content Management That Won't Rot Your Brain

#3:front-end

So now you've got your admin interface doing cool things, but you want to provide a little more functionality on the front-end.

Page 136: Content Management That Won't Rot Your Brain

page rendering

Let's take a look at the process of how a page is rendered.

Page 137: Content Management That Won't Rot Your Brain

map.connect “*url”

First, any request URL that doesn't match an admin or extension controller gets sent to the splatted route

Page 138: Content Management That Won't Rot Your Brain

SiteController#show_page

assigned to SiteController.

Page 139: Content Management That Won't Rot Your Brain

request.get? orrequest.head?# read cache

If the request method is GET or HEAD, the controller checks whether the requested URL is cached, populating the response if it is.

Page 140: Content Management That Won't Rot Your Brain

show_uncached_page(url)

Otherwise, it tries to show an uncached version of the page.

Page 141: Content Management That Won't Rot Your Brain

@page = find_page(url)

The controller tries to find the page by the given URL,

Page 142: Content Management That Won't Rot Your Brain

process_page(@page)

and then processes it if found

Page 143: Content Management That Won't Rot Your Brain

@page.process(request, response)

calling page.process with the request and response

Page 144: Content Management That Won't Rot Your Brain

@cache.cache_response(url, response)

caching the response where appropriate.

Page 145: Content Management That Won't Rot Your Brain

render :template => “site/not_found”,:status => 404

If it's not found, you get the default 404 page,

Page 146: Content Management That Won't Rot Your Brain

redirect_to welcome_path

and if there's no pages at all in the database, you get redirected to the login screen.

Page 147: Content Management That Won't Rot Your Brain

SiteController#find_page

So within this process are a number of extension points to play with - `find_page`,

Page 148: Content Management That Won't Rot Your Brain

SiteController#process_page

`process_page`,

Page 149: Content Management That Won't Rot Your Brain

Page#process(req, resp)

and `Page#process`.

Page 150: Content Management That Won't Rot Your Brain

conversion SEO

Let's say that we have an old site that has some existing URLs that we want to preserve for a bit for SEO purposes.

Page 151: Content Management That Won't Rot Your Brain

choose a Page class

Since when we create a new page in the interface, Radiant lets us choose the page class we want,

Page 152: Content Management That Won't Rot Your Brain

redirect oldies

let's create a new Page class that performs a redirect from the old URL to our new location.

Page 153: Content Management That Won't Rot Your Brain

class RedirectPage < Page

So we'll choose to override the `process` method in our new subclass that we'll call `RedirectPage`.

Page 154: Content Management That Won't Rot Your Brain

page.part(:body).content == “/old/url”

We'll assume that we put the new URL in the 'body' part of the page,

Page 155: Content Management That Won't Rot Your Brain

301 Moved Permanently

and we'll want to consider this a permanent redirection.

Page 156: Content Management That Won't Rot Your Brain

def process(req, res) url = parse_object part(:body)

To accomplish this, inside we'll just render the body part to get our URL,

Page 157: Content Management That Won't Rot Your Brain

res.redirect url, “301 Moved Permanently”end

then cause the response to redirect.

Page 158: Content Management That Won't Rot Your Brain

def cache?; true; end

Believe it or not, a redirect can be cached!

Page 159: Content Management That Won't Rot Your Brain

5-minute cachewith headers

Radiant nicely captures the response headers and status when caching pages so, if we want to cache this, it won't have to call our process method again for 5 minutes after the first render.

Page 160: Content Management That Won't Rot Your Brain

GET HEAD cache

Now you may have noticed that when I walked through the SiteController workflow, it only checks for cached versions of a page on GET or HEAD requests.

Page 161: Content Management That Won't Rot Your Brain

POST PUT DELETEdon’t cache

This means that when a page receives POST, PUT, or DELETE, you can do cool stuff with the data in the request.

Page 162: Content Management That Won't Rot Your Brain

mailerdatabase_form

For example, the mailer and database_form extensions respectively process email forms and store data to the database on POST requests,

Page 163: Content Management That Won't Rot Your Brain

seamless experience

allowing a seamless front-end experience.

Page 164: Content Management That Won't Rot Your Brain

#4:I want my MVC

This is great and all, but sometimes you'd just rather use a controller and views instead of a page.

Page 165: Content Management That Won't Rot Your Brain

share_layouts

That's ok too, because there's a very popular extension called `share_layouts`.

Page 166: Content Management That Won't Rot Your Brain

ERb, Haml -> Radiant Layout

share_layouts lets you set a Layout, as in a Radiant Layout, within which your regular ERb or Haml view will render.

Page 167: Content Management That Won't Rot Your Brain

content_for :side

part(:side)

Captured content blocks - using `content_for` - become page-parts,

Page 168: Content Management That Won't Rot Your Brain

@content_for_layout

part(:body)

and the default content becomes the body part, all of which are rendered in your Radiant Layout via `r:content` tags.

Page 169: Content Management That Won't Rot Your Brain

@breadcrumbs@title

You can also set the breadcrumbs and title that will be rendered inside our phantom page.

Page 170: Content Management That Won't Rot Your Brain

MOAR contexthttp://icanhascheezburger.com/2007/02/23/moar/

And should that not be good enough, and you need even better context, say, for rendering localized navigation or an inherited sidebar,

Page 171: Content Management That Won't Rot Your Brain

endpoints

you can reify these phantom pages as "endpoints" in the page-tree,

Page 172: Content Management That Won't Rot Your Brain

“Application”page-type

placing an "Application" page at the root of your controller route.

Page 173: Content Management That Won't Rot Your Brain

/widgets

That is, if your controller sits at '/widgets',

Page 174: Content Management That Won't Rot Your Brain

“widgets” slug

you'd make a page as a child of the root page with the slug 'widgets'.

Page 175: Content Management That Won't Rot Your Brain

just a spoonful of sugar

And that's just a smidgen of how you can customize Radiant.

Page 176: Content Management That Won't Rot Your Brain

RadiantRailsRuby

Because it's built on Rails, nearly anything you can do with Ruby and Rails can be done inside Radiant extensions.

Page 177: Content Management That Won't Rot Your Brain

workflowlifecycle

You could play with the model workflow and lifecycle,

Page 178: Content Management That Won't Rot Your Brain

concurrent_draft(working copies)

like the `concurrent_draft` extension that enables working copies,

Page 179: Content Management That Won't Rot Your Brain

scheduler(timed publish)

or the `scheduler` extension that lets you specify dates for your pages to appear and disappear from the site.

Page 180: Content Management That Won't Rot Your Brain

multi_site(virtual hosts)

Or you could modify built-in models and controllers, like the `multi_site` extension that creates virtual hosts as multiple page-trees inside the same Radiant instance.

Page 181: Content Management That Won't Rot Your Brain

twitterthirty_boxes

You could integrate with a third-party web-service, like the `twitter` and `thirty-boxes` extensions.

Page 182: Content Management That Won't Rot Your Brain

file_systemDB <-> files

Or you could make design, development, and maintenance easier like the `file_system` extension, which serializes models into text files,

Page 183: Content Management That Won't Rot Your Brain

import_export(big YAML file)

or the `import_export` extension that dumps the whole database to a YAML file.

Page 184: Content Management That Won't Rot Your Brain

ext.radiantcms.orgAnd once you've completed your masterpiece, you can share it on the extension registry,

Page 185: Content Management That Won't Rot Your Brain

script/extension install

thereby enabling automatic installation scripts for your users.

Page 186: Content Management That Won't Rot Your Brain

The world is your oyster.

Page 187: Content Management That Won't Rot Your Brain

fin

I hope this has whet your appetite to use Radiant

Page 188: Content Management That Won't Rot Your Brain

<r:questions:ask />

do you have any questions?