There are things in WordPress, I do not like. This includes the gallery. Not that the idea behind it is bad. It is just poorly implemented. But only criticizing is not fair. Let’s see what you can do better.
The problem of the gallery is the style sheet, which is simply written in the Post. So that the page no longer validates. Additional problems arise when you want to change the look of the pictures in your theme for example. The style sheet in the post overwrites the values from the theme style sheet. How do the developers know if I like a 2px border #cfcfcf around my images? Something like this definitely does not belong in the code!
Cause of the problem is the ability to choose when you insert the gallery into the post, the number of columns (2-9). WordPress then calculates the width of the list elements by the number of selected columns and writes the values in the style sheet.
An own gallery function
The function gallery_shortcode, which generates the gallery, can be found in wp-includes/media.php. For simplicity, we copy the complete function gallery_shortcode in to functions.php of the active theme. Then we rename the function, disable the function of WordPress and activate our own function:
//deactivate WordPress function
remove_shortcode('gallery', 'gallery_shortcode');
//activate own function
add_shortcode('gallery', 'wpe_gallery_shortcode');
//the own renamed function
function wpe_gallery_shortcode($attr) {
...
}
We are now going to call up a post with an inserted gallery. It should all work exactly as before, except that our own gallery function is now active. Now let us take any necessary changes to improve the output of the gallery.
First, we delete the following line. Which calculates the column. We do not need it anymore.
$itemwidth = $columns > 0 ? floor(100/$columns) : 100;
Then we modify the variable $output. The style sheet will be completely erased. The inline style of the clearing br
will be also removed. It’s more elegant in its own theme style sheet. Finally, the last br-tag gets removed. The revised code $output should now look like this:
$output = apply_filters('gallery_style', "
");
$i = 0;
foreach ( $attachments as $id => $attachment ) {
$link = isset($attr['link']) && 'file' == $attr['link'] ? wp_get_attachment_link($id, $size, false, false) : wp_get_attachment_link($id, $size, true, false);
$output .= "<{$itemtag} class='gallery-item'>";
$output .= "
<{$icontag} class='gallery-icon'>
$link
{$icontag}>";
if ( $captiontag && trim($attachment->post_excerpt) ) {
$output .= "
<{$captiontag} class='gallery-caption'>
" . wptexturize($attachment->post_excerpt) . "
{$captiontag}>";
}
$output .= "{$itemtag}>";
if ( $columns > 0 && ++$i % $columns == 0 )
$output .= '
';
}
$output .= "\n";
return $output;
After we have updated the post in our browser, we see all the pictures one below the other. But the document is valid. Now we need to create the column functionality again, that we have erased before. We simply add one additional class with the number of columns in $itemtag:
$output .= "<{$itemtag} class='gallery-item col-{$columns}'>";
In your source code, depending on the number of columns you see
Now, implement a few lines in the theme style sheet and the gallery is finished.
.gallery {
margin: auto;
/* gallery clearing*/
overflow: hidden;
width: 100%;
}
.gallery .gallery-item {
float: left;
margin-top: 10px;
text-align: center;
}
.gallery img {
border: 2px solid #cfcfcf;
}
.gallery .gallery-caption {
margin-left: 0;
}
.gallery br { clear: both }
/* available Columns */
.col-2 { width: 50% }
.col-3 { width: 33.333% }
.col-4 { width: 25% }
.col-5 { width: 20% }
.col-6 { width: 16.666% }
.col-7 { width: 14.285% }
.col-8 { width: 12.5% }
.col-9 { width: 11.111% }
Comments
36 responses to “A Solution For The WordPress Gallery”
Okay, that’s just awesome. So awesome, in fact, that it probably should be in core.
Too late for 2.9, but dang!, that oughtta be in 3.0.
Nice thinking, I can definitely live with the end result if it means that I no longer have to tweak NextGen after every update anymore.
Okay, I started a ticket:
http://core.trac.wordpress.org/ticket/11155
I just put up a .diff for the PHP. I’ll take a stab at the CSS too.
Doug, nice idea!
Okay, there was an existing ticket that covered the same area but lacked the simple approach you took. I’ve closed out my ticket as a dupe and submitted the PHP and CSS fixes over on that ticket instead.
*crossed fingers* Here’s hoping it goes into 3.0.
Btw:
http://core.trac.wordpress.org/ticket/10734
thank for this great post
I also like this solution, but imho there should be some settings for this, for backwards compatibility as all existing themes simply do not count with the need of implementing the style in their themes.
P.S.: i think there should be also some semantics in the code, e.g. using dl for gallery, dt for caption and dd for image
i stumbled across this site looking to find info on how to create a plugin. i have been trying to write up a description on the changes i’ve made to the wordpress gallery to use an additional attribute called currentid. i may need to take some of these changes, too.
I always thought that the core gallery function of wordpress felt more like a rush job to get it in the release than a final approach. Even so I have recently taken the opinion of why use a plug-in to reinvent something that the core already provides so I have been using the core function. Your solution just gave me vindication for my approach, one more thing in wordpress’s favour.
It’s really nice, but pagination for this would be just awesome! Any suggestion?
This is an elegant solution and worth taking an extra moment to fawn over via this comment. The WordPress core would only be improved, and I should visit your site more often. *noted*
[…] Lösung für die WordPress Galerie hat es Dank meines Beitrags auf WP Engineer zu einem Ticket geschafft. “It seems like the cleanest of all approaches as it modifies very […]
Damn. That is awesome!!
Any idea on how to make the images open in a thickbox as opposed to on a new page?
That option I really would like to see in 3.0 😀
Oh and I agree with Joe. I’m going to be keeping an eye on your site!!!
Best,
Dan
hehehe, Thanks man, you just saved my night. Awesome little fix.
Check it, I reworked this to allow you to specifiy if you want some of the tags or not but just setting them to an empty string in the shortcode.
like here I just set the icontag to “” and that gets rid of the icon tag entirely.
[gallery link="file" columns="3" itemtag="div" icontag="" captiontag="p"]
//the own renamed function
function wpe_gallery_shortcode($attr) {
global $post;
static $instance = 0;
$instance++;
// Allow plugins/themes to override the default gallery template.
$output = apply_filters('post_gallery', '', $attr);
if ( $output != '' )
return $output;
// We're trusting author input, so let's at least make sure it looks like a valid orderby statement
if ( isset( $attr['orderby'] ) ) {
$attr['orderby'] = sanitize_sql_orderby( $attr['orderby'] );
if ( !$attr['orderby'] )
unset( $attr['orderby'] );
}
extract(shortcode_atts(array(
'order' => 'ASC',
'orderby' => 'menu_order ID',
'id' => $post->ID,
'itemtag' => 'dl',
'icontag' => 'dt',
'captiontag' => 'dd',
'columns' => 3,
'size' => 'thumbnail',
'include' => '',
'exclude' => ''
), $attr));
$id = intval($id);
if ( 'RAND' == $order )
$orderby = 'none';
if ( !empty($include) ) {
$include = preg_replace( '/[^0-9,]+/', '', $include );
$_attachments = get_posts( array('include' => $include, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) );
$attachments = array();
foreach ( $_attachments as $key => $val ) {
$attachments[$val->ID] = $_attachments[$key];
}
} elseif ( !empty($exclude) ) {
$exclude = preg_replace( '/[^0-9,]+/', '', $exclude );
$attachments = get_children( array('post_parent' => $id, 'exclude' => $exclude, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) );
} else {
$attachments = get_children( array('post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) );
}
if ( empty($attachments) )
return '';
if ( is_feed() ) {
$output = "\n";
foreach ( $attachments as $att_id => $attachment )
$output .= wp_get_attachment_link($att_id, $size, true) . "\n";
return $output;
}
// check to see if tags have been set to false. If they are the defaults or have been set to a string value use that as the tag.
if ($itemtag) $itemtag = tag_escape($itemtag);
if ($captiontag) $captiontag = tag_escape($captiontag);
if ($icontag) $icontag = tag_escape($icontag);
$columns = intval($columns);
$selector = "gallery-{$instance}";
$output = apply_filters('gallery_style', "\n");
$i = 0;
foreach ( $attachments as $id => $attachment ) {
++$i;
$link = isset($attr['link']) && 'file' == $attr['link'] ? wp_get_attachment_link($id, $size, false, false) : wp_get_attachment_link($id, $size, true, false);
if ($itemtag) {
$output .= "\t 0 && $i % $columns == 0) $output .= "last";
$output .= '\'>';
}
if ($icontag) $output .= "";
$output .= "\n\t\t" . $link . "\n";
if ($icontag) $output .= "";
// if the attachment has a caption set
if ( trim($attachment->post_excerpt) ) {
if ($captiontag) $output .= "\t\t";
$output .= wptexturize($attachment->post_excerpt);
if ($captiontag) $output .= "" . "\n";
}
if ($itemtag) $output .= "\t" . "\n";
if ( $columns > 0 && $i % $columns == 0 ) $output .= "\n";
}
$output .= "\n";
return $output;
}
oh, here's the css as well:
gallery { margin: 0 24px; width: 552px; float: left;}
.gallery-item { float: left; margin: 0 24px 24px 0; background:#C4BFA2; }
.gallery .last { margin-right: 0; }
.gallery-icon {}
.gallery-caption {}
.gallery br { clear: both; }
@Aaron: My motivation was to make the gallary valid not to add more features. That is Dev Stuff.
@Dem: You can edit your gallery in the advanced tab and add classes or rel attributes for lightbox, thickbox etc. to make it work.
Very useful override to the gallery.
It solves the problem.
Thank you my friend.
@Aaron, that seems like a good solution. Unfortunately, the blog chewed up all your code so I cleaned it up and posted it on Snipplr: http://snipplr.com/view/27051/wordpress-27-gallery-styles-fix/
Thanks to you and Michael for your ingenuity and hard work.
Nice work, thanks for posting it.
P.S. Your sidebar says ‘Most Commeted’ (you missed out the N)
Thanks tom! fixed 😉
Thank you so much!!! It works wonderfully and I’m freaky happy to have finally validated my Galleries in my portfolio. That was an important issue. Solved brilliantly!
I would like to add that unfortunately I had an other problem which caused the not validation of my pages with a Gallery. Sort of this:
(followed suddenly by a )
Which I don’t understand, ‘cos the tag was missing the closure , causing 5 validation failures.
Adding a fictional just after the shortcode [gallery] did not help, ‘cos it ended up after the .
But now it’s all fine 😉
This is very similar to Tadlocks Cleaner gallery
http://justintadlock.com/archives/2008/04/13/cleaner-wordpress-gallery-plugin
Thanks so much for the great info.
First of – great solution! I’m almost there..
How would I go about to add a class to the thumbnail images?
I’m trying to get them to work with a jquery plugin. I’ve managed everything but adding the class “thumb” to the a href.
Please advice.
zamson, add the class with jquery :p
Thanks for the tip Michael. I tried with the addClass selector but I guess the js gallery plugin does not understand the links when the html still does not output the whole code 🙁
Any ideas on how to add class to the thumnail image link from within wordpress?
Your suggestion to change wordpress default gallery function is awesome. I used it to completely reworked gallery style. And now it is working for my client very well.
Thank you very much, Michael!
@Nikita: Nice to hear 🙂
[…] Layout-Hilfen: matthewjamestaylor.com (3 Spalten Design) blog.spoongraphics.co.uk (Vektorgrafiken) wpengineer.com (Anleitung zur Modifikation der […]
is there a chance to get the first image thumbnail bigger than the rest of the galery images?
Thank you so much Michael —
I was getting so frustrated trying to track down the little bugger that was making my gallery pages not validate. Starting with your tip, my markup is actually semantic too!
Count me as a new subscriber!
Just wow. Thanks so much. Was struggling with getting Masonry to work with a WP gallery, and the embedded WP CSS was messing with the layout. Plugged this in, and VIOLA!
Much appreciated!
got this when i tryed to use your code on my functions.php :/
Warning: Invalid argument supplied for foreach()
@jaime Yeah, I get the exact same error in the foreach() line.
Using wordpress 3.0.4
Looking to add a class to the a tag for the images in my gallery, just a set specific class like class=”lightbox”. any ideas?
thanks
I didn’t even know what a dl/dt tag was before I tried to style the wp gallery. Then I ran into all kinds problems trying to style it correctly. Thanks for this!