5

I know how it is possible to wrap HTML around anchor elements with the inbuilt arguments for wp_get_archives. Is there a way to alter the content of the anchors in order to add a wrapping span for the anchor text? The intention is to use it for a list of yearly archives on a category (i.e. an automated list of years for which posts exist).

Before:

<ul>
    <li><a href="xx">2014</a></li>
    <li><a href="xx">2015</a></li>
    <li><a href="xx">2016</a></li>
</ul>

After:

<ul>
    <li><a href="xx"><span>2014</span></a></li>
    <li><a href="xx"><span>2015</span></a></li>
    <li><a href="xx"><span>2016</span></a></li>
</ul>
7

Span outside anchor tags

I think you're looking for the before and after arguments (PHP 5.4+):

wp_get_archives(
    [
        'before' => '<span>',
        'after'  => '</span>'
    ]
);

if you want to wrap the <span> tag around the <a> tag:

<li><span><a href="xx">Link text</a></span></li>

Span inside anchor tags

If you want it inside the anchor tags:

<li><a href="xx"><span>Link text</span></a></li>

then you could use the get_archives_link filter to reconstruct the links to your needs.

Modify the corresponding theme file with (PHP 5.4+):

// Add a custom filter
add_filter( 'get_archives_link', 'wpse_get_archives_link', 10, 6 );

// Archive
wp_get_archives(
    [
        'type'   => 'yearly', // For yearly archive
        'format' => 'html'    // This is actually a default setting
    ]
);  // EDIT the arguments to your needs (I'm not showing the <ul> part here)

// Remove the custom filter
remove_filter( 'get_archives_link', 'wpse_get_archives_link', 10, 6 );

where our filter callback is defined, in the functions.php file in the current theme directory, as:

function wpse_get_archives_link(  $link_html, $url, $text, $format, $before, $after )
{
    if( 'html' === $format )
         $link_html = "\t<li>$before<a href='$url'><span>$text</span></a>$after</li>\n";

    return $link_html;
}

where we've added the span inside the anchor tag.

  • Thanks a lot so far, the second option is close to what I intended. However, two problems, possibly the first on my account: 1) When using get_archives_link in my template then puts the links out of context, possibly because of returning in the filter? 2) With get_archives_link I cannot have automatic YEARLY archive links, can I? The codex doesn't specify it is possible at all. – physalis Dec 5 '16 at 12:34
  • I'm not sure I understand what you mean by context and automatic here. Are you using the get_archives_link() function directly in your theme? You want to modify the wp_get_archives() only via filters from a plugin and not modify the theme? Can you give an example in your question? thanks @physalis – birgire Dec 5 '16 at 14:40
  • Hey @birgire, I was about to use wp_get_archives on a category archive page in order to have a list of clickable yearly archives within that archive. With its parameters, I can use wp_get_archives to do exactly that, but it is not possible to change the output of the text inside the anchor, so I could simply wrap a span around it :). As far as I understand, get_archives_link is meant to retrieve one specific archive link, at least not yearly archives? And yes, I tried to use get_archives_link within my template, but its output returned at the top of the source code. – physalis Dec 5 '16 at 16:56
  • NOW I got it. Your complete first block of code goes into the actual template, while the filter callback alone needs to go into my functions.php. This way, I can still use wp_get_archives with all parameters needed. I totally didn't get this point, and I thought I had to fiddle with the get_archives_link function! Can you please edit it to clarify, so I can mark your answer as right? Thanks again for your help!! – physalis Dec 6 '16 at 9:10
  • You're welcome - glad to hear you got this working. Yes that was the setup I had in mind, sorry if that wasn't clear from the beginning. I updated the answer. @physalis – birgire Dec 6 '16 at 9:49
-1

You can use custom query to modify html or add span

SELECT COUNT(ID) posts, YEAR(post_date) y, MONTH(post_date) m 
    FROM $wpdb->posts 
   WHERE post_status = 'publish'
GROUP BY y, m
  HAVING y = YEAR(NOW())
UNION
  SELECT COUNT(ID), YEAR(post_date) y, 0
    FROM $wpdb->posts
   WHERE post_status = 'publish'
GROUP BY y
  HAVING y < YEAR(NOW())
ORDER BY y DESC, m DESC;
  • 2
    Can you explain how it helps, afaik you are giving raw SQL here. – bravokeyl Dec 6 '16 at 8:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.