I'm working on a thematic child theme project for a client and they've requested a 'library' page which initially just featured a list of all articles published on the site. I'd achieved this quite nicely using the dagon design sitemap generator which also listed the articles by category.
the client has now asked whether it's possible to show just a page (grid) of thumbnail images which on rollover will show the article title and will link to the original source article, with the thumbnails being automatically generated from the first attached image. they gave this page as a design reference (see the thumbs on the RHS, got a feeling this sidebar isn't dynamically generated though and bear in mind I need mine to work within the page, not the sidebar): http://www.luckynumbermusic.com/
So I'm looking either for a better plugin recommendation, a custom page template which achieves this, or some code for functions.php which I can then go to work with. the page name is 'library'.
anyone?
Michael Fields answers:
Hi! Here's my solution in page template form. You may need to change a few things under "output" to get it to match you theme. If ou have problems, please show me what your theme's page.php file looks like and I can make it match.
Best wishes,
Mike
<?php
/*
Template Name: Page Thumbnails
*/
/* Configuration */
$post_type = 'page';
$number_posts = '-1'; /* ALL */
$image_size = 'thumbnail';
$div_height = 100; /* in pixels */
$div_width = 100; /* in pixels */
$show_all = false; /* Set to false to hide objects that have no associated thumbnails. */
/* Vars */
$in = array();
$objects = array();
$attachments = array();
/* Query for published objects */
$objects = get_posts( 'numberposts=' . $number_posts . '&post_type=' . $post_type );
/* "IN" String for cache Query */
if( is_array( $objects ) && count( $objects ) > 0 ) {
foreach( $objects as $obj ) {
$in[] = intval( $obj->ID );
wp_cache_add( $obj->ID, $obj, $obj->post_type );
}
}
/* Query for thumbnails */
if( !empty( $in ) ) {
$in_string = implode( ',', $in );
$query = "
SELECT p.*
FROM {$wpdb->prefix}posts AS p
WHERE p.`post_parent` IN( {$in_string} )
AND 'image' = LEFT( p.`post_mime_type`, 5 )
GROUP BY p.`post_parent`
ORDER BY p.`post_date` DESC
";
$attachments = $wpdb->get_results( $query );
if( !empty( $attachments ) )
foreach( $attachments as $image )
$images[ $image->post_parent ] = $image;
if( !empty( $images ) )
foreach( $images as $parent_id => $image )
wp_cache_add( $image->ID, $image, 'posts' );
}
/* Custom Styles */
add_action( 'wp_head', 'page_thumbnail_rollover_css' );
function page_thumbnail_rollover_css() {
global $div_width, $div_height;
print <<<EOF
<style type="text/css">
.page-thumbnail-rollover,
.page-thumbnail-rollover a{
height: {$div_height}px;
width: {$div_width}px;
overflow: hidden;
float:left;
}
.hide{display:none};
</style>
<script type="text/javascript">
/* <![CDATA[ */
jQuery( document ).ready( function( $ ) {
$( '.page-thumbnail-rollover' ).hover(
function () {
$( this ).find( 'img' ).hide();
$( this ).find( 'span' ).show();
},
function () {
$( this ).find( 'img' ).show();
$( this ).find( 'span' ).hide();
}
)
} );
/* ]]> */
</script>
EOF;
}
/* Custom Scripts */
add_action( 'wp_print_scripts', 'page_thumbnail_rollover_enqueue' );
function page_thumbnail_rollover_enqueue() {
wp_enqueue_script( 'jquery' );
}
function mfields_show_images() {
global $post, $images, $image_size;
if( isset( $images[ $post->ID ] ) ) {
$img = wp_get_attachment_image_src( $images[$post->ID]->ID, $image_size );
if( is_array( $img ) ) {
print "\n\t" . '<div class="page-thumbnail-rollover">';
print "\n\t" . '<a href="' . get_permalink( $post->ID ) . '">';
the_title( '<span class="hide">', '</span>' );
print "\n\t" . '<img src="'.$img[0].'" width="'.$img[1].'" height="'.$img[2].'" alt="" />';
print "\n\t" . '</a>';
print "\n\t" . '</div>';
}
}
}
function mfields_show_all() {
global $post, $images, $image_size;
print "\n\t" . '<div class="page-thumbnail-rollover">';
print "\n\t" . '<a href="' . get_permalink( $post->ID ) . '">';
the_title( '<span class="hide">', '</span>' );
if( isset( $images[ $post->ID ] ) ) {
$img = wp_get_attachment_image_src( $images[$post->ID]->ID, $image_size );
if( is_array( $img ) ) {
print "\n\t" . '<img src="'.$img[0].'" width="'.$img[1].'" height="'.$img[2].'" alt="" />';
}
}
print "\n\t" . '</a>';
print "\n\t" . '</div>';
}
/* Output to the browser.
==================================== */
get_header();
if( !empty( $objects ) ) {
foreach( $objects as $post ) {
setup_postdata( $post );
if( $show_all )
mfields_show_all();
else
mfields_show_images();
}
}
get_sidebar();
get_footer();
?>
Dave Smith comments:
tried implementing this, but it seems to be pulling on the page attached images rather than the post attached images... my error or yours?
Dave Smith comments:
incidentally here is the page.php code...
<?php get_header() ?>
<div id="container">
<div id="content">
<?php get_sidebar('page-top') ?>
<?php the_post() ?>
<div id="post-<?php the_ID(); ?>" class="<?php thematic_post_class() ?>">
<?php thematic_postheader(); ?>
<div class="entry-content">
<?php the_content() ?>
<?php wp_link_pages("\t\t\t\t\t<div class='page-link'>".__('Pages: ', 'thematic'), "</div>\n", 'number'); ?>
<?php edit_post_link(__('Edit', 'thematic'),'<span class="edit-link">','</span>') ?>
</div>
</div><!-- .post -->
<?php if ( get_post_custom_values('comments') ) thematic_comments_template() // Add a key+value of "comments" to enable comments on this page ?>
<?php get_sidebar('page-bottom') ?>
</div><!-- #content -->
</div><!-- #container -->
<?php thematic_sidebar() ?>
<?php get_footer() ?>
Michael Fields comments:
Dave, I have tested the script with both pages and posts... you can change this via the $post_type variable under configuration. it works fine for me where each page or post has an image associated to it by uploading it directly through that given page's media upload popup. Please change this var to 'post' and let me know what happens for you. If it works, I can rework the code to match your theme. Thanks! Mike
Michael Fields comments:
Dave,
Here is the finished code which should integrate rather well with your theme. I have also fixed a small javascript error and added caching for attachment metadata. Hope this works for ya!!!
-Mike
<?php
/*
Template Name: Page Thumbnails
*/
/* Configuration */
$post_type = 'post';
$number_posts = '-1'; /* ALL */
$image_size = 'thumbnail';
$div_height = 100; /* in pixels */
$div_width = 100; /* in pixels */
$show_all = false; /* Set to false to hide objects that have no associated thumbnails. */
/* Vars */
$in = array();
$objects = array();
$attachments = array();
$image_ids = array();
$attachment_meta = array();
/* Query for published objects */
$objects = get_posts( 'numberposts=' . $number_posts . '&post_type=' . $post_type );
/* "IN" String for cache Query */
if( is_array( $objects ) && count( $objects ) > 0 ) {
foreach( $objects as $obj ) {
$in[] = intval( $obj->ID );
wp_cache_add( $obj->ID, $obj, 'post' );
}
}
/* Query for thumbnails */
if( !empty( $in ) ) {
$in_string = implode( ',', $in );
$query = "
SELECT p.*
FROM {$wpdb->prefix}posts AS p
WHERE p.`post_parent` IN( {$in_string} )
AND 'image' = LEFT( p.`post_mime_type`, 5 )
GROUP BY p.`post_parent`
ORDER BY p.`post_date` DESC
";
$attachments = $wpdb->get_results( $query );
/* Re-key the array */
if( !empty( $attachments ) ) {
foreach( $attachments as $image ) {
$images[ $image->post_parent ] = $image;
$image_ids[] = $image->ID;
}
}
/* Add attachments to cache */
if( !empty( $images ) )
foreach( $images as $parent_id => $image )
wp_cache_add( $image->ID, $image, 'posts' );
/* Add Attachment Meta to cache. */
if( !empty( $image_ids ) )
update_meta_cache( 'post', $image_ids );
}
/* Custom Styles */
add_action( 'wp_head', 'page_thumbnail_rollover_css' );
function page_thumbnail_rollover_css() {
global $div_width, $div_height;
print <<<EOF
<style type="text/css">
.page-thumbnail-rollover,
.page-thumbnail-rollover a{
height: {$div_height}px;
width: {$div_width}px;
overflow: hidden;
float:left;
}
.hide{display:none;}
.clear{clear:both;}
</style>
<script type="text/javascript">
/* <![CDATA[ */
jQuery( document ).ready( function( $ ) {
$( '.page-thumbnail-rollover' ).hover(
function () {
$( this ).find( 'img' ).hide();
$( this ).find( 'span' ).show();
},
function () {
$( this ).find( 'img' ).show();
$( this ).find( 'span' ).hide();
}
)
} );
/* ]]> */
</script>
EOF;
}
/* Custom Scripts */
add_action( 'wp_print_scripts', 'page_thumbnail_rollover_enqueue' );
function page_thumbnail_rollover_enqueue() {
wp_enqueue_script( 'jquery' );
}
function mfields_show_images() {
global $post, $images, $image_size;
if( isset( $images[ $post->ID ] ) ) {
$img = wp_get_attachment_image_src( $images[$post->ID]->ID, $image_size );
if( is_array( $img ) ) {
print "\n\t" . '<div class="page-thumbnail-rollover">';
print "\n\t" . '<a href="' . get_permalink( $post->ID ) . '">';
the_title( '<span class="hide">', '</span>' );
print "\n\t" . '<img src="'.$img[0].'" width="'.$img[1].'" height="'.$img[2].'" alt="" />';
print "\n\t" . '</a>';
print "\n\t" . '</div>';
}
}
}
function mfields_show_all() {
global $post, $images, $image_size;
print "\n\t" . '<div class="page-thumbnail-rollover">';
print "\n\t" . '<a href="' . get_permalink( $post->ID ) . '">';
the_title( '<span class="hide">', '</span>' );
if( isset( $images[ $post->ID ] ) ) {
$img = wp_get_attachment_image_src( $images[$post->ID]->ID, $image_size );
if( is_array( $img ) ) {
print "\n\t" . '<img src="'.$img[0].'" width="'.$img[1].'" height="'.$img[2].'" alt="" />';
}
}
print "\n\t" . '</a>';
print "\n\t" . '</div>';
}
?>
<?php get_header() ?>
<div id="container">
<div id="content">
<?php get_sidebar('page-top') ?>
<?php the_post() ?>
<div id="post-<?php the_ID(); ?>" class="<?php thematic_post_class() ?>">
<?php thematic_postheader(); ?>
<div class="entry-content">
<?php
the_content();
if( !empty( $objects ) ) {
foreach( $objects as $post ) {
setup_postdata( $post );
if( $show_all )
mfields_show_all();
else
mfields_show_images();
}
print "\n\t" . '<div class="clear"></div>';
}
?>
<?php wp_link_pages("\t\t\t\t\t<div class='page-link'>".__('Pages: ', 'thematic'), "</div>\n", 'number'); ?>
<?php edit_post_link(__('Edit', 'thematic'),'<span class="edit-link">','</span>') ?>
</div>
</div><!-- .post -->
<?php if ( get_post_custom_values('comments') ) thematic_comments_template() // Add a key+value of "comments" to enable comments on this page ?>
<?php get_sidebar('page-bottom') ?>
</div><!-- #content -->
</div><!-- #container -->
<?php thematic_sidebar() ?>
<?php get_footer() ?>
Dave Smith comments:
Mike this is working great. just two things... is there a way of limiting this just to posts with a specific tag?
also, is there a way to set it so that the page title shows OVER the image on hover rather than instead of the image please?
Michael Fields comments:
Dave, Glad to hear it is working for you! I have made the corrections that youasked for in the code below. You can now declare the tag(s) that you would like in the $tag variable under the configuration section of code - these should be the tag "slug". Please refer to the codex for further instruction: http://codex.wordpress.org/Template_Tags/get_posts
I have also reworked the css + javascript to display the page titles over the thumbnails. I don't really know what you are going for aesthetically, but I made the text light grey and the text's background black... if you are comfortable editing css this should not be hard for you to modify the code.
Please let me know how this works for you.
-Mike
<?php
/*
Template Name: Page Thumbnails
*/
/* Configuration */
$post_type = 'post';
$tag = 'manor-of-art';
$number_posts = '-1'; /* ALL */
$image_size = 'thumbnail';
$div_height = 100; /* in pixels */
$div_width = 100; /* in pixels */
$show_all = false; /* Set to false to hide objects that have no associated thumbnails. */
/* Vars */
$in = array();
$objects = array();
$attachments = array();
$image_ids = array();
$attachment_meta = array();
/* Query for published objects */
$objects = get_posts( 'numberposts=' . $number_posts . '&post_type=' . $post_type . '&tag=' . $tag );
/* "IN" String for cache Query */
if( is_array( $objects ) && count( $objects ) > 0 ) {
foreach( $objects as $obj ) {
$in[] = intval( $obj->ID );
wp_cache_add( $obj->ID, $obj, 'post' );
}
}
/* Query for thumbnails */
if( !empty( $in ) ) {
$in_string = implode( ',', $in );
$query = "
SELECT p.*
FROM {$wpdb->prefix}posts AS p
WHERE p.`post_parent` IN( {$in_string} )
AND 'image' = LEFT( p.`post_mime_type`, 5 )
GROUP BY p.`post_parent`
ORDER BY p.`post_date` DESC
";
$attachments = $wpdb->get_results( $query );
/* Re-key the array */
if( !empty( $attachments ) ) {
foreach( $attachments as $image ) {
$images[ $image->post_parent ] = $image;
$image_ids[] = $image->ID;
}
}
/* Add attachments to cache */
if( !empty( $images ) )
foreach( $images as $parent_id => $image )
wp_cache_add( $image->ID, $image, 'posts' );
/* Add Attachment Meta to cache. */
if( !empty( $image_ids ) )
update_meta_cache( 'post', $image_ids );
}
/* Custom Styles */
add_action( 'wp_head', 'page_thumbnail_rollover_css' );
function page_thumbnail_rollover_css() {
global $div_width, $div_height;
print <<<EOF
<style type="text/css">
.page-thumbnail-rollover { position:relative; }
.page-thumbnail-rollover img,
.page-thumbnail-rollover span{
position: absolute;
top:0;
left:0;
}
.page-thumbnail-rollover{ z-index: 0; }
.page-thumbnail-rollover img{ z-index: 0; }
.page-thumbnail-rollover span{ z-index: 10; background: #000; color:#999; padding:.3em; }
.page-thumbnail-rollover,
.page-thumbnail-rollover a{
height: {$div_height}px;
width: {$div_width}px;
overflow: hidden;
float:left;
text-decoration:none;
}
.hide{display:none;}
.clear{clear:both;}
</style>
<script type="text/javascript">
/* <![CDATA[ */
jQuery( document ).ready( function( $ ) {
$( '.page-thumbnail-rollover' ).hover(
function () {
$( this ).find( 'span' ).show();
},
function () {
$( this ).find( 'span' ).hide();
}
)
} );
/* ]]> */
</script>
EOF;
}
/* Custom Scripts */
add_action( 'wp_print_scripts', 'page_thumbnail_rollover_enqueue' );
function page_thumbnail_rollover_enqueue() {
wp_enqueue_script( 'jquery' );
}
function mfields_show_images() {
global $post, $images, $image_size;
if( isset( $images[ $post->ID ] ) ) {
$img = wp_get_attachment_image_src( $images[$post->ID]->ID, $image_size );
if( is_array( $img ) ) {
print "\n\t" . '<div class="page-thumbnail-rollover">';
print "\n\t" . '<a href="' . get_permalink( $post->ID ) . '">';
the_title( '<span class="hide">', '</span>' );
print "\n\t" . '<img src="'.$img[0].'" width="'.$img[1].'" height="'.$img[2].'" alt="" />';
print "\n\t" . '</a>';
print "\n\t" . '</div>';
}
}
}
function mfields_show_all() {
global $post, $images, $image_size;
print "\n\t" . '<div class="page-thumbnail-rollover">';
print "\n\t" . '<a href="' . get_permalink( $post->ID ) . '">';
the_title( '<span class="hide">', '</span>' );
if( isset( $images[ $post->ID ] ) ) {
$img = wp_get_attachment_image_src( $images[$post->ID]->ID, $image_size );
if( is_array( $img ) ) {
print "\n\t" . '<img src="'.$img[0].'" width="'.$img[1].'" height="'.$img[2].'" alt="" />';
}
}
print "\n\t" . '</a>';
print "\n\t" . '</div>';
}
?>
<?php get_header() ?>
<div id="container">
<div id="content">
<?php get_sidebar('page-top') ?>
<?php the_post() ?>
<div id="post-<?php the_ID(); ?>" class="<?php thematic_post_class() ?>">
<?php thematic_postheader(); ?>
<div class="entry-content">
<?php
the_content();
if( !empty( $objects ) ) {
foreach( $objects as $post ) {
setup_postdata( $post );
if( $show_all )
mfields_show_all();
else
mfields_show_images();
}
print "\n\t" . '<div class="clear"></div>';
}
?>
<?php wp_link_pages("\t\t\t\t\t<div class='page-link'>".__('Pages: ', 'thematic'), "</div>\n", 'number'); ?>
<?php edit_post_link(__('Edit', 'thematic'),'<span class="edit-link">','</span>') ?>
</div>
</div><!-- .post -->
<?php if ( get_post_custom_values('comments') ) thematic_comments_template() // Add a key+value of "comments" to enable comments on this page ?>
<?php get_sidebar('page-bottom') ?>
</div><!-- #content -->
</div><!-- #container -->
<?php thematic_sidebar() ?>
<?php get_footer() ?>
Dave Smith comments:
bingo. mike, superstar, thanks so much, great work.
Michael Fields comments:
No problem! Glad I could help :)
Erez S answers:
simply use the loop and change the post limit to big number with query_posts and then only show the thumbs with simple html codex.wordpress.org/Template_Tags/query_posts
Dave Smith comments:
sounds good, but i'm kind of after the code working within a thematic child theme page template so i can just drop it into the theme
Erez S comments:
so what is the problem with my solution?
Dave Smith comments:
it tells me how to do it, but i don't necessarily have the coding skills or time to explore it. I just need some cut and paste code.
Erez S comments:
but as you said you are building a site for your client so you have the skills to code it
Dan Fraticiu answers:
It's bit complicated to explain here, but I'll give it a go:
First put this function in your functions.php file:
function get_post_thumb(){
global $post;
preg_match("/<img (.*) src\=('|\")(.*)('|\") .*( |)\/>/", $post->post_content, $matches);
$the_image_src = $matches[3];
$frags = preg_split("/(\"|')/", $the_image_src);
if(count($frags)) {
$the_image_src = $frags[0];
}
if(strlen($the_image_src)) {
$the_image = '<img alt="" src="' . get_bloginfo('template_url').'/scripts/timthumb.php?zc=1&w=50&h=50&src='. $the_image_src . '" />';
}
return $the_image;
}
This assumes you use TimThumb to generate the thumbnail, if you use something else, I can change the function.
Now create a file named page-library.php in your theme folder and put this in it:
<?php
/*
Template Name: Library
*/
?>
<?php get_header(); ?>
<?php while(have_posts()) : the_post(); ?>
<h2><?php the_title(); ?></h2>
<ul id="post-library">
<?php
$myposts = get_posts('numberposts=-1');
foreach($myposts as $post) :
setup_postdata(); ?>
<li>
<a href="<?php the_permalink(); ?>">
<span class="post-title"><?php the_title(); ?></span>
<?php echo get_post_thumb();?>
</a>
</li>
<?php endforeach; ?>
</ul>
<?php endwhile; ?>
<?php get_sidebar(); ?>
<?php get_footer(); ?>
You should have a list of all the post, each list item containing the title of the post and the image.
Now you need the CSS and the javascript.
If you can't handle the CSS/javscript I can help you but I'd prefer to talk in private because I have to actually see the design or at least give me more info the design, the size of the thumbnails, space beetwen them, and more.
Dave Smith comments:
I'm not currently using tim thumb, and had understood that wordpress had a native way of creating thumbnails built into the core... is there a way of integrating with that please Dan?
Dave Smith comments:
actually dan i've now installed tim thumb so i can work with that. i've followed your instructions but the images aren't showing. a quick peek in the source shows that the code seems to be looking for timthumb in the parent theme not the child theme... is there an edit to the code which will fix that?
Dan Fraticiu comments:
Aparently bloginfo('template_url') return the parent theme url, funny the easiest way to make it work is to put TimThumb in the <strong>thematic/scripts</strong> folder if that is OK by you.
Or you could replace bloginfo('template_url') with <strong>bloginfo('stylesheet_url')</strong> as this will return the actual child theme folder. Make sure you have TimThumb in a <strong>scripts</strong> folder.
If the script wont work, you could manually create a <strong>cache</strong> folder in the <strong>scripts</strong> folder and give it 777 permissions.