I’ve tinkered with WordPress a little, but I’m far from an expert, so apologies in advance if this is a duplicate question.
I’ve built a simple WordPress theme based around Bootstrap, and I can successfully display posts using the_content()
, while filling in the sidebar using get_sidebar()
.
My question is whether it’s possible to tag a specific section of a post, and have that section handled differently than the rest of the_content()
. Here’s an example:
Here’s some pseudo-code:
<?php get_header(); ?>
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<div class="row">
<div class="col-md-12">
<!--tag one image within the post, to appear across all 12 columns-->
</div>
</div>
<h1><?php the_title(); ?></h1>
<div class="row">
<div class="col-md-8">
<!--the rest of the post, minus the tagged image, goes here-->
<?php the_content(); ?>
</div>
<div class="col-md-4">
<?php get_sidebar(); ?>
</div>
</div>
<?php endwhile; else: ?>
<p><?php _e('Sorry, no posts matched your criteria.'); ?></p>
<?php endif; ?>
<?php get_footer(); ?>
In this case I’d like to tag (or otherwise identify) one image from the post, and have that appear in the col-md-12 div, with the rest of the post going into the col-md-8 div.
I’ve read about the_excerpt()
but I don’t believe that will work here.
2 Answers
You can make use of featured images as suggested by @gmazzap in comments. This featured image will not be included in post content. However, if you already have your images included in post content, then you need to strip the post content down in two parts, as you’ve said in your question.
I have two functions, one that returns all the images (or any html tag content) from the content and one function that returns the text without the desired tag/images. Both of these functions uses DOMDocument
The first function get_content_without_tag()
returns the content which has been stripped from images. There are two parameters
-
$html
-> The text with images to be stripped, in this case, useapply_filters( 'the_content', get_the_content() )
to use the post content -
$tag
-> The name of the tag to strip out, in this case, ‘a’ asa
tags hold images
Here is the function
function get_content_without_tag( $html, $tag )
{
$dom = new DOMDocument;
$dom->loadHTML( $html );
$dom_x_path = new DOMXPath( $dom );
while ($node = $dom_x_path->query( '//' . $tag )->item(0)) {
$node->parentNode->removeChild( $node );
}
return $dom->saveHTML();
}
You would then use this in place of the_content()
where you would need to display text only, stripping out the complete <a/>
tag in which the images are as follows
echo get_content_without_tag( apply_filters( 'the_content', get_the_content() ), 'a' )
The second function, get_tag_without_text()
returns the content between the desired tag, in your case, images. The parameters are exactly the same as the first function. Here is the function
function get_tag_without_text( $html, $tag )
{
$document = new DOMDocument();
$document->loadHTML( $html );
$tags = [];
$elements = $document->getElementsByTagName( $tag );
if ( $elements ) {
foreach ( $elements as $element ) {
$tags[] = $document->saveHtml($element);
}
}
return $tags;
}
This function returns an array of images should you use a
tags, so, to display the first image, use the function as follow:
$image = get_tag_without_text( apply_filters( 'the_content', get_the_content() ), 'a' );
echo $image[0];
Just one final tip on your code, move your call the side bar outside your loop. It should go just above the call to the footer