wcyvr-2013



wcyvr-2013

0 1


wcyvr-2013

Slides from "Towards a Partial Page Templating System in WordPress" talk given at WCYVR 2013

On Github tollmanz / wcyvr-2013

Towards a Partial Page Templating System in WordPress

Zack Tollman

The Theme Foundry

@tollmanz

What is WordPress at Scale?

The Problem

Page Caching is Lovely

Page Caching is Limiting

github.com/dashboard/issues

Page caching is effective

but cannot work in these scenarios

What Now?

Solution 1: Hardware

Expensive

Hard to scale

Solution 2: "Fragment Caching"

Partial page caching

using object caching

<div id="latest-activity">
<?php
$activity = wp_cache_get( 'latest_activity' );
if ( false === $activity ) {
    $activity = get_latest_activity();
    wp_cache_set( 'latest_activity', $activity, '', 3600 );
}
echo $activity;
?>
</div>

Cache user based variants

<div id="latest-activity">
<?php
$user_id  = get_current_user_id();
$activity = wp_cache_get( 'latest_activity', $user_id );
if ( false === $activity ) {
    $activity = get_latest_activity();
    wp_cache_set( 'latest_activity', $activity, $user_id, 3600 );
}
echo $activity;
?>
</div>

TLC transients

Fragment caching class by Jaquith

Pods framework

Works well

Easy to understand

Always load all of WordPress

Not very performant

Solution 3: Clever Advanced Cache

Daniel Dvorkin

advanced-cached.php implements a page cache for WordPress

Loaded after 1% of WordPress is loaded

1. Generate a page with "nocache" tags
<div id="latest-activity">
    <nocache callback="get_latest_activity"></nocache>
</div>
2. Save an associated piece of meta data if there are any "nocache" tags
3. Serve the page

If metadata does not exist, strip the tags and display

If metadata exists, generate the block

4. Add "is_user_logged_in" for user variants
<div id="latest-activity">
    <nocache is_user_logged_in callback="get_latest_activity">
        <p>Activity feed is not available.</p>
    </nocache>
</div>
Has potential to be quite fast

Uses core standards

"callback" method is may present problems

Solution 4: Edge Side Includes

Partial Page Templating

1. Save a page template

Embed ESI tags in the template

<div id="latest-activity">
    <?php 
    // Loads partial-activity.php
    get_template_part( 'partial', 'activity' ); 
    ?>
</div>
<?php if ( isset( $_GET['partial'] ) && 'activity' === $_GET['partial'] ) : ?>
    <?php echo get_latest_activity(); ?>
<?php else : ?>
    <esi:remove>
        <p>Activity feed is not available.</p>
    </esi:remove>
    <!--esi
    <esi:include src="<?php echo site_url( '/?partial=activity' ); ?>" />
    -->
<?php endif; ?>
2. Load page template from Varnish, Akamai, Squid
<div id="latest-activity">
    <esi:remove>
        <p>Activity feed is not available.</p>
    </esi:remove>
    <!--esi
    <esi:include src="<?php echo site_url( '/?partial=activity' ); ?>" />
    -->
</div>
3. Render ESIs
function zdt_page_template_redirect() {
    if ( isset( $_GET['partial'] ) ) {
        $sanitize_partial = sanitize_key( $_GET['partial'] );
        get_template_part( 'partial', $sanitize_partial );
        exit();
    }
}

add_action( 'template_redirect', 'zdt_page_template_redirect' );
<?php if ( isset( $_GET['partial'] ) && 'activity' === $_GET['partial'] ) : ?>
    <?php echo get_latest_activity(); ?>
<?php else : ?>
    <esi:remove>
        <p>Activity feed is not available.</p>
    </esi:remove>
    <!--esi
    <esi:include src="<?php echo site_url( '/?partial=activity' ); ?>" />
    -->
<?php endif; ?>
Load dynamic elements without any PHP

Adheres to WordPress standards

Many partials can lead to many WordPress loads

You Decide

There is no right answer

There are a lot of wrong answers

Each app needs its own technique

Zack Tollman

The Theme Foundry

@tollmanz

tollmanz.github.io/wcyvr-2013

tollmanz.com/partial-page-templating-in-wordpress