Get custom post_type’s archive URL

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?

Related posts

Leave a Reply

2 comments

  1. 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'];
            else
              $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.

  2. 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')
      ); 
     register_post_type('product',$args);
    

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