This document describes how a flexible site structure was implemented for the T3 magazine website using CakePHP. Key elements of the structure included:
- Storing the site structure and content in the database using a Tree behavior to define parent-child relationships
- Different types of "site objects" like pages, content boxes, lists, articles that could be organized and re-used
- Associating site objects with template elements to determine how each piece of content should be displayed
- Updating caching efficiently whenever content changed to ensure fast publishing of new articles
The approach provided a flexible, database-driven structure that could handle different page layouts and allowed non-technical editors to easily manage content.
5. T3
Future Publishing
• A popular title on Zino - an online
publishing platform
www.zinio.com
• Also a popular UK website
destination for gadget fans
www.t3.com
6. T3
Future Publishing
• Flagship brand for Future Publishing
• T3 Awards being an important part
of the UK calendar
• Many competitors - online, blogs
such as Engadget and Gizmodo
• Quick-to-publish vital on gadget
websites
7. T3 - Just use Drupal or Wordpress!
• Many Future websites now in Drupal or
Wordpress
www.pcgamer.com
www.netmagazine.com
• Pressflow (a distribution of Drupal) is an
excellent platform for publishing
websites
pressflow.org
• Drupal and Pressflow with Varnish scales
www.varnish-cache.org
8. T3 - Just use Drupal or Wordpress?
• No need to build another CMS?
• But the site editors had unique
requirements for their workflow
9. Editable custom content boxes
Popular list features need to
be fast and easy to create
Easy to update trending and ticker
11. Flexible site structure
• Obviously, articles, galleries, other
lists of content are stored in
database
• We also stored the site structure in
the database using the Tree
behaviour.
13. Elements
Model:
CREATE TABLE elements (
! id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
! name VARCHAR(255) DEFAULT '',
! PRIMARY KEY (id)
);
Name field, just the filename of a
CakePHP element
<div>
<h3>Latest</h3>
<ul>
<li><a href="/news/iphone5red">iPhone 5 actually Red</a></li>
<li><a href="/news/iphone5blue">iPhone 5 to Blue</a></li>
</ul>
[children]
14. SiteObject Element
id: 1 id: 1
name: Latest smartphone news name: content_boxes/list.ctp
type: ContentBox
element_id: 1
content_id: 50
SiteObject
id: 50
name: Latest smartphone news list
type: List
SiteObject Article
id: 51 id: 1
type: List name: Black Samsung
parent_id: 50 Galaxy S3 coming soon
article_id: 1
SiteObject Article
id: 52 id: 2
type: List name: Motorola RAZAR Ice
parent_id: 50 Cream Sandwich update out
article_id: 2 now
SiteObject Article
id: 53 id: 3
type: List name: Supposed Apple
parent_id: 50 iPhone 5 motherboard hints
article_id: 3 at features
17. So what about the structure?
All page elements were grouped together
as different types of “site object”
CREATE TABLE site_objects (
! id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
! parent_id INTEGER(10) UNSIGNED DEFAULT NULL,
! lft INTEGER(10) UNSIGNED DEFAULT NULL,
! rght INTEGER(10) UNSIGNED DEFAULT NULL,
! name VARCHAR(255) DEFAULT '',!
! page_id INTEGER(10) UNSIGNED DEFAULT NULL,
! article_id INTEGER(10) UNSIGNED DEFAULT NULL,
! element_id INTEGER(10) UNSIGNED DEFAULT NULL,
! content_id INTEGER(10) UNSIGNED DEFAULT NULL,
! PRIMARY KEY (id)
);
Page
CREATE TABLE pages (
! id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
! name VARCHAR(255) DEFAULT '',!
! title VARCHAR(255) DEFAULT '',!
! meta_description TEXT DEFAULT
! meta_keywords TEXT DEFAULT NULL,
! name VARCHAR(255) DEFAULT '',!
! url VARCHAR(255) DEFAULT '',!
! PRIMARY KEY (id)
);
18. URLs
• The structure of each “Page” or URL
was defined in a tree
• /news takes you to the page
structure for news articles
• /news/new-iphone5-released takes
you to the page structure associated
with the new articles that has the
slug “new-iphone5-released”
allowing different layouts for
articles from trades shows
19. Content?
• element_id field contains a reference to
the element that should be used to
display this content
• content_id field in SiteObject refers to
another SiteObject which contains
information about where to find the
content
• That content could be a list of articles,
images, a carousel... anything that the site
supports
20. Content?
• Backend process updates lists periodically
• Key lists such as the homepage lists of
articles are updated whenever articles
change
• Allows easy updating of caching. See:
andy-gale.com/positive-cache-clearing-with-cakephp.html
21. Caching!!!!!!
• Caching vital when implementing a
site using this methodology
• Structure and content both
SiteObjects can be cached in the
same way
• Caching need to be updated fast to
ensure new articles were published
as soon as possible
22. Caching
CMS
Cache update sent as a
topic via STOMP protocol
ActiveMQ Multiple clients can
subscribe to a topic so
all web servers that are
listening can update
their cache immediately
and serve new content
Web server Web server Web server
23. CSS, elements and flexible
Structure
• Consistent CSS style guide for each
component vital for implementing a
flexible site structure
• Elements should work wherever
they are placed
• Twitter Bootstrap is a great example
twitter.github.com/bootstrap/
24. Flexible site structure with CakePHP
• Code to be released on my GitHub
page shortly:
github.com/salgo/
• Avoiding Surprises with Chef and
Vagrant
Attend if you’ve ever had problems
with configuration or anything else
when putting sites live
25. Flexible site structure with CakePHP
• Questions?
• @andygale on Twitter
• andy-gale.com on the Web