Suppose the editor on my admin dashboard creates the following HTML (when I print to the webpage using the_content()
:
<blockquote>Hello this is the best quote in the world!</blockquote>
<blockquote>Hello this is the second best quote in the world!</blockquote>
<blockquote>Hello this is the third best quote in the world!</blockquote>
<h2>This is a heading for a paragraph</h2>
<p>This is some paragraph.</p>
.
.
.
From this, I want to group together the quotes in a div
and group the rest of the content of the page in a separate div
. Something like this:
<div class="my-blockquotes">
<blockquote>Hello this is the best quote in the world!</blockquote>
<blockquote>Hello this is the second best quote in the world!</blockquote>
<blockquote>Hello this is the third best quote in the world!</blockquote>
</div>
<div class="main-content">
<h2>This is a heading for a paragraph</h2>
<p>This is some paragraph.</p>
.
.
.
</div>
Basically, is there a way to change the structure of the HTML that the_content()
generates? I tried searching about walker classes, but that's not available for the_content()
. I tried hacky fixes like using shortcodes, but could not come up with a solution.
Suppose the editor on my admin dashboard creates the following HTML (when I print to the webpage using the_content()
:
<blockquote>Hello this is the best quote in the world!</blockquote>
<blockquote>Hello this is the second best quote in the world!</blockquote>
<blockquote>Hello this is the third best quote in the world!</blockquote>
<h2>This is a heading for a paragraph</h2>
<p>This is some paragraph.</p>
.
.
.
From this, I want to group together the quotes in a div
and group the rest of the content of the page in a separate div
. Something like this:
<div class="my-blockquotes">
<blockquote>Hello this is the best quote in the world!</blockquote>
<blockquote>Hello this is the second best quote in the world!</blockquote>
<blockquote>Hello this is the third best quote in the world!</blockquote>
</div>
<div class="main-content">
<h2>This is a heading for a paragraph</h2>
<p>This is some paragraph.</p>
.
.
.
</div>
Basically, is there a way to change the structure of the HTML that the_content()
generates? I tried searching about walker classes, but that's not available for the_content()
. I tried hacky fixes like using shortcodes, but could not come up with a solution.
3 Answers
Reset to default 4You can use the_content
filter, to literally filter the content into your structure.
Somthing like this
<?php
add_filter('the_content',function($the_content){
// find blockquotes
$regex = '/<blockquote>(.+?)<\/blockquote>([\n|$])/i';
$blockquotes = preg_match_all($regex,$the_content,$matches);
// remove blockquotes
$main_content = preg_replace($regex,'',$the_content);
// rebuild blockqoutes
$my_blockquotes = '';
foreach ($matches[1] as $blockquote) {
$my_blockquotes .= "<blockquote>{$blockquote}</blockquote>";
}
// rebuild content
$new_content = '';
if (!empty($my_blockquotes)) {
$new_content = "
<div class='my-blockquotes'>
{$my_blockquotes}
</div>\n";
}
$new_content .= "
<div class='main-content'>
{$main_content}
</div>\n";
return $new_content;
});
but you'll notice this still might feel a little hacky as you're separating user-supplied content where unexpected user error can still happen. For example: line-breaks may be inconsistent between blockquotes.
You'd be better off creating a custom metabox and/or using post_meta to store these blockquotes individually, as meta data to the post. You can then throw them in before your content (with out parsing with regex) via the_content
still, or you can edit your template files of your theme, or hook into another action in your theme.
I did something similar - in my case, I was applying a class directly on any blockquote
tags using string replace.
<?php
$content = the_content();
$content = str_replace( "<blockquote>", "<blockquote class=\"quote\">", $content );
echo $content;
?>
Read more about string replace here: http://php.net/manual/en/function.str-replace.php
Came to this answer in my search to "rewrite" blockquotes in the_content and this in turn led me to a different solution using php domdocument functions which I'll post below for any possible help it may provide.
/**
* Add tweet link to blockquotes
*/
function my_blockquote_tweets( $the_content ) {
global $wp;
// Parse content
$document = new DOMDocument();
$document->loadHTML( $the_content );
$blockquotes = $document->getElementsByTagName('blockquote');
$svg = file_get_contents( get_stylesheet_directory() . '/resources/images/svg/social-logos/twitter.svg' );
foreach ($blockquotes as $blockquote) {
// Twitter Icon
$twitter_svg = $document->createDocumentFragment();
$twitter_svg->appendXML( $svg );
// Icon wrapper
$twitter_logo_wrapper = $document->createElement('span');
$twitter_logo_wrapper->setAttribute('class', 'tweet-logo');
$twitter_logo_wrapper->appendChild( $twitter_svg );
$tweet_text = substr($blockquote->nodeValue, 0, 250);
if( strlen( $tweet_text ) > 250 ) {
$tweet_text .= ' …';
}
$tweet = $document->createElement('a');
$tweet->setAttribute( 'class', 'tweet-this group' );
$tweet->setAttribute( 'title', __('Tweet this quote', 'pwa') );
$tweet->setAttribute( 'href', 'https://twitter.com/intent/tweet?text=' . urlencode( $tweet_text ) . '&url=%0A' . urlencode(home_url( $wp->request )));
$tweet->setAttribute( 'target', '_blank' );
$tweet->appendChild( $twitter_logo_wrapper );
$tweet_text = $document->createTextNode( __( 'Tweet this' , 'pwa' ) );
$tweet->appendChild( $tweet_text );
$blockquote->appendChild( $tweet );
}
$the_content = $document->saveHtml();
return $the_content;
}
add_filter('the_content', 'my_blockquote_tweets', 10, 1);
Hope it help someone.