これを行うコードをfunctions.phpに追加します。
最初の段落に画像が含まれている場合は、その直後にカスタムコードを表示します。例えば:
<div class="entry-content">
<p><img src="http://example.com/example.jpg" alt="Image in 1st para" /></p>
<div>MY CUSTOM CODE</div>
</div>
しかし、最初の段落がテキスト(つまり画像ではない)の場合は、その前にカスタムコードを表示してください。
<div class="entry-content">
<div>MY CUSTOM CODE</div>
<p>This 1st paragraph contains text, not an image.</p>
</div>
どうすればいいのですか?サンプルコードスニペットは大歓迎です。
PS: /カスタムコードは広告(Google Adsenseなど)でもかまいません。
JQueryを使用した簡単な行はどうですか?
jQuery(document).ready( function ($) {
if ($(".entry-content:first-child").has('img').length) //this check for the img tag
$(".entry-content:first-child").after("<div>MY CUSTOM CODE</div>");
else
$(".entry-content:first-child").before("<div>MY CUSTOM CODE</div>");
});
更新:
これは、PHPのネイティブ DOMDocument
を使用した簡単なソリューションです。
add_filter('the_content','add_code_before_afterImage');
function add_code_before_afterImage($content){
$MYCODE = '<div>this is my custom code</div>';
$doc = new DOMDocument();
@$doc->loadHTML('<?xml encoding="'.get_bloginfo('charset').'">'.$content);
$ps = $doc->getElementsByTagName('p');
foreach ($ps as $p) {
if (false !== stripos($p->nodeValue,'img'));
return str_replace($p->nodValue, $p->nodValue.$MYCODE, $content);
}
break;
}
//if we got here then there is no img tag in the first paragraph
//so we return the code before the content.
return $MYCODE.$content;
}
更新2:
@Sarathiのコメントは、コンテンツの一部を実際に解析する必要はなく、最初の段落を取り出してimgタグがあるかどうかを確認する必要がないと思うので、PHPのネイティブstr_replace
およびstripos
add_filter('the_content','simple_img_tag_search');
function simple_img_tag_search($content){
$MYCODE = '<div>this is my custom code</div>';
//split content to first paragraph and the rest
$paragraphs = explode( '</p>', $content, 2 );
//extract the first paragraph
$first_paragraph = $paragraphs[0];
//then just look for img tag
if (false === stripos($first_paragraph, "<img")){
//not found then just return the code before the content
return $MYCODE.$content;
}else{
// img tag found so we return the code after the first paragraph
return str_replace($first_paragraph.'</p>',$first_paragraph.'</p>'.$MYCODE,$content);
}
}
最初の段落(<p>
)を捕らえるには、正規表現を使うことができます。それは 最適ではありません ですので、注意してください。 :)
次に、画像の一致をテストし、テスト結果に応じて追加のコンテンツを挿入します。ここでは、各ステップに1つずつ、合計2つの関数を使います。
// Late priority parameter to let shortcodes and other filters do their work first.
add_filter( 'the_content', 'wpse_52662_add_extra', 1000 );
/**
* Reads the content and calls a callback to add extra content.
*
* @param string $content
* @return string
*/
function wpse_52662_add_extra( $content )
{
// restrict to single posts:
if ( ! is_single() )
{
return $content;
}
return preg_replace_callback(
'~<p(>|\s+[^>]*>)(.*?)</p>~miU' // find <p>
, 'wpse_52662_callback' // pass the result to the callback
, $content
, 1 // stop after first match
);
}
/**
* Callback for wpse_52662_add_extra()
*
* @param array $m Matches. $m[0] contains the whole match,
* $m[2] the content of the paragraph.
* @return string
*/
function wpse_52662_callback( $m )
{
$extra = '<p><b>Hello World!</b></p>';
return ( FALSE === strpos( $m[2], '<img' ) ) ? $extra.$m[0] : $m[0].$extra;
}
DOMDocumentを使ってHTMLコンテンツを次のように解析できます。
add_filter( 'the_content', 'add_html_after_first_image' );
function add_html_after_first_image( $content ) {
$my_custom_html = '<div>MY CUSTOM CODE</div>';
// Create a dom document from the post content.
// The content needs to be wrapped in a root element to be valid xml, hence the div tags.
// I used loadXML because loadHTML adds the unnecessary <DOCTYPE>, <html>, and <body>.
if( $dom = DOMDocument :: loadXML( '<div>' . $content . '</div>' ) ) {
// Create a document fragment with your custom html.
$custom = $dom -> createDocumentFragment();
$custom -> appendXML( $my_custom_html );
// Get the root element, and first child.
$root = $dom -> firstChild;
$first = $root -> firstChild;
// Check if the first child is a paragraph, the first grandchild is an image,
// and if the paragraph has no content other than the image.
$has_image = 'p' == $first -> tagName
&& '' == trim( $first -> textContent )
&& 1 == count( $first -> childNodes )
&& 'img' == $first -> firstChild -> tagName;
// If $has_image is true then add the custom div after the first paragraph,
// otherwise add it before.
$root -> insertBefore( $custom, $has_image ? $first -> nextSibling : $first );
// Set the new content to the altered html.
$content = $dom -> saveHTML();
}
return $content;
}
編集:
これは上記の関数よりも速く走るように最適化された更新された関数です。
ヒント: <p>タグには、<img />タグ以外のコンテンツを含めないでください。 (空白も含みます)
add_filter( 'the_content', 'add_html_after_first_image' );
function add_html_after_first_image( $content ) {
$my_custom_html = '<div>MY CUSTOM CODE</div>';
// Explode the content to extract and parse only the first paragraph.
$parts = explode( '</p>', $content, 2 );
$p = $parts[0] . '</p>';
// Create a dom document from the first paragraph of content.
// I used loadXML because loadHTML adds the unnecessary <DOCTYPE>, <html>, and <body>.
// Checking for an opening <p> tag prevents the creation of a DOMDocument,
// and lowers the execution time on posts that don't start with a paragraph.
if( substr( $p, 0, 3 ) == '<p>' && $dom = @DOMDocument :: loadXML( $p ) ) {
// Create a document fragment with your custom html.
$custom = $dom -> createDocumentFragment();
$custom -> appendXML( $my_custom_html );
$first = $dom -> firstChild;
// Check if the first child is a paragraph, the first grandchild is an image,
// and if the paragraph has no content other than the image.
$has_image = 'p' == $first -> tagName
&& '' == $first -> textContent
&& 1 == count( $first -> childNodes )
&& 'img' == $first -> firstChild -> tagName;
// If $has_image is true then add the custom div after the first paragraph,
// otherwise add it before.
$dom -> insertBefore( $custom, $has_image ? $first -> nextSibling : $first );
// Set the new content to the altered html.
$p = $dom -> saveHTML();
}
// If the dom document could not be created, then the first element is not a
// paragraph and the custom code should be prepended to the content.
else $p = $my_custom_html . $p;
// Append the rest of the content to the paragraph.
return $p . $parts[1];
}