I've a custom post type named "references" and I added a function so I can use the category as part of the permalink. I'm declaring the custom slug like so:
'slug' => '/references/%category%',
and then use a filter to manipulate it:
function change_post_link($post_link, $id = 0) {
$post = get_post($id);
if ($post->post_type == 'references') {
$terms = wp_get_object_terms($post->ID, 'category');
if ($terms) {
return str_replace('%category%', $terms[0]->slug, $post_link);
}
}
return $post_link;
}
That part works fine, I'm getting URLs like "/references/cars/the-red-one".
But now I can't have a page (the default type) at "/references/cars", it only works if I'm not using a placeholder for the custom post type.
Do you have any ideas how this could be solved? 'has_archive' is false btw.
Thanks!
You can use this way
Find Category Slug:
$categories = get_categories();
foreach ($categories as $cat)
{
$cat_slug = $cat->slug;
}
Create New URL:
$new_url = esc_url(add_query_arg(array( 'category' => $cat_slug,), $old_url));
It might not be the best solution but at least it works now. Here you go:
I've added a hidden dummy post type with the slug "references/dummy". This seems to force Wordpress to recognize the correct (debateable...) permalink structure.
Related
I have the CPT (Custom Post Type) "news".
In the "category" taxonomy I have "food" and "health".
The archive page is accessed via the url:
www.mysite.com/news
Is there any way to show "news" by categories? Ex:
www.mysite.com/food/news
www.mysite.com/health/news
Thank you all in advance.
In that link I found the following solution:
The solution for me had three parts. In my case the post type is called trainings.
Add 'rewrite' => array('slug' => 'trainings/%cat%') to the
register_post_type function.
Change the slug to have a dynamic
category. "Listen" to the new dynamic URL and load the appropriate template.
So here is how to change the permalink dynamically for a given post type. Add to functions.php:
function vx_soon_training_post_link( $post_link, $id = 0 ) {
$post = get_post( $id );
if ( is_object( $post ) ) {
$terms = wp_get_object_terms( $post->ID, 'training_cat' );
if ( $terms ) {
return str_replace( '%cat%', $terms[0]->slug, $post_link );
}
}
return $post_link;
}
add_filter( 'post_type_link', 'vx_soon_training_post_link', 1, 3 );
...and this is how to load the appropriate template on the new dynamic URL. Add to functions.php:
function archive_rewrite_rules() {
add_rewrite_rule(
'^training/(.*)/(.*)/?$',
'index.php?post_type=trainings&name=$matches[2]',
'top'
);
//flush_rewrite_rules(); // use only once
}
add_action( 'init', 'archive_rewrite_rules' );
Thats it! Remember to refresh the permalinks by saving the permalinks again in de backend. Or use the flush_rewrite_rules() function.
But I have a question that I couldn't do there:
This part:
Add 'rewrite' => array('slug' => 'trainings/%cat%') to the register_post_type function.
where do I do that? Or is this already embedded in the later code?
Probably it is something obvious and has escaped under my nose.
I did not understand how to hook my extended class to timber.
Let's take the example of the issues. How can I get an object like MySitePost when I call Timber::query_post()?
So now I’ve got an easy way to refer to the {{ post.issue }} in our twig templates.
Looks like an automatic process... but I'm not so sure about this!
For reference:
https://timber.github.io/docs/guides/extending-timber/
I think this is a good question that might not be so obvious.
To use your custom post, you’ll often find a parameter when fetching posts where you can pass the name of your custom class. The returned object will then be instances of your custom class.
$posts = Timber::get_posts( $your_args, 'MySitePost' );
$posts = new Timber\PostQuery( $your_args, 'MySitePost' );
When you want to fetch a single post, it works quite similar. You can either directly instantiate your post or pass your post class to the function.
$post = new MySitePost();
$post = Timber::get_post( $post_id, 'MySitePost' );
If you want to set a default class to be used for your posts, you can use the Timber\PostClassMap filter:
// Use one class for all Timber posts.
add_filter( 'Timber\PostClassMap', function( $post_class, $post_type ) {
return 'MySitePost';
}, 10, 2 );
// Use default class for all post types, except for pages.
add_filter( 'Timber\PostClassMap', function( $post_class, $post_type ) {
// Bailout if not a page
if ( 'page' !== $post_type ) {
return $post_class;
}
return 'MySitePost';
}, 10, 2 );
// Use a class map for different post types
add_filter( 'Timber\PostClassMap', function( $post_class, $post_type ) {
return array(
'post' => 'MySitePost',
'apartment' => 'MyApartmentPost',
'city' => 'MyCityPost',
);
}, 10, 2 );
I'm trying to limit my WordPress search to a single, custom post type.
It seems I can change most parameters of the search query, except the post type variable.
$query_args = explode("&", $query_string);
$search_query = array();
foreach($query_args as $key => $string) {
$query_split = explode("=", $string);
$search_query[$query_split[0]] = urldecode($query_split[1]);
}
$search_query['post_type'] = 'thread';
$search = new WP_Query($search_query);
This query will still return all post types. But if I set a different parameter, like 'posts_per_page', it works fine.
What's going on? How can I limit my search query to a custom post type?
Thanks for your help!
EDIT: btw, I'm using WP 3.4.2
Place this in your functions.php file. :)
<?php
add_filter('pre_get_posts', 'filter_search_cpt_threads');
/** filter search for threads CPT */
function filter_search_cpt_threads($query)
{
if( $query->is_search ) $query->set('post_type', array('thread'));
return $query;
}
?>
Best!
R
I have searched, here is the closes result.
I am building a new wordpress site. I want most posts to have no category in the URL, simply www.site.com/title. However I do want the blog posts to be separate, so I'd like www.site.com/blog/title. I'd also like the option to add more like that in the future, for only specific categories, not the entire site.
There are many questions similar to this here on stackoverflow but most have 0 replies. Any advice would be great. I've even tried Advanced Permalinks without any luck.
You can simply do that by Setting > Permalinks and add to Common Setting > Custom Structure the value /blog/%postname%/. There you will get the blog post accessible from www.site.com/blog/title.
I cannot understand the first question. By:
I want most posts to have no category in the URL
do you mean to NOT HAVING www.site.com/category/category-name? or not having www.site.com/category/post?
EDIT #1
To answer this:
www.site.com/category/post is what I ONLY want for blog posts with the category of "Blog" > if the category is "Shoes" I don't want the category displayed in the URL. –
First: you can set the Permalink to /%postname%/ so all your post will have site/title therefore accessible from that link
Second: You have to filter the permalink to behave differently for the posts under "Blog" category.
Try this
add_filter( 'post_link', 'custom_permalink', 10, 2 );
function custom_permalink( $permalink, $post ) {
// Get the categories for the post
$categories = wp_get_post_categories( $post->ID );
foreach ( $categories as $cat ) {
$post_cat = get_category( $cat );
$post_cats[] = $post_cat->slug;
}
// Check if the post have 'blog' category
// Assuming that your 'Blog' category slug is 'blog'
// Change 'blog' to match yours
if ( in_array( 'blog',$post_cats ) ) {
$permalink = trailingslashit( home_url( 'blog/' . $post->post_name ) );
}
return $permalink;
}
Third: You have to filter rewrite_rules
add_filter( 'rewrite_rules_array', 'custom_rewrite_rule' );
function custom_rewrite_rule( $rules ) {
$new_rules = array(
'blog/([^/]+)/trackback/?$' => 'index.php?name=$matches[1]&tb=1',
'blog/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$' => 'index.php?name=$matches[1]&feed=$matches[2]',
'blog/([^/]+)/(feed|rdf|rss|rss2|atom)/?$' => 'index.php?name=$matches[1]&feed=$matches[2]',
'blog/([^/]+)/comment-page-([0-9]{1,})/?$' => 'index.php?name=$matches[1]&cpage=$matches[2]',
'blog/([^/]+)(/[0-9]+)?/?$' => 'index.php?name=$matches[1]&page=$matches[2]'
);
$rules = $new_rules + $rules;
return $rules;
}
Go to permalink setting and save the setting to refresh your rewrite rules and make the changes above active
NOTE: Add those functions on your active theme functions.php template
NOTICE: I haven't test it yet but that's the way you change permalink. I did the similar way to change my permalink on archives and search result.
(This post has been submitted on the Yootheme forums but I don't have as much confidence in a solution so I thought I'd post it here too.)
I'm using the Nano theme from Yoothemes and its working great for 90% of my site. http://dofekit.org However I've just installed the bbPress forum plugin (not on the live site, but a local version) and I have created 2 'forums'. The forum index page and all sub-pages seem to be inserted into a standard Nano page template. This is not suitable for the forum as it includes the page meta information and also I see no way of turning off 'sidebar-a' for the forums as my screenshot demonstrates.
http://dl.dropbox.com/u/240752/forums.jpg
Is there a way of creating a separate template for the forum post type within the yoothemes framework? ( I know its kind of proprietary but I can but ask)
Thanks.
UPDATE:
I'm part of the way there. I've manged to make separate templates for my forum post types like so, but I still need to get the custom post types to be acknowledged in the widget settings.
I've added the custom post types in warp/systems/wordpress3.0/layouts/content.php
if (is_home()) {
$content = 'index';
} elseif (is_page()) {
$content = 'page';
} elseif (is_attachment()) {
$content = 'attachment';
} elseif ((is_single()) && (get_post_type() == 'forum')) {
$content = 'forum-single';
}elseif ((is_single()) && (get_post_type() == 'topic')) {
$content = 'topic-single';
} elseif (is_single()) {
$content = 'single';
} elseif (is_search()) {
$content = 'search';
}elseif ((is_archive()) && (get_post_type() == 'forum')) {
$content = 'forum-archive';
} elseif (is_archive() && is_author()) {
$content = 'author';
} elseif (is_archive()) {
$content = 'archive';
} elseif (is_404()) {
$content = '404';
}
I've also added these custom post types into
warp/systems/wordpress3.0/config/layouts/fields/profile.php
in an effort to get them to appear in the dropdown lists on each widget. (I want to be able to toggle widgets on these new custom templates.)
$defaults = array(
'home' => 'Home',
'archive' => 'Archive',
'search' => 'Search',
'single' => 'Single',
'page' => 'Pages',
'forum-archive' => 'Forum List',
'forum-single' => 'Forum Single',
'topic-single' => 'Topic Single'
);
Can anyone please help? I think I'm almost there with this.
You should be able to handle this using a WordPress Template for your custom post type for single post display.
For example if your custom post type is called "product" create a template called single-product.php e.g. single-{post_type}.php
This solution should work irrespective of Yoothemes framework, Let me know if that works!
i'm not shure if my answer can help you but...
My code add the Custom Taxonomy categories to the widget position...
I edit the file warp/systems/wordpress/config/layouts/fields/style.php
and I add this lines for each custom taxonomy =)
// set Eventos cate
if ($categories = get_categories(array('hide_empty' => 0, 'name' => 'select_name', 'post_type' => 'event', 'taxonomy' => 'event-category'))) {
$options[] = '<optgroup label="Eventos | Categorias">';
foreach ($categories as $category) {
$val = 'cat-'.$category->cat_ID;
$attributes = in_array($val, $selected) ? array('value' => $val, 'selected' => 'selected') : array('value' => $val);
$options[] = sprintf('<option %s />%s</option>', $control->attributes($attributes), $category->cat_name);
}
$options[] = '</optgroup>';
}
Here... my postype is "event" and my taxonomy is "event-category" in the list of the widget position now you can see all the Categories or Terms of the Taxonomy and y label it with "Eventos | Categorias" for a better identification.
Ok this is only one part of the code and maybe you can take this like a point to start. Now i just can display and list this terms but still nok working :(
so... tnks for the comments and sorry for my english :P