WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

It seems like stupid question. But, I can't figure it out :(.

I need to display button at home that goes to custom post_type's archive URL (archive-{post_type}.php). How do I do that?

share|improve this question
What sort of button, add one to a nav menu, or just a generic link? The archive URL is generally yoursite.com/type-slug unless you explicitly set it to something else, eg. yoursite.com/some-other-url.. – t31os Mar 8 '11 at 23:30
@t31os: yup, right now, I hardcoded it like that. But, will soon change it using @Mike's code. – ariefbayu Mar 8 '11 at 23:51
up vote 21 down vote accepted

Hi @Silent:

Turns out there is a function in WordPress 3.1 that does exactly what you want and it is named get_post_type_archive_link(); here's how you'd call it (assuming a custom post type named 'product'):

<a href="<?php echo get_post_type_archive_link('product'); ?>">Products</a>

Below is my prior answer before I discovered that WordPress did indeed have a function built-in for this use case.

Prior Answer:

Unless I overlooked something in the core source code for WordPress 3.1 I think you are looking for a function like get_archive_link() which you might call like this (assuming a custom post type named 'product'):

<a href="<?php echo get_archive_link('product'); ?>">Products</a>

And here's the source code which you can place into your theme's function.php file or in a .php file for a plugin you might be writing:

if (!function_exists('get_archive_link')) {
  function get_archive_link( $post_type ) {
    global $wp_post_types;
    $archive_link = false;
    if (isset($wp_post_types[$post_type])) {
      $wp_post_type = $wp_post_types[$post_type];
      if ($wp_post_type->publicly_queryable)
        if ($wp_post_type->has_archive && $wp_post_type->has_archive!==true)
          $slug = $wp_post_type->has_archive;
        else if (isset($wp_post_type->rewrite['slug']))
          $slug = $wp_post_type->rewrite['slug'];
          $slug = $post_type;
      $archive_link = get_option( 'siteurl' ) . "/{$slug}/";
    return apply_filters( 'archive_link', $archive_link, $post_type );

I was actually working on this exact logic over the weekend although I'm not yet 100% sure the order of the logic is generically correct across all use-cases that WordPress might see although it will probably work for any specific site.

This is also a great thing to suggest be added to WordPress via trac which I think I will do later this evening.

share|improve this answer
Mike, you're the man! this is exactly what I need. – ariefbayu Mar 8 '11 at 23:50
btw, when you submit the trac, can you please, link it here. – ariefbayu Mar 8 '11 at 23:52
@silent - Yes, of course. – MikeSchinkel Mar 8 '11 at 23:59
@Mike - I'd have wrote something similar if you hadn't.... ;) I was wondering if this is what @silent had in mind, but the mention of a button had me thinking of something else.. – t31os Mar 9 '11 at 0:00
@t31os - I was working on the same logic this weekend for my URL routing plugin, so I had a head start. :) As for the button, you could add an answer to address that? – MikeSchinkel Mar 9 '11 at 0:08

when you register post type you can pass a string as slug with "has_archive" parameter and make sure you also set rewrite to either true or an array but not false and then your CPT archive URL would be http://www.YOURDOMAIN.com/has_archive_slug for example

if you set in your register_post_type for example:

$args = array(
    'labels' => $labels,
    'public' => true,
    'publicly_queryable' => true,
    'show_ui' => true, 
    'show_in_menu' => true, 
    'query_var' => true,
    'rewrite' => 'product',
    'capability_type' => 'post',
    'has_archive' => 'products', 
    'hierarchical' => false,
    'menu_position' => null,
    'supports' => array('title','editor','author','thumbnail','excerpt','comments')

then your single url is: http://www.YOURDOMAIN.com/product/postName and your archive url is: http://www.YOURDOMAIN.com/products/

share|improve this answer
Hooray. I had always thought has_archive was a boolean, but now I know it can be given a string, so my singular custom post type recipe can have a plural slug /recipes/ – Astrotim Dec 17 '14 at 0:30

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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