death of a themer - frontend united - 14 april 2013

Post on 19-May-2015

1.754 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

"Death of a themer" was presented by James Panton and myself at Frontend United on 14th April 2013. This was a revised and extended talk of the same name presented by James at DrupalCamp London on 2nd March 2013. http://www.slideshare.net/therealmcjim/death-of-a-themer-drupal-camplondon2013 Themers are the magicians who transform what Drupal wants to do into what the designer wants it to do. They work alongside developers and site builders and are usually hammering out CSS files, overriding templates, writing theme functions and scratching their heads. The thing is — and whisper this if possible redundancy concerns you — we can bypass the themer entirely. With some simple configuration, a site builder can get Drupal to output exactly the semantic, lightweight markup that any modern front-end designer would be proud of. The designer can be left alone to write the most appropriate HTML, CSS and JS, while the site builder need only choose a couple of options when putting together content types, views and panels to make Drupal behave. A friendly developer may have to lend a hand every now and then, but that’s it. You can get rid of the themer altogether. This is an extended version of a session James did recently but will take a closer look at the tools and workflow we created and the design principles that initially drove us to this approach.

TRANSCRIPT

Hello, we’re James and Matt

@mcjim and @MattFielding

from Code Enigma

developer

site builder

themer

designer

developer

site builder

themer

designer

developer

site builder

themer (deceased)

designer

the life of a themer

overworked

the life of a themer

overworked angry

the life of a themer

overworked angry frustrated

the life of a themer

overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff overriding stuff

hap

pin

ess

time

the theming curve

Murder Investigation

developer

site builder

designer

whodunnit?

the developer?

whodunnit?

“...to be honest, I never really saw the themer.We worked on different floors.”

official statement

the designer?

whodunnit?

excluded

15 columns, why? arrgghh $£@^£$%

“...there was a clash between my personal design principles and practices and his methods”

official statement

what did he mean bydesign principlesand practices?

Text

they are guides for the way we approach problems and craft our methods

design principles

here are 3 to start us off

minimise waste

waste is any activity where no value is produced

use the best tools

pick the tools that fit your workflow

PreprocessorsSass - CSS preprocessingLess - similar to SassStylus - a good but less popular preprocessorSusy/Singularity/ZenGrids/GridSet - grid system generatorsCompass - add-on functionality for Sass like vertical rhythm, sprites, css3 etcBourbon - Similar to Compass much to their dismayToolkit - A few nice extras to have - https://github.com/Snugug/toolkitCSS FrameworksSMACSS - styleguide/framework for developing css that is both modular and scalableOOCSS - object oriented CSS - more strict than smacssStyleguide generationKSS - uses comments in files to generate a styleguide - http://warpspire.com/posts/kss/Typecast - quick way to generate styles for typeClarify - http://www.clarify.ioStyle-Sites - https://github.com/snugug/style-sitesBrowsersChrome - Supports Sass in the web inspector - needs sass debugging turned on Canary - Same as above but also supports source mapsSafari - can use the desktop web inspector on the remote iphone/ipad site

Static page generatorsHammer for Mac http://hammerformac.com/Middleman - a bit more complex - requires command line http://middlemanapp.com/CodeKit - http://incident57.com/codekit/index.phpMixture.io http://mixture.io/Serve - Riby gem https://github.com/gummesson/serveTesting Live ReloadGuard - command line tool, faster than live-reloadAdobe Edge Inspect - http://html.adobe.com/edge/inspect/Mixture.io - http://mixture.io/Virtual Box with Windows XP and snapshots with IE6, IE7, IE8Lots of devicesTypographytypecast - http://typecast.com/ - can preview fastColourKuler - https://kuler.adobe.com/Colour Lovers - http://www.colourlovers.com/Color Scheme Designer - http://colorschemedesigner.com/http://color.hailpixel.com/Static image prototypingInvisionApp - very slick - http://invisionapp.com/Shipment - nice dropbox integration - http://blog.shipmentapp.com/

Browser ExtentionsWeb Inspector - needs sass debugging turned on and experimental modeSpeed TracerYSlowAdobe edge InspectLive ReloadVisual design and layoutFireworks - for working out Photoshop - mainly for image manipulationInDesign - some very useful tools for wireframesIllustrator - creating SVG files and illustrationsUXPin - http://uxpin.com/Useful websites and guidesHTML5 Please - http://html5please.com/Javascript Compression Tool - http://jscompress.comCompass - http://compass-style.org/examples/compass/HTML 5 Outliner - http://gsnedders.html5.org/outliner/Fontello - Icon Font generator - http://fontello.com/http://responsivepx.com/http://css3gen.com/button-generator/Sharing and experimenting with codeDabblet - http://dabblet.com/JS Fiddle - http://jsfiddle.net/CodePen - http://codepen.io/Practical tipsStart with pens and paper

add – don’t remove

only include what we want and need

Text

design principles are used as guides to inform the decisions we make as designers – primarily the

practices we use to design

design practices

work with real content

content strategy and modeling should come before design

get to code quickly

doing so also minimises a lot of waste

design a process for each job

each project is different, so designa unique process for each

what happens if we follow these design principles and

practices

static html

pure and honest

these principles and practices can be applied by any

designer/frontend developer

what problems doesthis cause us?

traditional Drupal workflow

traditional Drupal workflow

traditional Drupal workflow

angry viking god themerdrowning in a sea of divs

“...there was a clash between my personal design principles and practices and his methods”

official statement

Murder Investigation

the site builder?

whodunnit?

“...I always got on really well with the themer. Hadn’t seen him much since he went on holiday, though.”

official statement

so, what happened when the themer went on holiday?

designer, site-builder and developer were left to cope

without a themer

developer and site-builder came up with a plan…

they knew the designer was frustrated and wanted to try

new methods of working

so, they let the designerdo what he wanted…

…and figured out a way of getting Drupal to output that without the help of a themer

theming without a themer

STEP ONE

the designer builtprototypes in HTML

designer handedHTML, CSS and JS

over to the site builder

CSS and JS wasplaced in the theme*

*can be created there in the first place

HTML was used asa markup guide

theming without a themer

STEP TWO

the developer setone or two things upfor the site builder

required code

a basic theme

base theme?

<div id="page-wrapper"><div id="page">

<div id="header"><div class="section clearfix">

<?php if ($logo): ?> <a href="<?php print $front_page; ?>" title="<?php print t('Home'); ?>" rel="home" id="logo"> <img src="<?php print $logo; ?>" alt="<?php print t('Home'); ?>" /> </a> <?php endif; ?>

<?php if ($site_name || $site_slogan): ?> <div id="name-and-slogan"> <?php if ($site_name): ?> <?php if ($title): ?> <div id="site-name"><strong> <a href="<?php print $front_page; ?>" title="<?php print t('Home'); ?>" rel="home"><span><?php print $site_name; ?></span></a> </strong></div> <?php else: /* Use h1 when the content title is empty */ ?> <h1 id="site-name"> <a href="<?php print $front_page; ?>" title="<?php print t('Home'); ?>" rel="home"><span><?php print $site_name; ?></span></a> </h1> <?php endif; ?> <?php endif; ?>

<?php if ($site_slogan): ?> <div id="site-slogan"><?php print $site_slogan; ?></div> <?php endif; ?> </div> <!-- /#name-and-slogan --> <?php endif; ?>

<?php print render($page['header']); ?>

</div></div> <!-- /.section, /#header -->

<?php if ($main_menu || $secondary_menu): ?> <div id="navigation"><div class="section"> <?php print theme('links__system_main_menu', array('links' => $main_menu, 'attributes' => array('id' => 'main-menu', 'class' => array('links', 'inline', 'clearfix')), 'heading' => t('Main menu'))); ?> <?php print theme('links__system_secondary_menu', array('links' => $secondary_menu, 'attributes' => array('id' => 'secondary-menu', 'class' => array('links', 'inline', 'clearfix')), 'heading' => t('Secondary menu'))); ?> </div></div> <!-- /.section, /#navigation --> <?php endif; ?>

<?php if ($breadcrumb): ?> <div id="breadcrumb"><?php print $breadcrumb; ?></div> <?php endif; ?>

<?php print $messages; ?>

<div id="main-wrapper"><div id="main" class="clearfix">

<div id="content" class="column"><div class="section"> <?php if ($page['highlighted']): ?><div id="highlighted"><?php print render($page['highlighted']); ?></div><?php endif; ?> <a id="main-content"></a> <?php print render($title_prefix); ?> <?php if ($title): ?><h1 class="title" id="page-title"><?php print $title; ?></h1><?php endif; ?> <?php print render($title_suffix); ?> <?php if ($tabs): ?><div class="tabs"><?php print render($tabs); ?></div><?php endif; ?> <?php print render($page['help']); ?> <?php if ($action_links): ?><ul class="action-links"><?php print render($action_links); ?></ul><?php endif; ?> <?php print render($page['content']); ?> <?php print $feed_icons; ?> </div></div> <!-- /.section, /#content -->

<?php if ($page['sidebar_first']): ?> <div id="sidebar-first" class="column sidebar"><div class="section"> <?php print render($page['sidebar_first']); ?> </div></div> <!-- /.section, /#sidebar-first --> <?php endif; ?>

<?php if ($page['sidebar_second']): ?> <div id="sidebar-second" class="column sidebar"><div class="section"> <?php print render($page['sidebar_second']); ?> </div></div> <!-- /.section, /#sidebar-second --> <?php endif; ?>

</div></div> <!-- /#main, /#main-wrapper -->

<div id="footer"><div class="section"> <?php print render($page['footer']); ?> </div></div> <!-- /.section, /#footer -->

</div></div> <!-- /#page, /#page-wrapper -->

<div id="page-wrapper"><div id="page"><div id="header"><div class="section clearfix"><?php if ($logo): ?><a href="<?php print $front_page;

?>" title="<?php print t('Home'); ?>" rel="home" id="logo"><img src="<?php print $logo; ?>" alt="<?php print t('Home'); ?>" /></a><?php

endif; ?><?php if ($site_name || $site_slogan): ?><div id="name-and-slogan"><?php if ($site_name): ?><?php if ($title): ?><div id="site-

name"><strong><a href="<?php print $front_page; ?>" title="<?php print t('Home'); ?>" rel="home"><span><?php print $site_name;

?></span></a></strong></div><?php else: /* Use h1 when the content title is empty */ ?><h1 id="site-name"><a href="<?php print

$front_page; ?>" title="<?php print t('Home'); ?>" rel="home"><span><?php print $site_name; ?></span></a></h1><?php endif; ?><?php

endif; ?><?php if ($site_slogan): ?><div id="site-slogan"><?php print $site_slogan; ?></div><?php endif; ?></div> <!-- /#name-and-slogan

--><?php endif; ?><?php print render($page['header']); ?></div></div> <!-- /.section, /#header --><?php if ($main_menu ||

$secondary_menu): ?><div id="navigation"><div class="section"><?php print theme('links__system_main_menu', array('links' => $main_menu,

'attributes' => array('id' => 'main-menu', 'class' => array('links', 'inline', 'clearfix')), 'heading' => t('Main menu'))); ?><?php print

theme('links__system_secondary_menu', array('links' => $secondary_menu, 'attributes' => array('id' => 'secondary-menu', 'class' =>

array('links', 'inline', 'clearfix')), 'heading' => t('Secondary menu'))); ?></div></div> <!-- /.section, /#navigation --><?php endif; ?

><?php if ($breadcrumb): ?><div id="breadcrumb"><?php print $breadcrumb; ?></div><?php endif; ?><?php print $messages; ?><div id="main-

wrapper"><div id="main" class="clearfix"><div id="content" class="column"><div class="section"><?php if ($page['highlighted']): ?><div

id="highlighted"><?php print render($page['highlighted']); ?></div><?php endif; ?><a id="main-content"></a><?php print

render($title_prefix); ?><?php if ($title): ?><h1 class="title" id="page-title"><?php print $title; ?></h1><?php endif; ?><?php print

render($title_suffix); ?><?php if ($tabs): ?><div class="tabs"><?php print render($tabs); ?></div><?php endif; ?><?php print

render($page['help']); ?><?php if ($action_links): ?><ul class="action-links"><?php print render($action_links); ?></ul><?php endif; ?><?

php print render($page['content']); ?><?php print $feed_icons; ?></div></div> <!-- /.section, /#content --><?php if

($page['sidebar_first']): ?><div id="sidebar-first" class="column sidebar"><div class="section"><?php print

render($page['sidebar_first']); ?></div></div> <!-- /.section, /#sidebar-first --><?php endif; ?><?php if ($page['sidebar_second']): ?

><div id="sidebar-second" class="column sidebar"><div class="section"><?php print render($page['sidebar_second']); ?></div></div>

<!-- /.section, /#sidebar-second --><?php endif; ?></div></div> <!-- /#main, /#main-wrapper --><div id="footer"><div class="section"><?php

print render($page['footer']); ?></div></div> <!-- /.section, /#footer --></div></div> <!-- /#page, /#page-wrapper -->

<?php

print $content;

<?php

print $content;

<div id="<?php print $block_html_id; ?>" class="<?php print $classes; ?>"<?php print $attributes; ?>> <?php print

render($title_prefix); ?><?php if ($block->subject): ?> <h2<?php print $title_attributes; ?>><?php print $block->subject ?></h2><?php

endif;?> <?php print render($title_suffix); ?> <div class="content"<?php print $content_attributes; ?>> <?php print $content ?>

</div></div><?php

print $content;

<?php

print $content;

<?php

print $content;

a panels layout or two

/** * Implements hook_ctools_plugin_api(). */function ce_panels_ctools_plugin_api($module, $api) { if ($module == 'panels' && $api == 'styles') { return array('version' => 2.0); } if ($module == 'page_manager' && $api == 'pages_default') { return array('version' => 1); } if ($module == "panels_mini" && $api == "panels_default") { return array("version" => "1"); }}

/** * Implements hook_ctools_plugin_directory() */function ce_panels_ctools_plugin_directory($module, $plugin) { if ($module == 'page_manager' || $module == 'panels' || $module == 'ctools') { return $plugin; }}

<?php/** * @file * Layout definition for Code Enigma one column layout. */

/** * Panel layout definition. */$plugin = array( 'title' => t('Code Enigma One Column'), 'category' => t('Code Enigma'), 'icon' => 'ce_one_column.png', 'theme' => 'ce_one_column', 'regions' => array( 'content' => t('Content'), ),);

<?php/** * @file * Layout template for Code Enigma one column layout. * * Regions: * - content */

if (isset($content['content'])) { print $content['content'];}

a method for turning off all supplied CSS and JS

/** * Implements hook_js_alter(). */function mytheme_js_alter(&$js) { if (user_is_anonymous()) { $path_to_theme = path_to_theme(); $allowed_js = array( 'settings', 'misc/jquery.js', 'sites/all/modules/contrib/google_analytics/googleanalytics.js', ); foreach ($js as $key => $script) { if (!is_numeric($key) && !in_array($key, $allowed_js) && strpos($key, $path_to_theme) === FALSE) { unset($js[$key]); } } }}

theming without a themer

STEP THREE

add a few modules

display suitesemantic views

panelspanels everywhere semantic panels*

*using a forked version atmhttp://drupal.org/sandbox/mcjim/1899120

display suite

control over fieldand node markup

<img width="120" height="289" alt="useful alt text, ta"

src="/files/my_image.jpg" />

<div class="field field-name-field-image field-type-image

field-label-hidden">

<div class="field-items">

<div class="field-item even">

<img width="120" height="289" alt="useful alt text, ta"

src="/files/my_image.jpg">

</div>

</div>

</div>

view modes

semantic views

panelspanels everywhere semantic panels

an interface for wrapping content with markup

CONTENT<MARKUP> </MARKUP>

CONTENT<MARKUP> </MARKUP>

doesn't panels addloads* of divs?

*seriously, loads

<?php/** * @file * Layout template for Code Enigma one column layout. * * Regions: * - content */

if (isset($content['content'])) { print $content['content'];}

what do we end up with?

a real example

some rules

never write a .tpl.php

never write a .tpl.phpunless you really have to

start by outputting no markup at all

add markup via the UI

think carefully about where you add your layout classes

use Features andzero-touch deployment

Murder Investigation

was it a team effort?

whodunnit?

whodunnit?

was it a team effort?

whodunnit?

project manager

the PM did it

what have we learnedfrom this sorry tale?

design driven

give higher priority to the frontend

let designers take advantage of the best tools to improve speed

and reduce waste

group design & frontend dev

team structure

traditional Drupal workflow

new Drupal workflow

new Drupal workflow

split team effort evenly in sprints – creates a closer

working relationship across team disciplines

open up opportunities for contractors from outside

of Drupal

consistency

remove a layer of complexity for

site builders

markup is managed in UI only

dictate

reverse traditional drupal working methods

take an uncompromising approach to your markup

don’t let Drupal tell you what it should be – you show it who’s

boss

thank you!

epilogue

what happened to the team?

the designer was happy

site builder had an easy life

sprints were productive

the themer SURVIVED and adopted a new identity as a frontend developer

which was a great fit for the team

there were trust issues with the PM so he moved on

the end

questions?

exit

@MattFielding@mcjim

top related