admin管理员组文章数量:1122846
I use wp_list_pages()
to output all the child pages of the currently viewed page. This works well enough but I wanted to add the comment feed URL with an icon next to each child page.
My solution was to brute force it with a regular expression and a cheeky str_replace hack. It works. But it feels wrong that I was not able to identify a more WordPress way to do what I did. Like say, use some sort of basic template for the output.
Here's my current solution.
$string = '';
$meta_id = get_post_meta($post->ID,'meta',true);
$parent_meta_id = get_post_meta($post->post_parent,'meta',true);
if ( is_page() ){
$childpages = wp_list_pages( 'sort_column=post_name&title_li=&child_of=' . $post->ID . '&echo=0&depth=1&exclude='.$meta_id.','.$parent_meta_id );
}
if ( $childpages ) {
$rows = explode('</li>',$childpages);
$string = '<div class="subtopics container"><ul class="om_page_list list-unstyled card-columns" style="column-count: 3;">';
foreach($rows as $row){
$match = array();
if(''!=trim($row)){
preg_match_all('#\bhttps?://[^,\s()<>]+(?:\([\w\d]+\)|([^,[:punct:]\s]|/))#', $row, $match);
if(0<count($match)){
$feedlink = '<a href="'.$match[0][0].'feed/"><img src=".svg" style="width:1em;" title="Topic by RSS Feed"/></a>' ;
$row = str_replace('<a href', $feedlink.' <a href', $row);
}
$string .= $row;
}
}
$string.='</ul></div>';
}
You can see that I cludged the preg hack into the middle to add the extra link before the link. I noticed that there is a parameter link_before
but I could not figure out how to make that also carry the URL of the page (the feed URL is that plus "feed/"). I could have used it as a str_replace target but the string "<a href"
does that well enough if you remember to put it back after.
Is there a WordPress native way to get the same result?
I use wp_list_pages()
to output all the child pages of the currently viewed page. This works well enough but I wanted to add the comment feed URL with an icon next to each child page.
My solution was to brute force it with a regular expression and a cheeky str_replace hack. It works. But it feels wrong that I was not able to identify a more WordPress way to do what I did. Like say, use some sort of basic template for the output.
Here's my current solution.
$string = '';
$meta_id = get_post_meta($post->ID,'meta',true);
$parent_meta_id = get_post_meta($post->post_parent,'meta',true);
if ( is_page() ){
$childpages = wp_list_pages( 'sort_column=post_name&title_li=&child_of=' . $post->ID . '&echo=0&depth=1&exclude='.$meta_id.','.$parent_meta_id );
}
if ( $childpages ) {
$rows = explode('</li>',$childpages);
$string = '<div class="subtopics container"><ul class="om_page_list list-unstyled card-columns" style="column-count: 3;">';
foreach($rows as $row){
$match = array();
if(''!=trim($row)){
preg_match_all('#\bhttps?://[^,\s()<>]+(?:\([\w\d]+\)|([^,[:punct:]\s]|/))#', $row, $match);
if(0<count($match)){
$feedlink = '<a href="'.$match[0][0].'feed/"><img src="https://openmentions.com/wp-content/themes/openmention/Feed-icon.svg" style="width:1em;" title="Topic by RSS Feed"/></a>' ;
$row = str_replace('<a href', $feedlink.' <a href', $row);
}
$string .= $row;
}
}
$string.='</ul></div>';
}
You can see that I cludged the preg hack into the middle to add the extra link before the link. I noticed that there is a parameter link_before
but I could not figure out how to make that also carry the URL of the page (the feed URL is that plus "feed/"). I could have used it as a str_replace target but the string "<a href"
does that well enough if you remember to put it back after.
Is there a WordPress native way to get the same result?
Share Improve this question edited Jan 9, 2024 at 21:55 fuxia♦ 107k38 gold badges255 silver badges459 bronze badges asked Jan 9, 2024 at 21:24 Matthew Brown aka Lord MattMatthew Brown aka Lord Matt 1,0683 gold badges13 silver badges34 bronze badges1 Answer
Reset to default 1wp_list_pages() forwards the found pages array to walk_page_tree(), which uses Walker_Page to render the list, unless a custom walker instance is passed to wp_list_pages()
with array( 'walker' => $instance )
argument.
Walker_Page
is just an extension of WordPress' Walker class, which is used "for displaying various tree-like structures". The class has overwritable public methods for rendering the tree levels and elements - their starts and ends.
This means that we can create our own extension class from Walker_Page
and overwrite and modify the start_el() method to match our needs.
Here is an example where I first use the parent's method to render the list item to a temporary helper variable, then do a simple str_replace()
to add the feed link before the page link, and finally append the complete element html to the actual output, which is passed to the method by reference.
class WPSE_421764_Custom_Page_Walker extends Walker_Page
{
public function start_el( &$output, $data_object, $depth = 0, $args = array(), $current_object_id = 0 )
{
$element = '';
parent::start_el( $element, $data_object, $depth, $args, $current_object_id );
$page = $data_object;
$feed_link = sprintf(
'><a href="%1$s/feed">
<img src="https://openmentions.com/wp-content/themes/openmention/Feed-icon.svg" style="width:1em;" title="Topic by RSS Feed"/>
</a><a',
esc_attr( get_permalink( $page->ID ) )
);
$output .= str_replace( '><a', $feed_link, $element );
}
}
Walker_Page
uses <li%s><a%s>%s%s%s</a>
format with sprintf()
to create the element start and this is where ><a
comes from for the above str_replace()
.
I use string replacement here to avoid rewriting the whole method. If you want to customize the method from top to bottom, then I'd recommend using the Walker_Page::start_el()
source code as a reference and for inspiration.
And to make things a little cleaner, you can create a helper function to wrap the list rendering into a nice package.
function wpse_421764_child_pages_list( int $post_id, int $parent_id = 0 ): string {
$meta_id = get_post_meta( $post_id, 'meta', true );
$parent_meta_id = get_post_meta( $parent_id, 'meta', true );
$childpages = is_page( $post_id ) ? wp_list_pages( array(
'sort_column' => 'post_name',
'title_li' => '',
'child_of' => $post_id,
'echo' => 0,
'depth' => 1,
'walker' => new WPSE_421764_Custom_Page_Walker(),
'exclude' => implode( ',', array_filter( array( $meta_id, $parent_meta_id ) ) ),
) ) : '';
return $childpages ? sprintf(
'<div class="subtopics container">
<ul class="om_page_list list-unstyled card-columns" style="column-count: 3;">%s</ul>
</div>',
$childpages
) : '';
}
Usage,
echo wpse_421764_child_pages_list( $post->ID, $post->post_parent );
本文标签:
版权声明:本文标题:What's the WordPress way to get custom HTML for child pages list (with a second relative link)? Currently running regex 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736284046a1927166.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论