Relate all the things!

Preview:

DESCRIPTION

So your new site’s launched: great content, beautiful design, and SEO’ed like whoah. But when a visitor comes in for one particular page, how do you encourage them to engage further with your content rather than leave? The Yet Another Related Posts Plugin for WordPress—aka YARPP—was built exactly out of this concern. YARPP offers your visitors a number of “related posts” which may also interest them. These “related posts” are chosen automatically by a unique algorithm which compares the current post or page with other content on the site.Advocated by the likes of Matt Mullenweg (WordPress) and Matt Cutts (Google), YARPP is by far the most popular content recomendation plugin for WordPress. Learn about the past and future of YARPP straight from its author, mitcho. I’ll talk about YARPP’s internals, share some advanced tips for using and customizing YARPP, and will debut YARPP’s custom post type support.

Citation preview

mitcho @ WordCamp Birmingham, January 2012RELATE ALL THE THINGS!

YARPP!

mitcho (Michael 芳貴 Erlewine)

http://mitcho.com, @themitcho, @yarpp

toothpastefordinner.com

The solution: suggesting related content

Yet Another Related Posts Plugin

Yet Another Related Posts Plugin

One of my favorite [plugins] I just activated on my blog is called Yet Another Related Posts Plugin...

I've been blogging seven or eight years now so I have a lot of archives, and it actually surprises me sometimes when I blog about something and I visit the permalink to see I've written about it before... and it also increases the traffic on your blog because when they come in just to one entry, they'll see this other stuff going on.

Matt Mullenweg

TODAY

1. How does YARPP work?

TODAY

1. How does YARPP work?2. Relate all the things!

TODAY

1. How does YARPP work?2. Relate all the things!3. No, really—how does YARPP work?

TODAY

1. How does YARPP work?2. Relate all the things!3. No, really—how does YARPP work?

TODAY

How YARPP works

What’s “related”?CC-BY-NC-ND http://www.flickr.com/photos/twcollins/109069524/

My trip to Greece

My thoughts on Google+

20 ways to use Path now

I love my iPhone!

Fluid dynamics in 10 min

10 Great Eats in Birmingham

Writing your own WordPress plugin

Nikon D90 review

Living off the grid

“THE POOL”

Taiwan travel tipsVISITORreference entry:

The criteria:

• Title keywords*

• Content body keywords*

• Tags

• Categories

* a value computed by a MySQL FULLTEXT MATCH of the reference

entries’ top 20 keywords against the pool entries’ full values

2.73.2

1

2

SCORES:

The “match score”:

1310

WEIGHTS:

The “match score”:A weighted sum of the criteria:

1310

WEIGHTS:

The “match score”:A weighted sum of the criteria:

2.7 × 1 + 2.8 × 3 + 1 x 1 + 2 x 0 = 12.1

1310

WEIGHTS:

The “match score”:A weighted sum of the criteria:

2.7 × 1 + 2.8 × 3 + 1 x 1 + 2 x 0 = 12.1

12.1 > 7 (“match threshold”) so related!

1310

WEIGHTS:

The result:

The result:

• A good, organic sense of “relatedness”

The result:

• A good, organic sense of “relatedness”• Default settings are pretty good :)

The result:

• A good, organic sense of “relatedness”• Default settings are pretty good :)• Sometimes results in less than the

specified number of results

The result:

• A good, organic sense of “relatedness”• Default settings are pretty good :)• Sometimes results in less than the

specified number of results• A feature, not a bug

The result:

• A good, organic sense of “relatedness”• Default settings are pretty good :)• Sometimes results in less than the

specified number of results• A feature, not a bug

• Not symmetric, not transitive

Templates:Uber-customize the related posts display

http://phillprice.com http://elliottgoodman.com

Templates:<?php if (have_posts()): ?><h3>Related Photos</h3><ol> <?php while (have_posts()) : the_post(); ?> <?php if (has_post_thumbnail()):?> <li><a href="<?php the_permalink() ?>" rel="bookmark" title="<?php the_title_attribute(); ?>"> <?php the_post_thumbnail(); ?></a></li> <?php endif; ?> <?php endwhile; ?></ol><?php endif; ?>

http://mitcho.com/blog/projects/yarpp-3-templates/

1. How does YARPP work?2. Relate all the things!3. No, really—how does YARPP work?

TODAY

RELATE ALL THE THINGS!

YARPP!

RELATE ALL THE THINGS!

YARPP!

custom queries and CPT support

Custom queries

Custom queries

• YARPP has always had posts and pages

Custom queries

• YARPP has always had posts and pages• Options set in one place

Custom queries

• YARPP has always had posts and pages• Options set in one place• No way to programmatically override

Custom queries

• YARPP has always had posts and pages• Options set in one place• No way to programmatically override

• YARPP 3.5 allows one-off custom displays

Custom queries

related_posts();

related_posts(array(), $ID, true); *

* Some YARPP function signatures are changed in YARPP 3.5 to

make them all uniform. Sorry to break it to you. (Ha!)

Custom queries

related_posts(array());

Custom queries

related_posts(array());

THE FUN PART

Custom queries

related_posts(array( 'order' => 'post_title ASC'));

Custom queries

related_posts(array( 'order' => 'post_title ASC'));

Custom queries

a wp_posts column and ASC or DESC

Custom queries

related_posts(array( 'template' => 'yarpp-template.php'));

Custom queries

related_posts(array( 'template' => 'yarpp-template.php'));

a file in your active theme

Custom queries

related_posts(array( 'weight' => array( 'body' => 1, 'title' => 3 ), 'threshold' => 5));

related_posts(array( 'weight' => array( 'body' => 1, 'title' => 3, 'tax' => array( 'post_tag' => 1 ) )));

Custom queries

Custom queries

related_posts(array( 'weight' => array( 'body' => 1, 'title' => 3, 'tax' => array( 'post_tag' => 1, 'category' => 2 ) )));

Custom queries

related_posts(array( 'weight' => array( 'body' => 1, 'title' => 3, 'tax' => array( 'post_tag' => 1, 'category' => 2 ) ))); your taxonomy here

related_posts(array( 'weight' => array(...), 'require_tax' => array( 'post_tag' => 1 )));

Custom queries

related_posts(array( 'weight' => array(...), 'require_tax' => array( 'post_tag' => 1 )));

Custom queries

taxonomy # requiredin common

Custom queries

related_posts(array( 'recent' => '3 month'));

related_posts(array( 'exclude' => array(32,12,84)));

Custom queries

related_posts(array( 'exclude' => array(32,12,84)));

Custom queries

term_taxonomy_ids

Relate all the things!YARPP 3.5 adds Custom Post Type support

yarpp_related(array( 'post_type' => array('people','animals')));

YARPP!

POP QUIZ!YARPP!

yarpp_related(array( 'post_type' => array('movies'), 'weight' => array( 'title' => 1, 'tax' => array( 'actor' => 1 ) )));

yarpp_related(array( 'post_type' => array('movies'), 'weight' => array( 'title' => 1, 'tax' => array( 'actor' => 1 ) )));

related movies considering titles and actors

yarpp_related(array( 'post_type' => array('book'), 'recent' => '1 year', 'weight' => array( 'title' => 1, 'tax' => array( 'author' => 1 ) )));

yarpp_related(array( 'post_type' => array('book'), 'recent' => '1 year', 'weight' => array( 'title' => 1, 'tax' => array( 'author' => 1 ) )));

related books considering titles and authors and published in the past year

yarpp_related(array( 'post_type' => array('toy'), 'require_tax' => array( 'age_range' => 1 )));

yarpp_related(array( 'post_type' => array('toy'), 'require_tax' => array( 'age_range' => 1 )));

related toys with at least one age range in common

As you like it

As you like it

• yarpp_related_exist() returns boolean

As you like it

• yarpp_related_exist() returns boolean• yarpp_get_related() returns array of

objects

As you like it

• yarpp_related_exist() returns boolean• yarpp_get_related() returns array of

objects• just like WP’s get_posts()

Caveat:

• Custom queries with related_posts() or yarpp_related() aren’t cached in YARPP’s

internal cache

• If you use them a lot, cache the results yourself (which is another talk...)

1. How does YARPP work?2. Relate all the things!3. No, really—how does YARPP work?

TODAY

Do the mathSELECT 4024 as reference_ID, ID,

ROUND(0 + (MATCH (post_content) AGAINST ('carved panorama great ones lantern including chomsky photos richards share flickr jack norvin stata pumpkins couple team firefox halloween ')) * 1 + (MATCH (post_title) AGAINST ('halloween happy ')) * 1 + count(distinct if( terms.term_taxonomy_id in (598,447), terms.term_taxonomy_id, null )) * 1 + count(distinct if( terms.term_taxonomy_id in (649,47,808,861,824), terms.term_taxonomy_id, null )) * 1,1) as score

from wp_posts left join wp_term_relationships as terms on ( terms.object_id = wp_posts.ID )

where post_status in ( 'publish', 'static' ) andID != '4024' andpost_date <= '2010-10-29 16:22:51' andpost_password ='' andpost_type = 'post'

group by ID having score >= 5.00 and

bit_or(terms.term_taxonomy_id in (601)) = 0order by score desc limit 5

Do the mathSELECT 4024 as reference_ID, ID,

ROUND(0 + (MATCH (post_content) AGAINST ('carved panorama great ones lantern including chomsky photos richards share flickr jack norvin stata pumpkins couple team firefox halloween ')) * 1 + (MATCH (post_title) AGAINST ('halloween happy ')) * 1 + count(distinct if( terms.term_taxonomy_id in (598,447), terms.term_taxonomy_id, null )) * 1 + count(distinct if( terms.term_taxonomy_id in (649,47,808,861,824), terms.term_taxonomy_id, null )) * 1,1) as score

from wp_posts left join wp_term_relationships as terms on ( terms.object_id = wp_posts.ID )

where post_status in ( 'publish', 'static' ) andID != '4024' andpost_date <= '2010-10-29 16:22:51' andpost_password ='' andpost_type = 'post'

group by ID having score >= 5.00 and

bit_or(terms.term_taxonomy_id in (601)) = 0order by score desc limit 5

the score formula

Do the mathSELECT 4024 as reference_ID, ID,

ROUND(0 + (MATCH (post_content) AGAINST ('carved panorama great ones lantern including chomsky photos richards share flickr jack norvin stata pumpkins couple team firefox halloween ')) * 1 + (MATCH (post_title) AGAINST ('halloween happy ')) * 1 + count(distinct if( terms.term_taxonomy_id in (598,447), terms.term_taxonomy_id, null )) * 1 + count(distinct if( terms.term_taxonomy_id in (649,47,808,861,824), terms.term_taxonomy_id, null )) * 1,1) as score

from wp_posts left join wp_term_relationships as terms on ( terms.object_id = wp_posts.ID )

where post_status in ( 'publish', 'static' ) andID != '4024' andpost_date <= '2010-10-29 16:22:51' andpost_password ='' andpost_type = 'post'

group by ID having score >= 5.00 and

bit_or(terms.term_taxonomy_id in (601)) = 0order by score desc limit 5

table join

in YARPP 3.5, just two tables!

I got cache. Mega cache.

I got cache. Mega cache.

• The first time, compute and cache

I got cache. Mega cache.

• The first time, compute and cache• Internally, three cache engines built-in:

I got cache. Mega cache.

• The first time, compute and cache• Internally, three cache engines built-in:

• YARPP_Cache_Tables

I got cache. Mega cache.

• The first time, compute and cache• Internally, three cache engines built-in:

• YARPP_Cache_Tables

• YARPP_Cache_Postmeta

I got cache. Mega cache.

• The first time, compute and cache• Internally, three cache engines built-in:

• YARPP_Cache_Tables

• YARPP_Cache_Postmeta

• define('YARPP_CACHE_TYPE','postmeta');

I got cache. Mega cache.

• The first time, compute and cache• Internally, three cache engines built-in:

• YARPP_Cache_Tables

• YARPP_Cache_Postmeta

• define('YARPP_CACHE_TYPE','postmeta');

• YARPP_Cache_Bypass

I got cache. Mega cache.

• The first time, compute and cache• Internally, three cache engines built-in:

• YARPP_Cache_Tables

• YARPP_Cache_Postmeta

• define('YARPP_CACHE_TYPE','postmeta');

• YARPP_Cache_Bypass

• Used in custom queries

query_posts(’p=4024’) //=>SELECT wp_posts.*FROM wp_postsWHERE 1=1 AND wp_posts.ID = 4024 AND wp_posts.post_type = 'post'ORDER BY wp_posts.post_date DESC

query_posts w/table cacheSELECT wp_posts.*, yarpp.scoreFROM wp_postsJOIN wp_yarpp_related_cache AS yarppON wp_posts.ID = yarpp.ID

WHERE 1=1 ANDyarpp.reference_ID = 4024 ANDwp_posts.post_type IN ('post')

ORDER BY yarpp.score DESC LIMIT 5

http://mitcho.com/blog/how-to/external-orders-in-wordpress-queries/

query_posts w/list of IDsSELECT wp_posts.*,CASE wp_posts.IDWHEN 43 THEN 23.0 WHEN 1413 THEN 20.5WHEN 3448 THEN 19.7 WHEN 85 THEN 19.6WHEN 2203 THEN 19.0 END as score

FROM wp_postsWHERE 1=1 ANDwp_posts.ID in (43,1413,3448,85,2203) ANDwp_posts.post_type IN ('post')

ORDER BY score DESC LIMIT 5

YARPP 3.5COMING SOON TO A

WORDPRESS NEAR YOU

Download 3.5b4:http://tinyurl.com/yarppversions

Thank you!slides on http://slideshare.net/mitcho@themitcho, @yarpp