WordPress - Custom Taxonomies on CPT aren't displaying correctly - wordpress

I have a custom post type called 'activity' and a custom taxonomy called 'category_activity'.
On single-activity.php I am wanting to display the current taxonomy. At the moment, all taxonomies are being displayed even if they aren't added to the post.
single-activity.php:
$taxonomy = 'category_activity';
$terms = get_terms($taxonomy);
if ( $terms ) {
foreach ( $terms as $term ) { echo $term->name; }
}
Should display: 'Taxonomy Name 1'
Currently displays: 'Taxonomy Name 1 Taxonomy Name 2 Taxonomy Name 3'.
Taxonomy registration:
function cptui_register_my_taxes_category_activity() {
$labels = array(
"name" => __( 'Things Categories', '' ),
"singular_name" => __( 'Things Category', '' ),
);
$args = array(
"label" => __( 'Things Categories', '' ),
"labels" => $labels,
"public" => true,
"hierarchical" => true,
"label" => "Things Categories",
"show_ui" => true,
"show_in_menu" => true,
"show_in_nav_menus" => true,
"query_var" => true,
"rewrite" => array( 'slug' => 'things-to-do/category', 'with_front' => false, ),
"show_admin_column" => false,
"show_in_rest" => false,
"rest_base" => "",
"show_in_quick_edit" => false,
);
register_taxonomy( "category_activity", array( "activity" ), $args );
}
add_action( 'init', 'cptui_register_my_taxes_category_activity' );
Thanks for the help.
EDIT - I got this working with:
$category = wp_get_post_terms($post->ID, 'category_activity');
echo $category[0]->name;

It would be better to use wp_get_post_terms in your case :
https://codex.wordpress.org/Function_Reference/wp_get_post_terms
<?php $terms = wp_get_post_terms( $post_id, $taxonomy, $args ); ?>

Related

WordPress isn't replacing the rewrite slug for custom post URLS

Visiting https://website.com/albert/books does display all the books by this author. but the retrieved URL from WordPress for listed books would be https://website.com/%author%/books/ideas-and-opinions/
I created a custom post type named books and custom taxonomy named author, I did flush the permalinks by saving them but the issue is the get_permalink wordpress function still gives me the rewrite query which I believe it should be replaced.
function cptui_register_my_cpts_book() {
/**
* Post Type: Books.
*/
$labels = array(
"name" => __( "Books", "my-theme" ),
"singular_name" => __( "Book", "my-theme" ),
"menu_name" => __( "Books", "my-theme" ),
"all_items" => __( "All Books", "my-theme" ),
"add_new_item" => __( "Add New Book", "my-theme" ),
"edit_item" => __( "Edit Book", "my-theme" ),
"new_item" => __( "New Book", "my-theme" ),
"view_item" => __( "View Book", "my-theme" ),
"view_items" => __( "View Books", "my-theme" ),
"search_items" => __( "Search Book", "my-theme" ),
"not_found" => __( "No books found", "my-theme" ),
);
$args = array(
"label" => __( "Books", "my-theme" ),
"labels" => $labels,
"description" => "",
"public" => true,
"publicly_queryable" => false,
"show_ui" => true,
"delete_with_user" => false,
"show_in_rest" => true,
"rest_base" => "",
"rest_controller_class" => "WP_REST_Posts_Controller",
"has_archive" => true,
"show_in_menu" => true,
"show_in_nav_menus" => true,
"exclude_from_search" => true,
"capability_type" => "post",
"map_meta_cap" => true,
"hierarchical" => false,
"rewrite" => array( "slug" => "/%author%/books", "with_front" => false ),
"query_var" => true,
"menu_icon" => "/wp-content/uploads/2023/02/books.webp",
"supports" => array( "title", "thumbnail" ),
"taxonomies" => array( "author" ),
);
register_post_type( "book", $args );
}
add_action( 'init', 'cptui_register_my_cpts_book' );
function cptui_register_my_taxes() {
/**
* Taxonomy: Authors.
*/
$labels = array(
"name" => __( "Authors", "my-theme" ),
"singular_name" => __( "Author", "my-theme" ),
);
$args = array(
"label" => __( "Authors", "my-theme" ),
"labels" => $labels,
"public" => true,
"publicly_queryable" => true,
"hierarchical" => true,
"show_ui" => true,
"show_in_menu" => true,
"show_in_nav_menus" => false,
"query_var" => true,
"rewrite" => array( 'slug' => 'author', 'with_front' => true, ),
"show_admin_column" => true,
"show_in_rest" => true,
"rest_base" => "author",
"rest_controller_class" => "WP_REST_Terms_Controller",
"show_in_quick_edit" => true,
);
register_taxonomy( "author", array( "book" ), $args );
}
add_action( 'init', 'cptui_register_my_taxes' );
And here is my re-write rule in functions
function add_book_rewrite_rules() {
add_rewrite_rule(
'^([^/]+)/books/?$',
'index.php?author=$matches[1]&post_type=book',
'top'
);
}
add_action( 'init', 'add_book_rewrite_rules' );
function add_book_query_vars( $vars ) {
$vars[] = 'author';
return $vars;
}
add_filter( 'query_vars', 'add_book_query_vars' );
Books query
$author = get_query_var( 'author' );
$args = array(
'post_type' => 'book',
'tax_query' => array(
array(
'taxonomy' => 'author',
'field' => 'slug',
'terms' => $author
)
),
'posts_per_page' => -1
);
$books = new WP_Query( $args );
// Loop and display esc_url( get_permalink() ) to get the URL
You could add a function that will update the link for that post type using post_type_link hook it will update https://website.com/%author%/books/ideas-and-opinions/ to https://website.com/albert/books/ideas-and-opinions/ adding author name to the URL.
function modify_book_permalink( $post_link, $post, $leavename ) {
if ( $post->post_type == 'book' ) {
$terms = wp_get_post_terms( $post->ID, 'author' );
$author_slug = $terms[0]->slug;
$post_link = str_replace( '%author%', $author_slug, $post_link );
}
return $post_link;
}
add_filter( 'post_type_link', 'modify_book_permalink', 10, 3 );

how can i add post-categories list in elementor custom widget

My control code is
i want to create control in elementor which shows all post categories. please help me how can i achieve this...
enter image description here
$this->add_control(
'show_elements',
[
'label' => __( 'Post Categoris', 'plugin-domain' ),
'type' => \Elementor\Controls_Manager::SELECT2,
'multiple' => true,
'options' => [
$category,
],
]
); ```
You can use WP get_categories() to get all categories. check below code.
$options = array();
$args = array(
'hide_empty' => false,
);
$categories = get_categories($args);
foreach ( $categories as $key => $category ) {
$options[$category->term_id] = $category->name;
}
$this->add_control(
'show_elements',
[
'label' => __( 'Post Categoris', 'plugin-domain' ),
'type' => \Elementor\Controls_Manager::SELECT2,
'multiple' => true,
'options' => $options,
]
);

Add custom taxonomy term in woocommerce REST API

I have created custom taxonomy "Brands" and attached to woocommerce products. Unfortunately, It is not available in woocommerce REST API response.
How to attach custom taxonomy term to woocommerce rest API. Currently there is no documentation about attachment of custom taxonomy. Is there any hook or filter ?
I solved by using this code.You will be able to GET and Update custom taxonomy by using this method. Basically. You can add this code in functions.php file or in plugin.
Step:1
Replace brands with your taxonomy_name.
Step:2
If your taxonomy have custom fields, replace custom_field_name with yours.
Taxonomy Code:
add_action( 'init', 'create_brands_hierarchical_taxonomy', 0 );
//create a custom taxonomy name it topics for your posts
function create_brands_hierarchical_taxonomy() {
// Add new taxonomy, make it hierarchical like categories
//first do the translations part for GUI
$labels = array(
'name' => _x( 'Brands', 'taxonomy general name' ),
'singular_name' => _x( 'Brand', 'taxonomy singular name' ),
'search_items' => __( 'Search Brands' ),
'all_items' => __( 'All Brands' ),
'parent_item' => __( 'Parent Brand' ),
'parent_item_colon' => __( 'Parent Brand:' ),
'edit_item' => __( 'Edit Brand' ),
'update_item' => __( 'Update Brand' ),
'add_new_item' => __( 'Add New Brand' ),
'new_item_name' => __( 'New Brand Name' ),
'menu_name' => __( 'Brands' ),
);
$capabilities = array(
'manage_terms' => 'manage_woocommerce',
'edit_terms' => 'manage_woocommerce',
'delete_terms' => 'manage_woocommerce',
'assign_terms' => 'manage_woocommerce',
);
// Now register the taxonomy
$args = array(
'labels' => $labels,
'show_in_rest' => true,
'hierarchical' => true,
'public' => true,
'show_ui' => true,
'show_admin_column' => false,
'show_in_nav_menus' => true,
'show_tagcloud' => true,
'capabilities' => $capabilities,
);
register_taxonomy( 'brands', array( 'product' ), $args );
register_taxonomy_for_object_type( 'brands', 'product' );
}
Register Taxonomy API for WC
//Register taxonomy API for WC
add_action( 'rest_api_init', 'register_rest_field_for_custom_taxonomy_brands' );
function register_rest_field_for_custom_taxonomy_brands() {
register_rest_field('product', "brands", array(
'get_callback' => 'product_get_callback',
'update_callback' => 'product_update_callback',
'schema' => null,
));
}
//Get Taxonomy record in wc REST API
function product_get_callback($post, $attr, $request, $object_type)
{
$terms = array();
// Get terms
foreach (wp_get_post_terms( $post[ 'id' ],'brands') as $term) {
$terms[] = array(
'id' => $term->term_id,
'name' => $term->name,
'slug' => $term->slug,
'custom_field_name' => get_term_meta($term->term_id, 'custom_field_name', true)
);
}
return $terms;
}
//Update Taxonomy record in wc REST API
function product_update_callback($values, $post, $attr, $request, $object_type)
{
// Post ID
$postId = $post->get_id();
//Example: $values = [2,4,3];
// Set terms
wp_set_object_terms( $postId, $values , 'brands');
}
Solution above is working but you have to change the
$postId = $post->get_id();
with
$postId = $post->ID;
Took me ages to find out why update_callback did not work : $values contains the taxonomy-structure and is therefore too complex to pass as integer to wp_set_object_terms. You have to strip it to the numeric ID's only otherwise [null] is assigned
//Update Taxonomy record in wc REST API
function product_update_callback_Leerjaar($values, $post, $attr, $request, $object_type)
{
// Post ID
$postId = $post->id;
//Example: $values = [2,4,3];
error_log("debug on values");
error_log(json_encode($values));
$numarray = [];
foreach($values as $value){
$numarray[] = (int)$value['id'];
}
wp_set_object_terms( $postId, $numarray , 'brands');
}
If anyone has tested all the above and can't get it to work, I found a simplest and working solution, based on Taha Farooqui's answer and the wordpress register_rest_field documentation :
add_action( 'rest_api_init', 'register_rest_field_for_custom_taxonomy_brands');
function register_rest_field_for_custom_taxonomy_brands() {
register_rest_field('product', "field_rest_name",
array("get_callback" => function ($post) {
$taxonomy = wp_get_post_terms( $post['id'], 'your_taxonomy_name');
return $taxonomy;
}
)
);
}
After months of testing trying to prove why the product_update_callback() function returned a null value, he got a version that loads the taxonomy values ​​from the woocommerce Rest Api v3 only with the name and slug..
<?php
//Prevent a malicious user from executing php code from the browser bar
defined('ABSPATH') or die( "Bye bye" );
add_action( 'init', 'create_brands_hierarchical_taxonomy', 0 );
//create a custom taxonomy name it topics for your posts
function create_brands_hierarchical_taxonomy() {
// Add new taxonomy, make it hierarchical like categories
$labels = array(
'name' => _x( 'Marcas', 'taxonomy general name' ),
'singular_name' => _x( 'Marca', 'taxonomy singular name' ),
'search_items' => __( 'Buscar Marcas' ),
'all_items' => __( 'Todas las Marcas' ),
'parent_item' => __( 'Marca Relacionada' ),
'parent_item_colon' => __( 'Marca Relacionada:' ),
'edit_item' => __( 'Editar Marca' ),
'update_item' => __( 'Subir Marca' ),
'add_new_item' => __( 'Añadir Nueva Marca' ),
'new_item_name' => __( 'Nuevo Nombre de Marca' ),
'menu_name' => __( 'Marcas' ),
);
$capabilities = array(
'manage_terms' => 'manage_woocommerce',
'edit_terms' => 'manage_woocommerce',
'delete_terms' => 'manage_woocommerce',
'assign_terms' => 'manage_woocommerce',
);
// Now register the taxonomy
$args = array(
'labels' => $labels,
'show_in_rest' => true,
'hierarchical' => true,
'public' => true,
'show_ui' => true,
'show_admin_column' => false,
'show_in_nav_menus' => true,
'show_tagcloud' => true,
'capabilities' => $capabilities,
);
register_taxonomy( 'pwb-brand', array( 'product' ), $args );
register_taxonomy_for_object_type( 'pwb-brand', 'product' );
}
//Register taxonomy API for WC
add_action( 'rest_api_init', 'register_rest_field_for_custom_taxonomy_brands' );
function register_rest_field_for_custom_taxonomy_brands() {
register_rest_field('product', "pwb-brand", array(
'get_callback' => 'product_get_callback_brand',
'update_callback' => 'product_update_callback_brand',
'schema' => null,
));
}
//Get Taxonomy record in wc REST API
function product_get_callback_brand($post, $attr, $request, $object_type){
$terms = array();
// Get terms
foreach (wp_get_post_terms( $post[ 'id' ],'pwb-brand') as $term) {
$terms[] = array(
'id' => $term->term_id,
'name' => $term->name,
'slug' => $term->slug,
);
}
return $terms;
}
//Update Taxonomy record in wc REST API
function product_update_callback_brand($values, $post, $attr, $request, $object_type){
// Post ID
$postId = $post->id;
$terms = $values;
$termName = $terms[0]['name'];
$termSlug = $terms[0]['slug'];
wp_insert_term( $termName, 'pwb-brand', array( 'slug' => $termSlug ) );
error_log("debug on values");
error_log(json_encode($values));
$newTermId = get_term_by('slug',$termSlug,'pwb-brand')->term_id;
array_push($values, array('id' => (int)$newTermId));
$numarray = [];
foreach($values as $value){
if(is_numeric($value['id'])){
$numarray[] = (int)$value['id'];
}
}
wp_set_object_terms( $postId, $numarray , 'pwb-brand');
}
After so much testing he understood that the values ​​that pass through the product_get_callback_brand function are mandatory to register a taxonomy so if you add a custom field like in the first example then they must be loaded so that the taxonomy can be retrieved.
It is worth noting that it is not a valid field for image fields or galleries that will not have the permissions to be loaded by the Rest Api v3 of woocommerce

Creating a custom post type and subpages with same slug

I made a custom post type with the 'has_archive' to 'false' to be able to create a page with the same slug as the custom post type: 'Test'.
I want to create subpages / child pages for the 'Test' page but i receive error 404 page.
There is a way to prioritize pages over custom post type?
add_action( 'init', 'cptui_register_my_cpts_test' );
function cptui_register_my_cpts_test() {
$labels = array(
"name" => __( 'Test', 'test' ),
"singular_name" => __( 'Test', 'test' ),
);
$args = array(
"label" => __( 'Test', 'test' ),
"labels" => $labels,
"description" => "",
"public" => true,
"publicly_queryable" => true,
"show_ui" => true,
"show_in_rest" => false,
"rest_base" => "",
"has_archive" => false,
"show_in_menu" => true,
"exclude_from_search" => false,
"capability_type" => "post",
"map_meta_cap" => true,
"hierarchical" => true,
"rewrite" => array( 'slug' => 'test'),
"query_var" => true,
"supports" => array( "title", "editor", "thumbnail" ),
);
register_post_type( "test", $args );
}
function custom_rada_type() {
$labels = array(
'name' => 'Porady',
'singular_name' => 'Porady',
'menu_name' => 'Porady',
'parent_item_colon' => 'Kategoria rodzica',
'all_items' => 'Wszystkie porady',
'view_item' => 'Wyświetl poradę',
'add_new_item' => 'Dodaj poradę',
'add_new' => 'Dodaj poradę',
'edit_item' => 'Edytuj poradę',
'update_item' => 'Zaktualizuj poradę',
'search_items' => 'Wyszukaj poradę',
'not_found' => 'Nie znaleziono',
'not_found_in_trash' => 'Nie znaleziono w koszyku',
);
$args = array(
'label' => 'rada',
'description' => 'Szablony porad',
'labels' => $labels,
'supports' => array( 'title', 'editor', 'thumbnail', 'comments' ),
'taxonomies' => array( '' ),
'hierarchical' => false,
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'show_in_nav_menus' => true,
'show_in_admin_bar' => true,
'can_export' => true,
'has_archive' => 'porady',
'rewrite' => array( 'slug' => 'porady', 'with_front' => false ),
'exclude_from_search' => false,
'publicly_queryable' => true,
'capability_type' => 'post',
'menu_icon' => 'dashicons-editor-help',
);
register_post_type( 'rada', $args );
}
add_action( 'init', 'custom_rada_type', 0 );
Create custom post type
Create Page with slug - porady
Add rewrite rule
add_action('init', function () {
add_rewrite_rule('porady/?$','index.php?pagename=porady', 'top');
flush_rewrite_rules();
}, 1000);
After change Flush you permalinks at "Settings > Permalinks"
And you will receive - site.com/porady(page with slug porady) and site.com/porady/article(custom post article)
Sally CJ has answered this question and worked fine!
just add this function to function.php
https://wordpress.stackexchange.com/a/396970/60877
add_action( 'parse_request', 'my_parse_request' );
function my_parse_request( $wp ) {
$post_type = 'rada'; // set the post type slug
// and the "porady" below is the Page slug
// This code checks if the path of the current request/page URL begins with
// "porady/" as in https://example.com/porady/child-page-name and also
// https://example.com/porady/child-page-name/page/2 (paginated request).
// We also check if the post_type var is the post type set above.
if ( preg_match( '#^porady/#', $wp->request ) &&
isset( $wp->query_vars['post_type'], $wp->query_vars['name'] ) &&
$post_type === $wp->query_vars['post_type']
) {
$posts = get_posts( array(
'post_type' => 'page',
'name' => $wp->query_vars['name'],
) );
// If a (child) Page with the same name/slug exists, we load the Page,
// regardless the post type post exists or not.
if ( ! empty( $posts ) ) {
$wp->query_vars['pagename'] = get_page_uri( $posts[0] );
unset( $wp->query_vars['post_type'], $wp->query_vars['name'],
$wp->query_vars[ $post_type ] );
}
}
}

Filter WordPress custom post types by taxonomy term

I have been struggling with this for a few days now and I seem to be no closer to a solution. I have been searching forums and tutorial sites, but have ended up more confused, as there seem to be a lot of ways and variations to achieve what I am looking for.
What I want to do is create a Custom Post Type archive that can be filtered by taxonomy terms based on the url string.
_domain/products/_
_domain/products/taxonomy-term/_
_domain/products/taxonomy-term/product-1_
So the taxonomy term will only display custom posts of that type.
I have got as far as this. Which seems to work for domain/products/taxonomy_term/product_1, but isn't picking up any archive templates.
// define custom post types
add_action( 'init', 'create_products' );
function create_products() {
register_post_type( 'products',
array(
'labels' => array(
'name' => __( 'Products' ),
'singular_name' => __( 'Product' )
),
'public' => true,
'has_archive' => true,
'supports' => array( 'title', 'editor', 'excerpt', 'thumbnail', 'revisions' ),
'rewrite' => array('slug' => 'products/%product_cat%', 'with_front' => true ),
'hierarchical' => true,
'query_var' => true,
'show_in_nav_menus' => true,
'menu_position' => 5
)
);
}
add_action( 'init', 'create_my_taxonomies', 0 );
function create_my_taxonomies() {
register_taxonomy(
'product_cat',
'products',
array(
'labels' => array(
'name' => 'Product Categories',
'add_new_item' => 'Add New Product',
'new_item_name' => "New Product Category"
),
'show_ui' => true,
'show_tagcloud' => false,
'hierarchical' => true,
'rewrite' => array( 'slug' => 'products', 'with_front' => true ),
'query_var' => true,
)
);
}
function filter_post_type_link($link, $post)
{
if ($post->post_type != 'product_listing')
return $link;
if ($cats = get_the_terms($post->ID, 'product_cat'))
$link = str_replace('%product_cat%', array_pop($cats)->slug, $link);
return $link;
}
add_filter('post_type_link', 'filter_post_type_link', 10, 2);
For me it was a conflict in naming. I had a post type with the same name as the taxonomy. That caused a conflict.
register_post_type( 'some_name' );
register_taxonomy( 'some_name' );
Rename the taxonomy to something unique.
register_taxonomy( 'some_tax_name' );

Resources