SlideShare a Scribd company logo
1 of 97
Rewriting the Drupal
theme layer
Carl Wiedemann
DrupalCamp Colorado • 2013-06-29
Hi!
c4rl
Carl Wiedemann
Rewriting the Drupal
theme layer
Theming: What's
happening in D8?
Theming: Why is what
is happening in D8
happening in D8?
A history of theming
to understand why
what is happening in
D8 happening in D8?
What/Why/How is
theming?
Theming?
??
This is not a
how-to session.
This is a
how-come? session.
how-come?
Where are we?
How did we get here?
Where are we going?
Act I.
commit c678127f72bc52ba992cd9eb8a8195473334daaa
Author: Kjartan Mannes <kjartan@2.no-reply.drupal.org>
Date: Fri May 19 11:20:58 2000 +0000
I got bored *G*
2000
./theme.inc
<?
global $user;
if (isset($user)) $cookie = explode(":", base64_decode($user));
if (isset($cookie[9])) include "themes/$cookie[9]/theme.class";
else include "themes/default/theme.class";
$theme = new Theme();
?>
./themes/jeroen/theme.class
<?
class Theme {
### color set #1:
var $bgcolor1 = "blue"; // background color
var $fgcolor1 = "red"; // table body color
var $hlcolor1 = "#AAAAAA"; // high-light color
### color set #2:
var $bgcolor2 = "#EEEEEE";
var $fgcolor2 = "#666699";
var $hlcolor2 = "#666699";
### color set #3:
var $bgcolor3 = "#EEEEEE";
var $fgcolor3 = "yellow";
var $hlcolor3 = "yellow";
######
# Syntax.......: header($title);
# Description..: a function to draw the page header.
function header($title) {
?>
<HTML>
<HEAD>
<TITLE><? include "config.inc"; echo $sitename; ?></TITLE>
<META NAME="description" CONTENT="drop.org">
<META NAME="keywords" CONTENT="drop, weblog, portal, community, news, article,
announcements, stories, story, computer, science, space, hype, cult, geek, nerd, foo, bar">
</HEAD>
<STYLE type="text/css">
<!--
BODY,TD,P,UL,LI,DIV,FORM,EM,BLOCKQUOTE { font-size: 8pt; font-family: verdana,helvetica,
arial; }
-->
</STYLE>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" ALINK="#CCCCCC" LINK="#444444" VLINK="#666666">
<TABLE BORDER="0" CELLPADDING="2" CELLSPACING="2">
commit e6998fd3225da8e1a3621168f3e55d78de0eb1b4
Author: Kjartan Mannes <kjartan@2.no-reply.drupal.org>
Date: Fri May 19 23:33:15 2000 +0000
Wheeeeee... I think I finally figured this out :P
<?PHP
# Natrak was here!
# Dries was here!
# Natra was here again!
include "functions.inc";
//...
commit 3a62885aef7aa410288760c20a834dbdce260ca7
Author: Jeroen Bensch <jeroen@44.no-reply.drupal.org>
Date: Mon May 22 10:05:10 2000 +0000
sigh
commit a0cb7b5503ce0e798d4ad898fffab80173d66f81
Author: Jeroen Bensch <jeroen@44.no-reply.drupal.org>
Date: Mon May 22 10:02:48 2000 +0000
testi-i-ing
commit 4e042672186634e93d6fd0eba4514a9a8eac61f3
Author: Jeroen Bensch <jeroen@44.no-reply.drupal.org>
Date: Mon May 22 10:01:22 2000 +0000
testing ... please
commit 65d0fcf50f370cc0ce59e620aa8183269e3be184
Author: Dries Buytaert <dries@buytaert.net>
Date: Mon May 22 10:31:36 2000 +0000
como'n, work
commit 2ce00a9d4548e94838ee276e698810c888e2e486
Author: Dries Buytaert <dries@buytaert.net>
Date: Mon May 22 10:20:17 2000 +0000
fdasfdas
commit d3d8c37d3c731a0f863929703df85f2ab88d1408
Author: Dries Buytaert <dries@buytaert.net>
Date: Mon May 22 10:18:58 2000 +0000
testing
<?
class Theme {
### color set #1:
var $bgcolor1 = "blue"; // background color
var $fgcolor1 = "red"; // table body color
var $hlcolor1 = "#AAAAAA"; // high-light color
### color set #2:
var $bgcolor2 = "#EEEEEE";
var $fgcolor2 = "#666699";
var $hlcolor2 = "#666699";
### color set #3:
var $bgcolor3 = "#EEEEEE";
var $fgcolor3 = "yellow";
var $hlcolor3 = "yellow";
######
# Syntax.......: header($title);
# Description..: a function to draw the page header.
function header($title) {
?>
<HTML>
<HEAD>
<TITLE><? include "config.inc"; echo $sitename; ?></TITLE>
<META NAME="description" CONTENT="drop.org">
<META NAME="keywords" CONTENT="drop, weblog, portal, community, news, article,
announcements, stories, story, computer, science, space, hype, cult, geek, nerd, foo, bar">
</HEAD>
<STYLE type="text/css">
<!--
BODY,TD,P,UL,LI,DIV,FORM,EM,BLOCKQUOTE { font-size: 8pt; font-family: verdana,helvetica,
arial; }
-->
</STYLE>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" ALINK="#CCCCCC" LINK="#444444" VLINK="#666666">
<TABLE BORDER="0" CELLPADDING="2" CELLSPACING="2">
In
Open
Source,
we tend
to guess.:)
commit 85594eb9a1f9355152d0008eb2875cb7fc71221d
Author: Jeroen Bensch <jeroen@44.no-reply.drupal.org>
Date: Sun Jun 4 12:20:44 2000 +0000
like this?
FEATURE :)
In 2000, there
existed an
overridable way of
generating markup via
PHP classes.
PROBLEM :(
Too much in a Theme
class. As Drupal
grows, so must a
Theme Class.
./index.php
<?PHP
$theme->header();
$theme->abstract($story);
$theme->footer();
// Our theme class needs methods for **all** of these.
Act II.
commit fc3d320d860acbe9e31a968b2ca09f4ffaf179d7
Author: Dries Buytaert <dries@buytaert.net>
Date: Mon Jan 1 12:00:09 2001 +0000
- fixed a few typoes in the documentation
2001
./includes/theme.inc
<?PHP
function theme_new_headlines($theme, $num = 10) {
global $user;
$content = "";
$result = db_query("SELECT id, subject FROM stories WHERE status = 2 ORDER BY id
DESC LIMIT $num");
while ($story = db_fetch_object($result)) $content .= "<LI><A HREF="discussion.
php?id=$story->id">". check_output($story->subject) ."</A></LI>n";
$content .= "<P ALIGN="right">[ <A HREF="search.php"><FONT COLOR="$theme-
>hlcolor2">more</FONT></A> ]</P>";
$theme->box("Latest headlines", $content);
}
<?php
class BaseTheme {
function links($links = array(), $status = 0, $node = 0) {
if ($status == 1)
$links = array_merge(theme_morelink($node), $links);
foreach ($links as $link) {
$_links[] = count($link) == 2 ? "<A HREF="$link[0]"><FONT COLOR="$theme-
>link">". t($link[1]) ."</FONT></A>" : t($link[0]);
}
if ($status == 2) return ($_links ? implode(" | ", $_links) : "");
else return ($_links ? "[ ". implode(" | ", $_links) ." ]" : "");
}
}
FEATURE :)
We have
default markup
in core. Themes only
override what they
need to.
<?php
/*********************************************************************
Theme: Marvin
Author: Dries Buytaert (Dries)
Email: dries@drop.org
Description: Classic theme, white, basic design with a fresh look.
Notes: Only supports blocks on the right.
*********************************************************************/
class Theme extends BaseTheme {
2002
commit 08b82913d44a79720211cf252100cf316400e7cd
Author: Dries Buytaert <dries@buytaert.net>
Date: Sun Jun 23 13:31:30 2002 +0000
- Added the theme_invoke() function from Moshe's
sandbox.
./includes/theme.inc
<?php
function theme_invoke() {
global $theme;
$args = func_get_args();
$function = array_shift($args);
if (method_exists($theme, $function)) {
return call_user_method_array($function, $theme, $args);
}
else {
return call_user_func_array($function, $args);
}
}
PROBLEM :(
Concatenating strings
in PHP to write
markup is not how
people want to write
markup.
Act III.
commit 8b6d92fc69beb41d1c8d652c3f22143c375dc55d
Author: Dries Buytaert <dries@buytaert.net>
Date: Mon Jan 20 21:00:31 2003 +0000
- Added a template driven theme.
2003
./themes/xtemplate.theme
<?php
class Theme_xtemplate extends BaseTheme {
// ...
function node($node, $main) {
// ...
$this->template->assign(array (
"title" => ucfirst($node->title),
"taxonomy" => $this->links($terms),
"author" => format_name($node),
"date" => format_date($node->created),
"content" => ($main && $node->teaser) ?
check_output($node->teaser) :
check_output($node->body)));
if ($links = link_node($node, $main)) {
$this->template->assign("links", $this->links($links));
}
$this->template->parse("node");
print $this->template->text("node");
$this->template->reset("node");
}
./themes/xtemplate.xtmpl
<!-- BEGIN: header -->
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.
org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>{name} - {slogan}</title>
<style type="text/css" media="all">
@import "themes/xtemplate/xtemplate.css";
</style>
</head>
<body>
<!-- END: header -->
<!-- ... -->
<!-- BEGIN: message -->
<div id="message">{message}</div>
<!-- END: message -->
<!-- BEGIN: node -->
<div id="node">
<div id="title">{title}</div>
<span id="author">Submitted by {author} on {date}.</span>
<span id="taxonomy">{taxonomy}</span>
<div id="content">{content}</div>
<div id="links">&raquo; {links}</div>
</div>
<!-- END: node -->
FEATURE :)
We have
template-based
markup in core.
PROBLEM :(
Xtemplate isn't very
intuitive, dynamic,
powerful, elegant ...
or popular.
2005
[drupal-devel] phptemplate in core?
Dries Buytaert dries at buytaert.net
Sun May 1 15:49:22 UTC 2005
Previous message: [drupal-devel] Talk with Rasmus
Next message: [drupal-devel] phptemplate in core?
Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Adrian et al,
here is what I'd like to see happen: get PHPTemplate in core. We'd
need to:
1. remove Xtemplate from core.
2. remove the Bluemarine theme from core (Xtemplate based).
3. remove the Pushbutton theme from core (Xtemplate based).
4. add PHPTemplate to core.
5. add a PHPTemplate-based theme to core.
...
[drupal-devel] phptemplate in core?
Adrian Rossouw adrian at bryght.com
Sun May 1 18:15:12 UTC 2005
Previous message: [drupal-devel] phptemplate in core?
Next message: [drupal-devel] phptemplate in core?
Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 01 May 2005, at 5:49 PM, Dries Buytaert wrote:
> - What needs to be done to get PHPTemplate in core? From what I can
> tell, PHPTemplate's engine-specific settings (eg. the primary and
> secondary links) need some work.
My plan was to get this done this weekend, but unfortunately I didn't
have the time for it this week.
...
commit e274f97c879bff059511472a4d14a3584941393e
Author: Dries Buytaert <dries@buytaert.net>
Date: Wed May 4 18:12:18 2005 +0000
- Removed the Xtemplate engine and added the
PHPTemplate engine.
- Converted the Bluemarine theme from XTemplate to
PHPTemplate.
- Moved the the Pushbutton theme and the Xtemplate
engine to the contributions repository.
./themes/engines/phptemplate/node.tpl.php
<div class="node<?php print ($sticky) ? " sticky" : ""; ?>">
<?php if ($page == 0): ?>
<h2><a href="<?php print $node_url ?>" title="<?php print $title ?>"><?php print
$title ?></a></h2>
<?php endif; ?>
<?php print $picture ?>
<div class="info"><?php print $submitted ?><span class="terms"><?php print $terms
?></span></div>
<div class="content">
<?php print $content ?>
</div>
<?php if ($links): ?>
<?php if ($picture): ?>
<br class='clear' />
<?php endif; ?>
<div class="links"><?php print $links ?></div>
<?php endif; ?>
</div>
./includes/theme.inc
<?php
function theme() {
global $theme, $theme_engine;
if (!$theme) {
// Initialize the enabled theme.
$theme = init_theme();
}
$args = func_get_args();
$function = array_shift($args);
if (($theme != '') && function_exists($theme .'_'. $function)) {
// call theme function
return call_user_func_array($theme .'_'. $function, $args);
}
elseif (($theme != '') && isset($theme_engine) && function_exists($theme_engine
.'_'. $function)) {
// call engine function
return call_user_func_array($theme_engine .'_'. $function, $args);
}
elseif (function_exists('theme_'. $function)){
// call Drupal function
return call_user_func_array('theme_'. $function, $args);
}
}
./themes/engines/phptemplate/phptemplate.
engine
<?php
function phptemplate_node($node, $main = 0, $page = 0) {
//...
$variables = array(
'title' => check_plain($node->title),
'node_url' => url('node/' . $node->nid),
'name' => format_name($node),
'date' => format_date($node->created),
'sticky' => $node->sticky,
'picture' => theme_get_setting('toggle_node_user_picture') ? theme
('user_picture', $node) : '',
'content' => ($main && $node->teaser) ? $node->teaser : $node->body,
'links' => $node->links ? theme('links', $node->links) : '',
'mission' => $mission,
'page' => $page,
/* Lastly , pass the actual node to allow more customization */
'node' => $node,
'main' => $main,
'page' => $page
);
// Display info only on certain node types.
if (theme_get_setting('toggle_node_info_' . $node->type)) {
$variables['submitted'] = t('Submitted by %a on %b.', array('%a' => format_name
($node), '%b' => format_date($node->created)));
}
return _phptemplate_callback('node', $variables, 'node-' . $node->type);
}
<?php
function _phptemplate_callback($hook, $variables = array(), $file = null) {
$variables = array_merge($variables, _phptemplate_default_variables($hook,
$variables));
// Allow specified variables to be overridden
if (function_exists('_phptemplate_variables')) {
$variables = array_merge($variables, _phptemplate_variables($hook, $variables));
}
if ($variables['template_file']) {
$file = $variables['template_file'];
}
if (function_exists('_phptemplate_' . $hook)) {
return call_user_func('_phptemplate_' . $hook, $variables, $file);
}
elseif (function_exists('_phptemplate_default')) {
return call_user_func('_phptemplate_default', $hook, $variables, $file);
}
}
<?php
function _phptemplate_default($hook, $variables, $file = null) {
if ($file && file_exists(path_to_theme() . "/$file.tpl.php")) {
$file = path_to_theme() . "/$file.tpl.php";
}
else {
if (file_exists(path_to_theme() . "/$hook.tpl.php")) {
$file = path_to_theme() . "/$hook.tpl.php";
}
else {
if (in_array($hook, array('node', 'block', 'box', 'comment'))) {
$file = "themes/engines/phptemplate/$hook.tpl.php";
}
else {
$variables['hook'] = $hook;
watchdog('error', 'PHPTemplate was instructed to override the ' . $hook . '
theme function, but no valid template file was found.');
$file = "themes/engines/phptemplate/default.tpl.php";
}
}
}
if ($file) {
extract($variables); // Extract the vars to local namespace
ob_start(); // Start output buffering
include($file); // Include the file
$contents = ob_get_contents(); // Get the contents of the buffer
ob_end_clean(); // End buffering and discard
return $contents; // Return the contents
}
}
FEATURES :)
Powerful templates.
Pluggable, atomic,
extensible. Variable
overrides.
Engine/theme/core
default markup. Wow!
PROBLEMS :(
Tooling isn't well
documented or
understood,
malperformant, flimsy
APIs.
2007
commit 5bbbf10ba84042b8576d67576d98922c0063c6d6
Author: Dries Buytaert <dries@buytaert.net>
Date: Fri Apr 6 13:27:23 2007 +0000
- Patch #130987 by merlinofchaos: added theme
registry for easier themability.
./includes/theme.inc
<?php
/**
* ...
* ENGINE_engine_variables(&$variables)
* This function should only be implemented by theme engines and is exists
* so that the theme engine can set necessary variables. It is commonly
* used to set global variables such as $directory and $is_front_page.
* ENGINE_engine_variables_HOOK(&$variables)
* This is the same as the previous function, but is called only per hook.
* ENGINE_variables_HOOK(&$variables)
* ENGINE_variables(&$variables)
* This is meant to be used by themes that utilize a theme engine; as it is
* good practice for these themes to use the theme engine's name for
* their functions so that they may share code. In PHPTemplate, these
* functions will appear in template.php
* THEME_variables_HOOK(&$variables)
* THEME_variables(&$variables)
* These functions are based upon the raw theme; they should primarily be
* used by themes that do not use an engine or by themes that need small
* changes to what has already been established in the theme engine version
* of the function.
*
* There are two special variables that these hooks can set:
* 'template_file' and 'template_files'. These will be merged together
* to form a list of 'suggested' alternate template files to use, in
* reverse order of priority. template_file will always be a higher
* priority than items in template_files. theme() will then look for these
* files, one at a time, and use the first one
* that exists.
* ...
*/
function theme() {
<?php
/**
* ...
* ENGINE_engine_preprocess(&$variables)
* This function should only be implemented by theme engines and is exists
* so that the theme engine can set necessary variables. It is commonly
* used to set global variables such as $directory and $is_front_page.
* ENGINE_engine_preprocess_HOOK(&$variables)
* This is the same as the previous function, but is called only per hook.
* ENGINE_preprocess_HOOK(&$variables)
* ENGINE_preprocess(&$variables)
* This is meant to be used by themes that utilize a theme engine; as it is
* good practice for these themes to use the theme engine's name for
* their functions so that they may share code. In PHPTemplate, these
* functions will appear in template.php
* THEME_preprocess_HOOK(&$variables)
* THEME_preprocess(&$variables)
* These functions are based upon the raw theme; they should primarily be
* used by themes that do not use an engine or by themes that need small
* changes to what has already been established in the theme engine version
* of the function.
* template_preprocess(&$variables)
* This function will only be called for theme functions registered by
* the named module. In general it is preferred to use the following
* function if possible, but it may not always be the case.
* template_preprocess_HOOK(&$variables)
* This is the same as the previous function, but is called only per hook.
*
* ...
*/
function theme() {
FEATURES :)
More variable
overrides, template
registry overrides.
PROBLEMS??
Act IV.
commit 2e8ca690ff471b1d6604226e8153f401b1827204
Author: Dries Buytaert <dries@buytaert.net>
Date: Tue Jan 27 00:22:27 2009 +0000
- Patch #351235 by dmitrig01, webchick, frando,
moshe weitzman, et al: hook_page_alter. Oh, behave.
2005
commit 7e1527ee61bc10b3765b95b9af8faaa2254da5a8
Author: Dries Buytaert <dries@buytaert.net>
Date: Fri Oct 7 06:11:12 2005 +0000
- Patch #29465: new form API by Adrian et al.
ALTER ALL
OF THE
THINGS
ALTER ALL
OF THE
THINGS
2007
<?php
/**
* Implementation of hook_elements().
*/
function system_elements() {
// Top level form
$type['form'] = array(
'#method' => 'post',
'#action' => request_uri(),
);
$type['page'] = array(
'#show_messages' => TRUE,
'#show_blocks' => TRUE,
'#theme' => 'page',
);
$type['list'] = array(
'#title' => '',
'#list_type' => 'ul',
'#attributes' => array(),
'#items' => array(),
);
// ...
FEATURES :)
Form structure is
abstracted for better
module extensibility.
<?php
/**
* Implementation of hook_elements().
*/
function system_elements() {
// Top level form
$type['form'] = array(
'#method' => 'post',
'#action' => request_uri(),
);
$type['page'] = array(
'#show_messages' => TRUE,
'#show_blocks' => TRUE,
'#theme' => 'page',
);
$type['list'] = array(
'#title' => '',
'#list_type' => 'ul',
'#attributes' => array(),
'#items' => array(),
);
// ...
2.0
http://drupal.org/node/134478#comment-538674
Posted by bjaspan on October 15, 2007 at 1:39pm
"menu callbacks ought to return
structured data, not rendered data"
<?php
// OLD
return theme('foo', $bar);
<?php
// NEW
return array(
'#theme' => 'foo',
'#bar' => $bar,
);
FEATURES :)
Page structure is
abstracted for better
extensibility.
PROBLEMS :(
Everything just
changed.
2009
hook_page_alter()
template_preprocess_foo()
template_preprocess()
template_process_foo()
template_process()
Templates can be overridden...
Preprocessors can be overridden...
Processors can be overridden...
Theme functions still exist...
PROBLEMS
PROBLEMS
PROBLEMS
PROBLEMS
PROBLEMS
PROBLEMS
PROBLEMS
PROBLEMS
PROBLEMS
PROBLEMS
let's fix the
problems
Act V.
commit ee2acd68cca6ecfb2a1f3436c6adb593659489a8
Author: Dries <dries@buytaert.net>
Date: Sat Nov 3 10:36:10 2012 -0700
Issue #1696786 by Fabianx, jenlampton, stevector,
steveoliver, jwilson3, amateescu, chx: Integrate Twig
into core: Implementation issue.
RAD
this was a lot
of work
the future?
http://drupal.org/node/1899454
Rewriting the Drupal
theme layer
Carl Wiedemann
DrupalCamp Colorado • 2013-06-29

More Related Content

What's hot

jQuery For Beginners - jQuery Conference 2009
jQuery For Beginners - jQuery Conference 2009jQuery For Beginners - jQuery Conference 2009
jQuery For Beginners - jQuery Conference 2009Ralph Whitbeck
 
JavaScript DOM Manipulations
JavaScript DOM ManipulationsJavaScript DOM Manipulations
JavaScript DOM ManipulationsYnon Perek
 
8 things to know about theming in drupal 8
8 things to know about theming in drupal 88 things to know about theming in drupal 8
8 things to know about theming in drupal 8Logan Farr
 
Building a Custom Theme in Drupal 8
Building a Custom Theme in Drupal 8Building a Custom Theme in Drupal 8
Building a Custom Theme in Drupal 8Anne Tomasevich
 
Porting Flashblock to Jetpack Platform (draft)
Porting Flashblock to Jetpack Platform (draft)Porting Flashblock to Jetpack Platform (draft)
Porting Flashblock to Jetpack Platform (draft)Thomas Bassetto
 
Drupal Javascript for developers
Drupal Javascript for developersDrupal Javascript for developers
Drupal Javascript for developersDream Production AG
 
PSD to a Drupal Theme (using a base theme)
PSD to a Drupal Theme (using a base theme)PSD to a Drupal Theme (using a base theme)
PSD to a Drupal Theme (using a base theme)kuydigital
 
Grok Drupal (7) Theming
Grok Drupal (7) ThemingGrok Drupal (7) Theming
Grok Drupal (7) ThemingPINGV
 
jQuery and_drupal
jQuery and_drupaljQuery and_drupal
jQuery and_drupalBlackCatWeb
 
Fronteers - Drupal 7 ux
Fronteers   - Drupal 7 uxFronteers   - Drupal 7 ux
Fronteers - Drupal 7 uxBojhan
 
Mojo – Simple REST Server
Mojo – Simple REST ServerMojo – Simple REST Server
Mojo – Simple REST Serverhendrikvb
 
Absolute Beginners Guide to Drupal
Absolute Beginners Guide to DrupalAbsolute Beginners Guide to Drupal
Absolute Beginners Guide to DrupalRod Martin
 
Drupal 8 introduction to theming
Drupal 8  introduction to themingDrupal 8  introduction to theming
Drupal 8 introduction to themingBrahampal Singh
 
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)Doris Chen
 
8 things I like about Datomic
8 things I like about Datomic8 things I like about Datomic
8 things I like about Datomicdatablend
 
Grok Drupal (7) Theming (presented at DrupalCon San Francisco)
Grok Drupal (7) Theming (presented at DrupalCon San Francisco)Grok Drupal (7) Theming (presented at DrupalCon San Francisco)
Grok Drupal (7) Theming (presented at DrupalCon San Francisco)Laura Scott
 
How browser engines work?
How browser engines work?How browser engines work?
How browser engines work?haricot
 

What's hot (20)

jQuery For Beginners - jQuery Conference 2009
jQuery For Beginners - jQuery Conference 2009jQuery For Beginners - jQuery Conference 2009
jQuery For Beginners - jQuery Conference 2009
 
JavaScript DOM Manipulations
JavaScript DOM ManipulationsJavaScript DOM Manipulations
JavaScript DOM Manipulations
 
Drupal by fire
Drupal by fireDrupal by fire
Drupal by fire
 
8 things to know about theming in drupal 8
8 things to know about theming in drupal 88 things to know about theming in drupal 8
8 things to know about theming in drupal 8
 
Building a Custom Theme in Drupal 8
Building a Custom Theme in Drupal 8Building a Custom Theme in Drupal 8
Building a Custom Theme in Drupal 8
 
Git Makes Me Angry Inside
Git Makes Me Angry InsideGit Makes Me Angry Inside
Git Makes Me Angry Inside
 
Porting Flashblock to Jetpack Platform (draft)
Porting Flashblock to Jetpack Platform (draft)Porting Flashblock to Jetpack Platform (draft)
Porting Flashblock to Jetpack Platform (draft)
 
Drupal Javascript for developers
Drupal Javascript for developersDrupal Javascript for developers
Drupal Javascript for developers
 
PSD to a Drupal Theme (using a base theme)
PSD to a Drupal Theme (using a base theme)PSD to a Drupal Theme (using a base theme)
PSD to a Drupal Theme (using a base theme)
 
Grok Drupal (7) Theming
Grok Drupal (7) ThemingGrok Drupal (7) Theming
Grok Drupal (7) Theming
 
jQuery and_drupal
jQuery and_drupaljQuery and_drupal
jQuery and_drupal
 
Fronteers - Drupal 7 ux
Fronteers   - Drupal 7 uxFronteers   - Drupal 7 ux
Fronteers - Drupal 7 ux
 
Mojo – Simple REST Server
Mojo – Simple REST ServerMojo – Simple REST Server
Mojo – Simple REST Server
 
Absolute Beginners Guide to Drupal
Absolute Beginners Guide to DrupalAbsolute Beginners Guide to Drupal
Absolute Beginners Guide to Drupal
 
Design to Theme @ CMSExpo
Design to Theme @ CMSExpoDesign to Theme @ CMSExpo
Design to Theme @ CMSExpo
 
Drupal 8 introduction to theming
Drupal 8  introduction to themingDrupal 8  introduction to theming
Drupal 8 introduction to theming
 
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
 
8 things I like about Datomic
8 things I like about Datomic8 things I like about Datomic
8 things I like about Datomic
 
Grok Drupal (7) Theming (presented at DrupalCon San Francisco)
Grok Drupal (7) Theming (presented at DrupalCon San Francisco)Grok Drupal (7) Theming (presented at DrupalCon San Francisco)
Grok Drupal (7) Theming (presented at DrupalCon San Francisco)
 
How browser engines work?
How browser engines work?How browser engines work?
How browser engines work?
 

Similar to Rewriting the Drupal Theme layer

PostgreSQL Open SV 2018
PostgreSQL Open SV 2018PostgreSQL Open SV 2018
PostgreSQL Open SV 2018artgillespie
 
D7 theming what's new - London
D7 theming what's new - LondonD7 theming what's new - London
D7 theming what's new - LondonMarek Sotak
 
Kenneth Truyers - Using Git as a NoSql database - Codemotion Milan 2018
Kenneth Truyers - Using Git as a NoSql database - Codemotion Milan 2018Kenneth Truyers - Using Git as a NoSql database - Codemotion Milan 2018
Kenneth Truyers - Using Git as a NoSql database - Codemotion Milan 2018Codemotion
 
NZYP Project Casestudy using SilverStripe CMS
NZYP Project Casestudy using SilverStripe CMSNZYP Project Casestudy using SilverStripe CMS
NZYP Project Casestudy using SilverStripe CMSCam Findlay
 
Intro to Theming Drupal, FOSSLC Summer Camp 2010
Intro to Theming Drupal, FOSSLC Summer Camp 2010Intro to Theming Drupal, FOSSLC Summer Camp 2010
Intro to Theming Drupal, FOSSLC Summer Camp 2010Emma Jane Hogbin Westby
 
Schema Design with MongoDB
Schema Design with MongoDBSchema Design with MongoDB
Schema Design with MongoDBrogerbodamer
 
Design Systems, Pattern Libraries & WordPress
Design Systems, Pattern Libraries & WordPressDesign Systems, Pattern Libraries & WordPress
Design Systems, Pattern Libraries & WordPressJesse James Arnold
 
[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018Adam Tomat
 
BreizhBeans - Web components
BreizhBeans - Web componentsBreizhBeans - Web components
BreizhBeans - Web componentsHoracio Gonzalez
 
Starting with MongoDB
Starting with MongoDBStarting with MongoDB
Starting with MongoDBDoThinger
 
When dynamic becomes static : the next step in web caching techniques
When dynamic becomes static : the next step in web caching techniquesWhen dynamic becomes static : the next step in web caching techniques
When dynamic becomes static : the next step in web caching techniquesWim Godden
 
Drupal Theme Development - DrupalCon Chicago 2011
Drupal Theme Development - DrupalCon Chicago 2011Drupal Theme Development - DrupalCon Chicago 2011
Drupal Theme Development - DrupalCon Chicago 2011Ryan Price
 
Beyond PHP - It's not (just) about the code
Beyond PHP - It's not (just) about the codeBeyond PHP - It's not (just) about the code
Beyond PHP - It's not (just) about the codeWim Godden
 
Advanced CSS Troubleshooting & Efficiency
Advanced CSS Troubleshooting & EfficiencyAdvanced CSS Troubleshooting & Efficiency
Advanced CSS Troubleshooting & EfficiencyDenise Jacobs
 
Iasi code camp 12 october 2013 shadow dom - mihai bîrsan
Iasi code camp 12 october 2013   shadow dom - mihai bîrsanIasi code camp 12 october 2013   shadow dom - mihai bîrsan
Iasi code camp 12 october 2013 shadow dom - mihai bîrsanCodecamp Romania
 
Intro to MongoDB and datamodeling
Intro to MongoDB and datamodeling Intro to MongoDB and datamodeling
Intro to MongoDB and datamodeling rogerbodamer
 
ETL for Pros: Getting Data Into MongoDB
ETL for Pros: Getting Data Into MongoDBETL for Pros: Getting Data Into MongoDB
ETL for Pros: Getting Data Into MongoDBMongoDB
 

Similar to Rewriting the Drupal Theme layer (20)

PostgreSQL Open SV 2018
PostgreSQL Open SV 2018PostgreSQL Open SV 2018
PostgreSQL Open SV 2018
 
D7 theming what's new - London
D7 theming what's new - LondonD7 theming what's new - London
D7 theming what's new - London
 
Kenneth Truyers - Using Git as a NoSql database - Codemotion Milan 2018
Kenneth Truyers - Using Git as a NoSql database - Codemotion Milan 2018Kenneth Truyers - Using Git as a NoSql database - Codemotion Milan 2018
Kenneth Truyers - Using Git as a NoSql database - Codemotion Milan 2018
 
NZYP Project Casestudy using SilverStripe CMS
NZYP Project Casestudy using SilverStripe CMSNZYP Project Casestudy using SilverStripe CMS
NZYP Project Casestudy using SilverStripe CMS
 
Intro to Theming Drupal, FOSSLC Summer Camp 2010
Intro to Theming Drupal, FOSSLC Summer Camp 2010Intro to Theming Drupal, FOSSLC Summer Camp 2010
Intro to Theming Drupal, FOSSLC Summer Camp 2010
 
jquery.ppt
jquery.pptjquery.ppt
jquery.ppt
 
Schema Design with MongoDB
Schema Design with MongoDBSchema Design with MongoDB
Schema Design with MongoDB
 
Design Systems, Pattern Libraries & WordPress
Design Systems, Pattern Libraries & WordPressDesign Systems, Pattern Libraries & WordPress
Design Systems, Pattern Libraries & WordPress
 
[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018
 
BreizhBeans - Web components
BreizhBeans - Web componentsBreizhBeans - Web components
BreizhBeans - Web components
 
Variations on a Theme
Variations on a ThemeVariations on a Theme
Variations on a Theme
 
Starting with MongoDB
Starting with MongoDBStarting with MongoDB
Starting with MongoDB
 
Please dont touch-3.6-jsday
Please dont touch-3.6-jsdayPlease dont touch-3.6-jsday
Please dont touch-3.6-jsday
 
When dynamic becomes static : the next step in web caching techniques
When dynamic becomes static : the next step in web caching techniquesWhen dynamic becomes static : the next step in web caching techniques
When dynamic becomes static : the next step in web caching techniques
 
Drupal Theme Development - DrupalCon Chicago 2011
Drupal Theme Development - DrupalCon Chicago 2011Drupal Theme Development - DrupalCon Chicago 2011
Drupal Theme Development - DrupalCon Chicago 2011
 
Beyond PHP - It's not (just) about the code
Beyond PHP - It's not (just) about the codeBeyond PHP - It's not (just) about the code
Beyond PHP - It's not (just) about the code
 
Advanced CSS Troubleshooting & Efficiency
Advanced CSS Troubleshooting & EfficiencyAdvanced CSS Troubleshooting & Efficiency
Advanced CSS Troubleshooting & Efficiency
 
Iasi code camp 12 october 2013 shadow dom - mihai bîrsan
Iasi code camp 12 october 2013   shadow dom - mihai bîrsanIasi code camp 12 october 2013   shadow dom - mihai bîrsan
Iasi code camp 12 october 2013 shadow dom - mihai bîrsan
 
Intro to MongoDB and datamodeling
Intro to MongoDB and datamodeling Intro to MongoDB and datamodeling
Intro to MongoDB and datamodeling
 
ETL for Pros: Getting Data Into MongoDB
ETL for Pros: Getting Data Into MongoDBETL for Pros: Getting Data Into MongoDB
ETL for Pros: Getting Data Into MongoDB
 

Recently uploaded

Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructureitnewsafrica
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...itnewsafrica
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxfnnc6jmgwh
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 

Recently uploaded (20)

Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 

Rewriting the Drupal Theme layer

  • 1. Rewriting the Drupal theme layer Carl Wiedemann DrupalCamp Colorado • 2013-06-29
  • 5. Theming: Why is what is happening in D8 happening in D8?
  • 6. A history of theming to understand why what is happening in D8 happening in D8?
  • 9. ??
  • 10. This is not a how-to session. This is a how-come? session.
  • 11. how-come? Where are we? How did we get here? Where are we going?
  • 12. Act I. commit c678127f72bc52ba992cd9eb8a8195473334daaa Author: Kjartan Mannes <kjartan@2.no-reply.drupal.org> Date: Fri May 19 11:20:58 2000 +0000 I got bored *G*
  • 13. 2000
  • 15. <? global $user; if (isset($user)) $cookie = explode(":", base64_decode($user)); if (isset($cookie[9])) include "themes/$cookie[9]/theme.class"; else include "themes/default/theme.class"; $theme = new Theme(); ?>
  • 17. <? class Theme { ### color set #1: var $bgcolor1 = "blue"; // background color var $fgcolor1 = "red"; // table body color var $hlcolor1 = "#AAAAAA"; // high-light color ### color set #2: var $bgcolor2 = "#EEEEEE"; var $fgcolor2 = "#666699"; var $hlcolor2 = "#666699"; ### color set #3: var $bgcolor3 = "#EEEEEE"; var $fgcolor3 = "yellow"; var $hlcolor3 = "yellow"; ###### # Syntax.......: header($title); # Description..: a function to draw the page header. function header($title) { ?> <HTML> <HEAD> <TITLE><? include "config.inc"; echo $sitename; ?></TITLE> <META NAME="description" CONTENT="drop.org"> <META NAME="keywords" CONTENT="drop, weblog, portal, community, news, article, announcements, stories, story, computer, science, space, hype, cult, geek, nerd, foo, bar"> </HEAD> <STYLE type="text/css"> <!-- BODY,TD,P,UL,LI,DIV,FORM,EM,BLOCKQUOTE { font-size: 8pt; font-family: verdana,helvetica, arial; } --> </STYLE> <BODY TEXT="#000000" BGCOLOR="#FFFFFF" ALINK="#CCCCCC" LINK="#444444" VLINK="#666666"> <TABLE BORDER="0" CELLPADDING="2" CELLSPACING="2">
  • 18. commit e6998fd3225da8e1a3621168f3e55d78de0eb1b4 Author: Kjartan Mannes <kjartan@2.no-reply.drupal.org> Date: Fri May 19 23:33:15 2000 +0000 Wheeeeee... I think I finally figured this out :P
  • 19. <?PHP # Natrak was here! # Dries was here! # Natra was here again! include "functions.inc"; //...
  • 20. commit 3a62885aef7aa410288760c20a834dbdce260ca7 Author: Jeroen Bensch <jeroen@44.no-reply.drupal.org> Date: Mon May 22 10:05:10 2000 +0000 sigh commit a0cb7b5503ce0e798d4ad898fffab80173d66f81 Author: Jeroen Bensch <jeroen@44.no-reply.drupal.org> Date: Mon May 22 10:02:48 2000 +0000 testi-i-ing commit 4e042672186634e93d6fd0eba4514a9a8eac61f3 Author: Jeroen Bensch <jeroen@44.no-reply.drupal.org> Date: Mon May 22 10:01:22 2000 +0000 testing ... please
  • 21. commit 65d0fcf50f370cc0ce59e620aa8183269e3be184 Author: Dries Buytaert <dries@buytaert.net> Date: Mon May 22 10:31:36 2000 +0000 como'n, work commit 2ce00a9d4548e94838ee276e698810c888e2e486 Author: Dries Buytaert <dries@buytaert.net> Date: Mon May 22 10:20:17 2000 +0000 fdasfdas commit d3d8c37d3c731a0f863929703df85f2ab88d1408 Author: Dries Buytaert <dries@buytaert.net> Date: Mon May 22 10:18:58 2000 +0000 testing
  • 22. <? class Theme { ### color set #1: var $bgcolor1 = "blue"; // background color var $fgcolor1 = "red"; // table body color var $hlcolor1 = "#AAAAAA"; // high-light color ### color set #2: var $bgcolor2 = "#EEEEEE"; var $fgcolor2 = "#666699"; var $hlcolor2 = "#666699"; ### color set #3: var $bgcolor3 = "#EEEEEE"; var $fgcolor3 = "yellow"; var $hlcolor3 = "yellow"; ###### # Syntax.......: header($title); # Description..: a function to draw the page header. function header($title) { ?> <HTML> <HEAD> <TITLE><? include "config.inc"; echo $sitename; ?></TITLE> <META NAME="description" CONTENT="drop.org"> <META NAME="keywords" CONTENT="drop, weblog, portal, community, news, article, announcements, stories, story, computer, science, space, hype, cult, geek, nerd, foo, bar"> </HEAD> <STYLE type="text/css"> <!-- BODY,TD,P,UL,LI,DIV,FORM,EM,BLOCKQUOTE { font-size: 8pt; font-family: verdana,helvetica, arial; } --> </STYLE> <BODY TEXT="#000000" BGCOLOR="#FFFFFF" ALINK="#CCCCCC" LINK="#444444" VLINK="#666666"> <TABLE BORDER="0" CELLPADDING="2" CELLSPACING="2">
  • 24. commit 85594eb9a1f9355152d0008eb2875cb7fc71221d Author: Jeroen Bensch <jeroen@44.no-reply.drupal.org> Date: Sun Jun 4 12:20:44 2000 +0000 like this?
  • 25.
  • 26. FEATURE :) In 2000, there existed an overridable way of generating markup via PHP classes.
  • 27. PROBLEM :( Too much in a Theme class. As Drupal grows, so must a Theme Class.
  • 30. Act II. commit fc3d320d860acbe9e31a968b2ca09f4ffaf179d7 Author: Dries Buytaert <dries@buytaert.net> Date: Mon Jan 1 12:00:09 2001 +0000 - fixed a few typoes in the documentation
  • 31. 2001
  • 33. <?PHP function theme_new_headlines($theme, $num = 10) { global $user; $content = ""; $result = db_query("SELECT id, subject FROM stories WHERE status = 2 ORDER BY id DESC LIMIT $num"); while ($story = db_fetch_object($result)) $content .= "<LI><A HREF="discussion. php?id=$story->id">". check_output($story->subject) ."</A></LI>n"; $content .= "<P ALIGN="right">[ <A HREF="search.php"><FONT COLOR="$theme- >hlcolor2">more</FONT></A> ]</P>"; $theme->box("Latest headlines", $content); }
  • 34. <?php class BaseTheme { function links($links = array(), $status = 0, $node = 0) { if ($status == 1) $links = array_merge(theme_morelink($node), $links); foreach ($links as $link) { $_links[] = count($link) == 2 ? "<A HREF="$link[0]"><FONT COLOR="$theme- >link">". t($link[1]) ."</FONT></A>" : t($link[0]); } if ($status == 2) return ($_links ? implode(" | ", $_links) : ""); else return ($_links ? "[ ". implode(" | ", $_links) ." ]" : ""); } }
  • 35. FEATURE :) We have default markup in core. Themes only override what they need to.
  • 36. <?php /********************************************************************* Theme: Marvin Author: Dries Buytaert (Dries) Email: dries@drop.org Description: Classic theme, white, basic design with a fresh look. Notes: Only supports blocks on the right. *********************************************************************/ class Theme extends BaseTheme {
  • 37. 2002
  • 38. commit 08b82913d44a79720211cf252100cf316400e7cd Author: Dries Buytaert <dries@buytaert.net> Date: Sun Jun 23 13:31:30 2002 +0000 - Added the theme_invoke() function from Moshe's sandbox.
  • 40. <?php function theme_invoke() { global $theme; $args = func_get_args(); $function = array_shift($args); if (method_exists($theme, $function)) { return call_user_method_array($function, $theme, $args); } else { return call_user_func_array($function, $args); } }
  • 41. PROBLEM :( Concatenating strings in PHP to write markup is not how people want to write markup.
  • 42. Act III. commit 8b6d92fc69beb41d1c8d652c3f22143c375dc55d Author: Dries Buytaert <dries@buytaert.net> Date: Mon Jan 20 21:00:31 2003 +0000 - Added a template driven theme.
  • 43. 2003
  • 45. <?php class Theme_xtemplate extends BaseTheme { // ... function node($node, $main) { // ... $this->template->assign(array ( "title" => ucfirst($node->title), "taxonomy" => $this->links($terms), "author" => format_name($node), "date" => format_date($node->created), "content" => ($main && $node->teaser) ? check_output($node->teaser) : check_output($node->body))); if ($links = link_node($node, $main)) { $this->template->assign("links", $this->links($links)); } $this->template->parse("node"); print $this->template->text("node"); $this->template->reset("node"); }
  • 47. <!-- BEGIN: header --> <?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3. org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> <head> <title>{name} - {slogan}</title> <style type="text/css" media="all"> @import "themes/xtemplate/xtemplate.css"; </style> </head> <body> <!-- END: header --> <!-- ... --> <!-- BEGIN: message --> <div id="message">{message}</div> <!-- END: message --> <!-- BEGIN: node --> <div id="node"> <div id="title">{title}</div> <span id="author">Submitted by {author} on {date}.</span> <span id="taxonomy">{taxonomy}</span> <div id="content">{content}</div> <div id="links">&raquo; {links}</div> </div> <!-- END: node -->
  • 49. PROBLEM :( Xtemplate isn't very intuitive, dynamic, powerful, elegant ... or popular.
  • 50. 2005
  • 51. [drupal-devel] phptemplate in core? Dries Buytaert dries at buytaert.net Sun May 1 15:49:22 UTC 2005 Previous message: [drupal-devel] Talk with Rasmus Next message: [drupal-devel] phptemplate in core? Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] Adrian et al, here is what I'd like to see happen: get PHPTemplate in core. We'd need to: 1. remove Xtemplate from core. 2. remove the Bluemarine theme from core (Xtemplate based). 3. remove the Pushbutton theme from core (Xtemplate based). 4. add PHPTemplate to core. 5. add a PHPTemplate-based theme to core. ...
  • 52. [drupal-devel] phptemplate in core? Adrian Rossouw adrian at bryght.com Sun May 1 18:15:12 UTC 2005 Previous message: [drupal-devel] phptemplate in core? Next message: [drupal-devel] phptemplate in core? Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 01 May 2005, at 5:49 PM, Dries Buytaert wrote: > - What needs to be done to get PHPTemplate in core? From what I can > tell, PHPTemplate's engine-specific settings (eg. the primary and > secondary links) need some work. My plan was to get this done this weekend, but unfortunately I didn't have the time for it this week. ...
  • 53. commit e274f97c879bff059511472a4d14a3584941393e Author: Dries Buytaert <dries@buytaert.net> Date: Wed May 4 18:12:18 2005 +0000 - Removed the Xtemplate engine and added the PHPTemplate engine. - Converted the Bluemarine theme from XTemplate to PHPTemplate. - Moved the the Pushbutton theme and the Xtemplate engine to the contributions repository.
  • 55. <div class="node<?php print ($sticky) ? " sticky" : ""; ?>"> <?php if ($page == 0): ?> <h2><a href="<?php print $node_url ?>" title="<?php print $title ?>"><?php print $title ?></a></h2> <?php endif; ?> <?php print $picture ?> <div class="info"><?php print $submitted ?><span class="terms"><?php print $terms ?></span></div> <div class="content"> <?php print $content ?> </div> <?php if ($links): ?> <?php if ($picture): ?> <br class='clear' /> <?php endif; ?> <div class="links"><?php print $links ?></div> <?php endif; ?> </div>
  • 57. <?php function theme() { global $theme, $theme_engine; if (!$theme) { // Initialize the enabled theme. $theme = init_theme(); } $args = func_get_args(); $function = array_shift($args); if (($theme != '') && function_exists($theme .'_'. $function)) { // call theme function return call_user_func_array($theme .'_'. $function, $args); } elseif (($theme != '') && isset($theme_engine) && function_exists($theme_engine .'_'. $function)) { // call engine function return call_user_func_array($theme_engine .'_'. $function, $args); } elseif (function_exists('theme_'. $function)){ // call Drupal function return call_user_func_array('theme_'. $function, $args); } }
  • 59. <?php function phptemplate_node($node, $main = 0, $page = 0) { //... $variables = array( 'title' => check_plain($node->title), 'node_url' => url('node/' . $node->nid), 'name' => format_name($node), 'date' => format_date($node->created), 'sticky' => $node->sticky, 'picture' => theme_get_setting('toggle_node_user_picture') ? theme ('user_picture', $node) : '', 'content' => ($main && $node->teaser) ? $node->teaser : $node->body, 'links' => $node->links ? theme('links', $node->links) : '', 'mission' => $mission, 'page' => $page, /* Lastly , pass the actual node to allow more customization */ 'node' => $node, 'main' => $main, 'page' => $page ); // Display info only on certain node types. if (theme_get_setting('toggle_node_info_' . $node->type)) { $variables['submitted'] = t('Submitted by %a on %b.', array('%a' => format_name ($node), '%b' => format_date($node->created))); } return _phptemplate_callback('node', $variables, 'node-' . $node->type); }
  • 60. <?php function _phptemplate_callback($hook, $variables = array(), $file = null) { $variables = array_merge($variables, _phptemplate_default_variables($hook, $variables)); // Allow specified variables to be overridden if (function_exists('_phptemplate_variables')) { $variables = array_merge($variables, _phptemplate_variables($hook, $variables)); } if ($variables['template_file']) { $file = $variables['template_file']; } if (function_exists('_phptemplate_' . $hook)) { return call_user_func('_phptemplate_' . $hook, $variables, $file); } elseif (function_exists('_phptemplate_default')) { return call_user_func('_phptemplate_default', $hook, $variables, $file); } }
  • 61. <?php function _phptemplate_default($hook, $variables, $file = null) { if ($file && file_exists(path_to_theme() . "/$file.tpl.php")) { $file = path_to_theme() . "/$file.tpl.php"; } else { if (file_exists(path_to_theme() . "/$hook.tpl.php")) { $file = path_to_theme() . "/$hook.tpl.php"; } else { if (in_array($hook, array('node', 'block', 'box', 'comment'))) { $file = "themes/engines/phptemplate/$hook.tpl.php"; } else { $variables['hook'] = $hook; watchdog('error', 'PHPTemplate was instructed to override the ' . $hook . ' theme function, but no valid template file was found.'); $file = "themes/engines/phptemplate/default.tpl.php"; } } } if ($file) { extract($variables); // Extract the vars to local namespace ob_start(); // Start output buffering include($file); // Include the file $contents = ob_get_contents(); // Get the contents of the buffer ob_end_clean(); // End buffering and discard return $contents; // Return the contents } }
  • 62.
  • 63. FEATURES :) Powerful templates. Pluggable, atomic, extensible. Variable overrides. Engine/theme/core default markup. Wow!
  • 64. PROBLEMS :( Tooling isn't well documented or understood, malperformant, flimsy APIs.
  • 65. 2007
  • 66. commit 5bbbf10ba84042b8576d67576d98922c0063c6d6 Author: Dries Buytaert <dries@buytaert.net> Date: Fri Apr 6 13:27:23 2007 +0000 - Patch #130987 by merlinofchaos: added theme registry for easier themability.
  • 68. <?php /** * ... * ENGINE_engine_variables(&$variables) * This function should only be implemented by theme engines and is exists * so that the theme engine can set necessary variables. It is commonly * used to set global variables such as $directory and $is_front_page. * ENGINE_engine_variables_HOOK(&$variables) * This is the same as the previous function, but is called only per hook. * ENGINE_variables_HOOK(&$variables) * ENGINE_variables(&$variables) * This is meant to be used by themes that utilize a theme engine; as it is * good practice for these themes to use the theme engine's name for * their functions so that they may share code. In PHPTemplate, these * functions will appear in template.php * THEME_variables_HOOK(&$variables) * THEME_variables(&$variables) * These functions are based upon the raw theme; they should primarily be * used by themes that do not use an engine or by themes that need small * changes to what has already been established in the theme engine version * of the function. * * There are two special variables that these hooks can set: * 'template_file' and 'template_files'. These will be merged together * to form a list of 'suggested' alternate template files to use, in * reverse order of priority. template_file will always be a higher * priority than items in template_files. theme() will then look for these * files, one at a time, and use the first one * that exists. * ... */ function theme() {
  • 69. <?php /** * ... * ENGINE_engine_preprocess(&$variables) * This function should only be implemented by theme engines and is exists * so that the theme engine can set necessary variables. It is commonly * used to set global variables such as $directory and $is_front_page. * ENGINE_engine_preprocess_HOOK(&$variables) * This is the same as the previous function, but is called only per hook. * ENGINE_preprocess_HOOK(&$variables) * ENGINE_preprocess(&$variables) * This is meant to be used by themes that utilize a theme engine; as it is * good practice for these themes to use the theme engine's name for * their functions so that they may share code. In PHPTemplate, these * functions will appear in template.php * THEME_preprocess_HOOK(&$variables) * THEME_preprocess(&$variables) * These functions are based upon the raw theme; they should primarily be * used by themes that do not use an engine or by themes that need small * changes to what has already been established in the theme engine version * of the function. * template_preprocess(&$variables) * This function will only be called for theme functions registered by * the named module. In general it is preferred to use the following * function if possible, but it may not always be the case. * template_preprocess_HOOK(&$variables) * This is the same as the previous function, but is called only per hook. * * ... */ function theme() {
  • 70. FEATURES :) More variable overrides, template registry overrides.
  • 72. Act IV. commit 2e8ca690ff471b1d6604226e8153f401b1827204 Author: Dries Buytaert <dries@buytaert.net> Date: Tue Jan 27 00:22:27 2009 +0000 - Patch #351235 by dmitrig01, webchick, frando, moshe weitzman, et al: hook_page_alter. Oh, behave.
  • 73. 2005
  • 74. commit 7e1527ee61bc10b3765b95b9af8faaa2254da5a8 Author: Dries Buytaert <dries@buytaert.net> Date: Fri Oct 7 06:11:12 2005 +0000 - Patch #29465: new form API by Adrian et al.
  • 75. ALTER ALL OF THE THINGS ALTER ALL OF THE THINGS
  • 76. 2007
  • 77. <?php /** * Implementation of hook_elements(). */ function system_elements() { // Top level form $type['form'] = array( '#method' => 'post', '#action' => request_uri(), ); $type['page'] = array( '#show_messages' => TRUE, '#show_blocks' => TRUE, '#theme' => 'page', ); $type['list'] = array( '#title' => '', '#list_type' => 'ul', '#attributes' => array(), '#items' => array(), ); // ...
  • 78. FEATURES :) Form structure is abstracted for better module extensibility.
  • 79. <?php /** * Implementation of hook_elements(). */ function system_elements() { // Top level form $type['form'] = array( '#method' => 'post', '#action' => request_uri(), ); $type['page'] = array( '#show_messages' => TRUE, '#show_blocks' => TRUE, '#theme' => 'page', ); $type['list'] = array( '#title' => '', '#list_type' => 'ul', '#attributes' => array(), '#items' => array(), ); // ...
  • 80. 2.0
  • 81. http://drupal.org/node/134478#comment-538674 Posted by bjaspan on October 15, 2007 at 1:39pm "menu callbacks ought to return structured data, not rendered data"
  • 82. <?php // OLD return theme('foo', $bar); <?php // NEW return array( '#theme' => 'foo', '#bar' => $bar, );
  • 83. FEATURES :) Page structure is abstracted for better extensibility.
  • 85. 2009
  • 86. hook_page_alter() template_preprocess_foo() template_preprocess() template_process_foo() template_process() Templates can be overridden... Preprocessors can be overridden... Processors can be overridden... Theme functions still exist...
  • 87.
  • 88.
  • 89.
  • 92. Act V. commit ee2acd68cca6ecfb2a1f3436c6adb593659489a8 Author: Dries <dries@buytaert.net> Date: Sat Nov 3 10:36:10 2012 -0700 Issue #1696786 by Fabianx, jenlampton, stevector, steveoliver, jwilson3, amateescu, chx: Integrate Twig into core: Implementation issue.
  • 93.
  • 94. RAD
  • 95. this was a lot of work
  • 97. Rewriting the Drupal theme layer Carl Wiedemann DrupalCamp Colorado • 2013-06-29