Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Cleaner Themes: A Persil.co.uk Case Study

Cleaner Themes: A Persil.co.uk Case Study

Persil may say “Dirt is Good”, but when it comes to WordPress themes you want to make sure they're as clean as possible, especially when you're building a global network of websites for one of the world's leading washing detergent brands. This case study will take a close look inside the theme and front end code powering the Persil.co.uk website and it's international counterparts.

Using WordPress Multisite, some select plugins, parent and child theming, as well as custom plugins, Sass, and Compass we were able to tackle problems such as: internationalisation, complex page content, and lots of Ajax interactivity. All the while making sure the sites would be easily updatable and extensible by the local content teams, good for SEO, and easily customised for each market.

Adam Onishi

April 29, 2014
Tweet

More Decks by Adam Onishi

Other Decks in Technology

Transcript

  1. @onishiweb
    Cleaner Themes
    Persil Case Study

    View Slide

  2. @onishiweb

    View Slide

  3. @onishiweb

    View Slide

  4. @onishiweb
    2 to
    give away

    View Slide

  5. @onishiweb

    View Slide

  6. @onishiweb
    Code Examples

    View Slide

  7. @onishiweb
    Beginner / Expert

    View Slide

  8. @onishiweb
    The project

    View Slide

  9. @onishiweb
    The project:
    ‣ WordPress backend
    ‣ 35+ Markets Worldwide
    ‣ Multi-language support
    ‣ Customisable per market - features, styling, etc
    ‣ Manageable by local teams
    ‣ Integrate with external campaigns

    View Slide

  10. @onishiweb
    The solution...
    ‣ Work with a team of developers
    ‣ Modify styles/functionality on a per-site basis
    ‣ Managed through a simple codebase
    ‣ Easy to keep up to date and easy to deploy
    ‣ Extendible when necessary

    View Slide

  11. @onishiweb
    Tools

    View Slide

  12. ‣ Multisite
    ‣ Parent/Child Themes
    ‣ Git
    ‣ Frontend Tools - Sass/Compass/Grunt
    ‣ Plugins
    @onishiweb
    Tools

    View Slide

  13. @onishiweb
    Multisite

    View Slide

  14. @onishiweb
    Centrally managed
    system

    View Slide

  15. @onishiweb
    Easily create new sites

    View Slide

  16. @onishiweb
    Got a bit messed up...

    View Slide

  17. @onishiweb
    Parent/Child Themes

    View Slide

  18. @onishiweb
    1 core parent theme

    View Slide

  19. @onishiweb
    Child themes
    https://codex.wordpress.org/Child_Themes

    View Slide

  20. ‣ Functions file
    ‣ Pluggable functions
    ‣ Post type & taxonomy slugs
    ‣ Mail settings
    @onishiweb
    Child theme config

    View Slide

  21. if( ! function_exists('dig_mail_from_address') ) :
    function dig_mail_from_address( $old ) {
    return '[email protected]';
    }
    endif;
    add_filter('wp_mail_from', 'dig_mail_from_address');
    @onishiweb

    View Slide

  22. function dig_mail_from_address( $old ) {
    return '[email protected]';
    }
    @onishiweb

    View Slide

  23. @onishiweb
    Always child theme!

    View Slide

  24. @onishiweb
    Git

    View Slide

  25. @onishiweb
    USE IT!
    http://git-scm.com/book/en/Getting-Started
    http://gitimmersion.com/
    http://alistapart.com/article/get-started-with-git

    View Slide

  26. @onishiweb
    A successful Git branching model
    http://nvie.com/posts/a-successful-git-branching-model/

    View Slide

  27. @onishiweb
    Frontend Tools

    View Slide

  28. @onishiweb
    Sass/Compass

    View Slide

  29. @onishiweb
    Sass & Compass benefits
    ‣ Easier to work in collaboration
    ‣ More modular way of writing styles
    ‣ Makes working with child themes a breeze
    ‣ Good for performance
    ‣ Easily modify base styles

    View Slide

  30. @onishiweb

    View Slide

  31. @onishiweb

    View Slide

  32. @onishiweb
    Grunt

    View Slide

  33. ‣ JSHint
    ‣ Concatenation
    ‣ Minification
    ‣ Image optimisation
    ‣ Compass compliation
    @onishiweb
    Grunt tasks

    View Slide

  34. @onishiweb
    Icon Fonts

    View Slide

  35. @onishiweb
    http://fontastic.me/

    View Slide

  36. @onishiweb
    Plugins

    View Slide

  37. @onishiweb
    Advanced Custom Fields
    http://www.advancedcustomfields.com/

    View Slide

  38. ‣ Repeater Field
    ‣ Options Pages
    ‣ Flexible Content Field
    @onishiweb
    ACF Add-ons

    View Slide

  39. @onishiweb
    WordPress Multilingual
    http://wpml.org/
    http://translate-toolkit.readthedocs.org/en/latest/commands/csv2po.html

    View Slide

  40. @onishiweb
    WordPress SEO (Yoast)
    https://wordpress.org/plugins/wordpress-seo/

    View Slide

  41. @onishiweb
    WordPress Social Login
    http://wordpress.org/plugins/wordpress-social-login/

    View Slide

  42. @onishiweb
    Content

    View Slide

  43. @onishiweb
    Custom Post Types

    View Slide

  44. @onishiweb
    5 main
    3 supporting

    View Slide

  45. @onishiweb
    Custom Taxonomies

    View Slide

  46. @onishiweb

    View Slide

  47. @onishiweb
    Configured per market

    View Slide

  48. $count = 1;
    foreach( $tax_labels as $slug => $labels ) {
    $args = array(
    'hierarchical' => true,
    'labels' => $labels,
    'show_ui' => true,
    'show_admin_column' => true,
    'query_var' => true,
    'rewrite' => array( 'slug' => $slug ),
    );
    register_taxonomy( 'dig_product_filter_' . $count, 'dig_product', $args );
    $count++;
    }
    @onishiweb

    View Slide

  49. @onishiweb
    Custom Fields

    View Slide

  50. @onishiweb
    ACF...

    View Slide

  51. @onishiweb
    Modular content
    made easy

    View Slide

  52. @onishiweb

    View Slide

  53. @onishiweb
    $75!

    View Slide

  54. @onishiweb
    $75 AUD!

    View Slide

  55. @onishiweb
    The Theme

    View Slide

  56. @onishiweb
    Theme organisation

    View Slide

  57. @onishiweb
    Folders are your friend!

    View Slide

  58. /css
    /javascript
    /inc
    /inc/admin
    /inc/template-tags
    /templates
    /template-parts
    @onishiweb

    View Slide

  59. @onishiweb
    The template hierarchy
    extends into subdirectories
    http://nacin.com/2012/03/29/page-templates-in-subdirectories-new-in-wordpress-3-4/

    View Slide

  60. // For /pages/page-contact.php

    // Will return ‘pages/page-contact.php’
    @onishiweb

    View Slide

  61. @onishiweb
    Templating

    View Slide

  62. @onishiweb
    Template parts

    View Slide

  63. // Explicit
    get_template_part('template-parts/content', 'page');
    // Dynamic
    get_template_part('template-parts/loop', dig_current_post_type());
    ?>
    @onishiweb

    View Slide

  64. @onishiweb
    Separating logic from
    templates

    View Slide

  65. @onishiweb

    View Slide

  66. @onishiweb
    Custom template tags

    View Slide

  67. if( ! function_exists( 'dig_get_post_type_title' ) ) :
    function dig_get_post_type_title() {
    if( is_tag() ) {
    $query = get_queried_object();
    return __('Topic: ', 'dirtisgood') . $query->name;
    }
    $type_name = dig_current_post_type();
    if( '' !== $type_name ) {
    $post_type = get_post_type_object( $type_name );
    return $post_type->labels->name;
    }
    }
    endif;
    @onishiweb

    View Slide

  68. @onishiweb
    Custom templates

    View Slide

  69. @onishiweb
    Best for i18n -
    no more page-xxxx.php

    View Slide

  70. @onishiweb
    Ajax

    View Slide

  71. @onishiweb
    admin-ajax.php
    http://www.smashingmagazine.com/2011/10/18/how-to-use-ajax-in-wordpress/

    View Slide

  72. // Set up Nonce in the arguments
    args.nonce = coreData.ajaxData.postUserNonce;
    // Run ajax call
    $.ajax({
    type: 'POST',
    dataType: 'json',
    url: coreData.ajaxData.ajaxurl,
    data: args,
    success: callback
    });
    @onishiweb

    View Slide

  73. <br/>/* <![CDATA[ */<br/>var coreData = {"ajaxData":{"ajaxurl":"http:\/\/<br/>www.persil.co.uk\/wp-admin\/admin-<br/>ajax.php","postUserNonce":"d11736ec4f"}};<br/>/* ]]> */<br/>
    @onishiweb

    View Slide

  74. wp_enqueue_script( 'core', $javascript_file, 'jquery', '1.1.1',
    true );
    $ajaxData = array(
    'ajaxurl' => admin_url('admin-ajax.php' ),
    'postUserNonce' => wp_create_nonce( 'ajax-users-nonce' ),
    );
    wp_localize_script( 'core', 'coreData', $ajaxData );
    @onishiweb

    View Slide

  75. add_action('wp_ajax_sort_filter_articles',
    'dig_ajax_process_archive');
    add_action('wp_ajax_nopriv_sort_filter_articles',
    'dig_ajax_process_archive');
    @onishiweb

    View Slide

  76. // Set up and send the response
    $response = json_encode(array(
    'results' => true,
    'pages' => $pages,
    'data' => $data,
    ));
    die( $response );
    @onishiweb

    View Slide

  77. @onishiweb
    I18n and L10n

    View Slide

  78. $labels = array(
    'name' => __('Laundry Products', 'dirtisgood'),
    'singular_name' => __('Product', 'dirtisgood'),
    [...]
    );


    strtolower( dig_get_post_type_title() ) ); ?>

    @onishiweb

    View Slide

  79. $strings = array(
    'close' => __('close', 'dirtisgood'),
    'all' => __('All', 'dirtisgood'),
    'both' => __('Both', 'dirtisgood'),
    [...]
    );
    wp_localize_script( 'core', 'coreData', $localisations );
    @onishiweb

    View Slide

  80. @onishiweb
    Custom plugins

    View Slide

  81. @onishiweb
    Reusable functionality

    View Slide

  82. @onishiweb
    Easy to switch on/off

    View Slide

  83. @onishiweb
    Menu

    View Slide

  84. @onishiweb

    View Slide

  85. @onishiweb
    Uses custom menus

    View Slide

  86. @onishiweb

    View Slide

  87. @onishiweb

    View Slide

  88. @onishiweb
    Making use of
    JavaScript

    View Slide

  89. @onishiweb
    Universal Navigation

    View Slide

  90. @onishiweb
    Work in Progress!

    View Slide

  91. @onishiweb
    Thanks!
    adamonishi.com
    twitter.com/onishiweb
    github.com/onishiweb

    View Slide