The question:
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?
The Solutions:
Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.
Method 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'); ?>" rel="nofollow noreferrer noopener">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'); ?>" rel="nofollow noreferrer noopener">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.
Method 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/
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0