Radicle
In botany, the radicle is the first part of a seedling (a growing plant embryo) to emerge from the seed during the process of germination. The radicle is the embryonic root of the plant, and grows downward in the soil.
In WordPress, it's an experimental MVC style theme that is just crazy enough to work.
Disclaimer
This theme was ported over from a production version that wasn't originally build with open-sourcing it in mind. It was made for a specific use case: a simple mobile theme for a WP Multisite install. It also contains some code to enable CDN assets to work correctly while using WP Total Cache.
The odds are very low that you'll be able to use this theme as is without modifications.
Theme Architecture
There are 3 files required by WordPress which must remain in the theme root: style.css
, functions.php
, and index.php
.
-
style.css
contains meta data about the theme that WordPress parses. No actual CSS should be included. -
index.php
is left blank and shouldn't be modified. -
functions.php
gets loaded before anything else. Right now this file just acts as a bootstrap to load all required files.
lib/init.php
is the next file to run. It performs a few WP theme configurations and sets up our views. See below for more.
Views
WordPress "templates" are always found in the theme root (without folder organization). We've worked around this limitation by hooking into the template_redirect
action and bypassing the default template hierarchy.
Our custom template loader is found in lib/init.php
. Add additional mappings as needed. Mappings just consist of a conditional tag function and a view file to load if true. Read ViewLoader class for documentation.
WP templates now act as a kind of Controller + View class. WordPress hits these files first, and their purpose is to load Model data and then render to an actual template.
View classes extend from the base View
class. To render a template, the view class only needs to implement the data function which returns anything to be passed down to the template.
The class needs to be instantiated and rendered. This isn't done automatically since there's no router.
Example of a View
<?php
class HomeView extends View {
protected function data() {
$blogs = get_last_updated_blogs();
return array('blogs' => $blogs);
}
}
$view = new HomeView();
$view->render('home.twig');
WP Query
Although this theme bypasses a lot of WordPress default functionality, it still leaves the complex stuff alone.
For the home page, we are doing manual SQL queries since we're displaying posts across all blogs.
However, for the individual blogs, we leave that up to WP_Query. WP_Query automatically queries your database for objects based on the request URL.
It will return posts, a single post, categories, comments, pages, etc. Here's an example of how to access WP_Query for a blog post in a view:
<?php
global $wp_query
$post = $wp_query->posts[0]
Models
Under the models
directory are models for a Blog
, Post
, Author
, Comment
and Thumbnail
. In order to get around WordPress Network Install (WPMU) constraints, there's some manual SQL queries are done in these files.
Currently, the models are plain classes that don't inherit from a parent Model class since they don't have much in common right now.
Templates
Templates are found in the templates
directory. They use a real templating language instead of PHP mixed in with HTML. Twig is used as the templating language. It's basically a PHP port of Jinja which Django uses.
These templates work just like any template/view would in MVC since they only have access to the data passed down to them. There's one big exception to this: all built-in WP functions are available through the wp
object to make our lives easier.
Assets
All assets (css, js, img) are under assets/
. To reference them in a template, use the asset_url
function. It takes a relative path to an asset: asset_url('css/app.css')
. An md5 hash of the file will be appended in a query parameter for caching purposes.
Multisite
This theme contains a lot of WPMU specific code. It assumes that there are multiple blogs being used. If you want to use this on a normal single blog setup, any code referencing blogs or blog ids will need to be removed.