Create new product attribute programmatically in Woocommerce - php

How can I create attributes for WooCommerce from a plugin?
I find only :
wp_set_object_terms( $object_id, $terms, $taxonomy, $append);
From this stack-question
But this approach required id of some product. I need to generate some attributes not attached to any products.

To create a term you can use wp_insert_term()
like so:
wp_insert_term( 'red', 'pa_colors' );
where colors is the name of your attribute. The taxonomy name of an attribute is always prepended by pa_.
Edit Attributes are merely custom taxonomies. Or you could say they are dynamic taxonomies that are manually created by the user in the back-end. Still, all the same, custom taxonomy rules apply.
You can see the source code here which loops through the attributes and runs register_taxonomy() on each. So to create a new attribute (remember it is just a taxonomy) then you need to run register_taxonomy() and simple prepend pa_ to the start of the taxonomy name.
Mimicking some of the values of the taxonomy args from core would get you something like this for a 'Colors' attribute.
/**
* Register a taxonomy.
*/
function so_29549525_register_attribute() {
$permalinks = get_option( 'woocommerce_permalinks' );
$taxonomy_data = array(
'hierarchical' => true,
'update_count_callback' => '_update_post_term_count',
'labels' => array(
'name' => __( 'My Colors', 'your-textdomain' ),
'singular_name' => __( 'Color', 'your-textdomain' ),
'search_items' => __( 'Search colors', 'your-textdomain' ),
'all_items' => __( 'All colors', 'your-textdomain' ),
'parent_item' => __( 'Parent color', 'your-textdomain' ),
'parent_item_colon' => __( 'Parent color:', 'your-textdomain' ),
'edit_item' => __( 'Edit color', 'your-textdomain' ),
'update_item' => __( 'Update color', 'your-textdomain' ),
'add_new_item' => __( 'Add new color', 'your-textdomain' ),
'new_item_name' => __( 'New color', 'your-textdomain' )
),
'show_ui' => false,
'query_var' => true,
'rewrite' => array(
'slug' => empty( $permalinks['attribute_base'] ) ? '' : trailingslashit( $permalinks['attribute_base'] ) . sanitize_title( 'colors' ),
'with_front' => false,
'hierarchical' => true
),
'sort' => false,
'public' => true,
'show_in_nav_menus' => false,
'capabilities' => array(
'manage_terms' => 'manage_product_terms',
'edit_terms' => 'edit_product_terms',
'delete_terms' => 'delete_product_terms',
'assign_terms' => 'assign_product_terms',
)
);
register_taxonomy( 'pa_my_color', array('product'), $taxonomy_data );
}
add_action( 'woocommerce_after_register_taxonomy', 'so_29549525_register_attribute' );
Update 2020-11-18
Attribute taxonomies are stored in the {$wpdb->prefix}woocommerce_attribute_taxonomies database table. And from there WooCommerce runs register_taxonomy() on each one that's found in the table. So in order to create an attribute taxonomy, a row should be added to this table. WooCommerce has a function wc_create_attribute() that will handle this for us. (Since 3.2+).
My conditional logic to test if the attribute exists is not the greatest and I would advise using some kind of version option in your plugin's update routine. But as an example of using wc_create_taxonomy() this should insert an attribute called "My Color".
/**
* Register an attribute taxonomy.
*/
function so_29549525_create_attribute_taxonomies() {
$attributes = wc_get_attribute_taxonomies();
$slugs = wp_list_pluck( $attributes, 'attribute_name' );
if ( ! in_array( 'my_color', $slugs ) ) {
$args = array(
'slug' => 'my_color',
'name' => __( 'My Color', 'your-textdomain' ),
'type' => 'select',
'orderby' => 'menu_order',
'has_archives' => false,
);
$result = wc_create_attribute( $args );
}
}
add_action( 'admin_init', 'so_29549525_create_attribute_taxonomies' );

For Woocommerce 3+ (2018)
To create a new product attribute from a label name use the following function:
function create_product_attribute( $label_name ){
global $wpdb;
$slug = sanitize_title( $label_name );
if ( strlen( $slug ) >= 28 ) {
return new WP_Error( 'invalid_product_attribute_slug_too_long', sprintf( __( 'Name "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) );
} elseif ( wc_check_if_attribute_name_is_reserved( $slug ) ) {
return new WP_Error( 'invalid_product_attribute_slug_reserved_name', sprintf( __( 'Name "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) );
} elseif ( taxonomy_exists( wc_attribute_taxonomy_name( $label_name ) ) ) {
return new WP_Error( 'invalid_product_attribute_slug_already_exists', sprintf( __( 'Name "%s" is already in use. Change it, please.', 'woocommerce' ), $label_name ), array( 'status' => 400 ) );
}
$data = array(
'attribute_label' => $label_name,
'attribute_name' => $slug,
'attribute_type' => 'select',
'attribute_orderby' => 'menu_order',
'attribute_public' => 0, // Enable archives ==> true (or 1)
);
$results = $wpdb->insert( "{$wpdb->prefix}woocommerce_attribute_taxonomies", $data );
if ( is_wp_error( $results ) ) {
return new WP_Error( 'cannot_create_attribute', $results->get_error_message(), array( 'status' => 400 ) );
}
$id = $wpdb->insert_id;
do_action('woocommerce_attribute_added', $id, $data);
wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' );
delete_transient('wc_attribute_taxonomies');
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Based on:
Product Attribute wc_create_attribute() function code (Woocommerce 3.2+).
Create programmatically a variable product and two new attributes in Woocommerce
Related: Create programmatically a product using CRUD methods in Woocommerce 3

Related

how to create short code to display particular testimonial using its post id?

i have created custom post type for testimonials in wordpress.i have added 89 testimonials and wants to display 2 which i wants to displany in home page .
so wanted to created shortcode which will display testimonials according to their Post ID.
can anyone please tell me the code for shortcode.
Below i am showing code i had written to create custom post type for testimonial . Pls tell me the code to create shortcode like this:-[testimonial posts_per_page="5" testimonial_id="123,145"]
function custom_post_testimonial_type() {
// Set UI labels for Custom Post Type
$labels = array(
'name'=> _x( 'Testimonials', 'Post Type General Name', 'walker_theme' ),
'singular_name'=> _x( 'Testimonial', 'Post Type Singular Name', 'walker_theme' ),
'menu_name'=> __( 'Testimonials', 'walker_theme' ),
'parent_item_colon' => __( 'Testimonial', 'walker_theme' ),
'all_items' => __( 'All Testimonials', 'walker_theme' ),
'view_item' => __( 'View Testimonial', 'walker_theme' ),
'add_new_item' => __( 'Add New Testimonial','walker_theme' ),
'add_new' => __( 'Add New', 'walker_theme' ),
'edit_item' => __( 'Edit Testimonial','walker_theme' ),
'update_item' => __( 'Update Testimonial','walker_theme' ),
'search_items' => __( 'Search Testimonial', 'walker_theme' ),
'not_found' => __( 'Not Found', 'walker_theme' ),
'not_found_in_trash' => __( 'Not found in Trash','walker_theme' ),
);
// Set other options for Custom Post Type
$args = array(
'label' => __( 'testimonials', 'walker_theme' ),
'description' => __( 'Home page testimonials', 'walker_theme' ),
'labels' => $labels,
// Features this CPT supports in Post Editor
'supports' => array( 'title', 'editor', 'author','thumbnail', 'tags'),
// You can associate this CPT with a taxonomy or custom
taxonomy.
'taxonomies' => array( 'genres', 'post_tag' ),
/* A hierarchical CPT is like Pages and can have
* Parent and child items. A non-hierarchical CPT
* is like Posts.
*/
'hierarchical' => false,
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'show_in_nav_menus' => true,
'show_in_admin_bar' => true,
'menu_position' => 5,
'can_export' => true,
'has_archive' => true,
'exclude_from_search' => false,
'publicly_queryable' => true,
'capability_type' => 'page',
);
// Registering your Custom Post Type
register_post_type( 'testimonials', $args );
}
add_action( 'init', 'custom_post_testimonial_type', 0 );
Use the shortcode attributes with known attributes and fills in defaults when needed.
function testimonials($atts) {
$a = shortcode_atts( array(
'posts_per_page' => '',
'testimonial_id' => ''
), $atts );
$testimonials = '';
$post_in = esc_attr($a['testimonial_id']);
$posts_per_page = esc_attr($a['posts_per_page']);
$post_artay = explode(',', $post_in);
$args = array(
'post__in' => $post_artay,
'posts_per_page' => $posts_per_page,
'post_type' => 'testimonials',
'order_by' => 'post__in',
);
// the query
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
$testimonials.= '<div class="title">'.get_the_title().'</div>';
$testimonials.= '<div class="content">'.get_the_content().'</div>';
$testimonials.='<div class="date">'.get_the_date().'</div>';
$testimonials.='<div class="author">'.get_the_author().'</div>';
endwhile;
endif;
return $testimonials;
}
add_shortcode('testimonial', 'testimonials' );
use the shortcode like.
[testimonial posts_per_page="5" testimonial_id="29,23"]
Hi let's add this code in the theme's functions.php file.
add_shortcode( 'testimonial', 'testimonial_shortcode_callback' );
function testimonial_shortcode_callback( $atts ) {
ob_start();
extract( shortcode_atts( array(
'posts_per_page' => 5,
'testimonial_id' => '',
), $atts ) );
// define query parameters based on attributes
$options = array(
'post_type' => 'testimonials',
'posts_per_page' => $posts_per_page,
);
if ( ! empty( $testimonial_id ) ) {
$options['post__in'] = array_map( 'trim', explode( ',', $testimonial_id ) );
}
$testimonial_query = new WP_Query( $options );
// run the loop based on the query
if ( $testimonial_query->have_posts() ) :
?>
<ul class="testimonial-listing">
<?php
while ( $testimonial_query->have_posts() ) : $testimonial_query->the_post();
?>
<li id="testimonial-<?php the_ID(); ?>">
<?php the_content(); ?>
</li>
<?php
endwhile;
wp_reset_postdata();
?>
</ul>
<?php
$testimonial_output = ob_get_clean();
return $testimonial_output;
endif;
}
Than use this shortcode as a example [testimonial posts_per_page="2" testimonial_id="123,145"]

WordPress - Custom Post type, Custom role, Custom Capability

I am stuck in a problem assigning custom capability with custom post type to a custom role.
The issue is i want to remove the Add New ( Not with a CSS hack or by unsetting menu item ) option of my custom post type. I have already come across answers that suggest many solutions but none of them works perfectly.
Closest to what i want is this :
register_post_type( 'custom_post_type_name', array(
'capability_type' => 'post',
'capabilities' => array(
'create_posts' => 'do_not_allow', // false < WP 4.5, credit #Ewout
),
'map_meta_cap' => true, // Set to `false`, if users are not allowed to edit/delete existing posts
));
This code removes the Add New link but it assigns the default post slug for capabilities.Notice line 2 of above code. If i change it to my custom post type slug, it stops working and i can't even go posts page.
One thing to keep in mind is that i am working with custom role, which has only read capability by default.
If i also assign the edit_posts capability then my objective is achieved, but then user can also access posts and comments, which i do not want.
Woocommerce is doing this. I dive into woocommerce code and add this line where it registers its products and orders.
'capabilities' => array( 'create_posts' => 'do_not_allow' ),
And everything works as i want. I have explored woocommerce code all day but can't find how it is doing this. Can someone else help me out on this with another pair of eyes ? :)
Much appreciated. Thanks..
I already mention to you that give us little more details about the plan that you want to do?
Here is the solution that I think it would be helpful for you.
If you want to used map_meta_cap => true then you will need to change capability_type as well with your own type, see more https://codex.wordpress.org/Function_Reference/register_post_type#capability_type
But if you set your own capability_type value then you will need to add capability to users role those you want to add.
here is a complete example.
if ( !class_exists( 'WPSE64458_CPT_Register' ) ) {
class WPSE64458_CPT_Register {
function __construct() {
add_action( 'init', array( $this, 'wpse64458_register_post_types' ), 5 );
add_action( 'admin_init', array( $this, 'wpse64458_add_caps' ), 5 );
add_filter( 'register_post_type_args', array( $this, 'wpse64458_modify_cpt_registry' ) , 10, 2 );
}
/**
* Register core post types.
*/
public function wpse64458_register_post_types() {
if ( ! is_blog_installed() || post_type_exists( 'member' ) ) {
return;
}
register_post_type( 'member',
apply_filters( 'wpse64458_callb_post_type_member',
array(
'labels' => array(
'name' => __( 'Members', 'domaintext' ),
'singular_name' => __( 'Member', 'domaintext' ),
'all_items' => __( 'All Members', 'domaintext' ),
'menu_name' => _x( 'Members', 'Admin menu name', 'domaintext' ),
'add_new' => __( 'Add New', 'domaintext' ),
'add_new_item' => __( 'Add new member', 'domaintext' ),
'edit' => __( 'Edit', 'domaintext' ),
'edit_item' => __( 'Edit member', 'domaintext' ),
'new_item' => __( 'New member', 'domaintext' ),
'view' => __( 'View member', 'domaintext' ),
'view_item' => __( 'View member', 'domaintext' ),
'search_items' => __( 'Search members', 'domaintext' ),
'not_found' => __( 'No members found', 'domaintext' ),
'not_found_in_trash' => __( 'No members found in trash', 'domaintext' ),
'parent' => __( 'Parent member', 'domaintext' ),
'featured_image' => __( 'Member image', 'domaintext' ),
'set_featured_image' => __( 'Set member image', 'domaintext' ),
'remove_featured_image' => __( 'Remove member image', 'domaintext' ),
'use_featured_image' => __( 'Use as member image', 'domaintext' ),
'insert_into_item' => __( 'Insert into member', 'domaintext' ),
'uploaded_to_this_item' => __( 'Uploaded to this member', 'domaintext' ),
'filter_items_list' => __( 'Filter members', 'domaintext' ),
'items_list_navigation' => __( 'Members navigation', 'domaintext' ),
'items_list' => __( 'Members list', 'domaintext' ),
),
'public' => true,
'show_ui' => true,
'capability_type' => 'member',
'map_meta_cap' => true,
'menu_icon' => 'dashicons-groups',
'publicly_queryable' => true,
'exclude_from_search' => false,
'hierarchical' => false, // Hierarchical causes memory issues - WP loads all records!
'rewrite' => array( 'slug' => 'member' ),
'query_var' => true,
'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt' ),
'has_archive' => 'members',
'show_in_nav_menus' => true,
'show_in_rest' => true,
)
)
);
} // end of wpse64458_register_post_types
/**
* Get capabilities.
*
* #return array
*/
private function wpse64458_set_caps() {
$capabilities = array();
$capability_types = array( 'member' );
foreach ( $capability_types as $capability_type ) {
$capabilities[ $capability_type ] = array(
// Post type
"edit_{$capability_type}",
"read_{$capability_type}",
"delete_{$capability_type}",
"edit_{$capability_type}s",
"edit_others_{$capability_type}s",
"publish_{$capability_type}s",
"read_private_{$capability_type}s",
"delete_{$capability_type}s",
"delete_private_{$capability_type}s",
"delete_published_{$capability_type}s",
"delete_others_{$capability_type}s",
"edit_private_{$capability_type}s",
"edit_published_{$capability_type}s",
// Terms
// "manage_{$capability_type}_terms",
// "edit_{$capability_type}_terms",
// "delete_{$capability_type}_terms",
// "assign_{$capability_type}_terms",
);
}
return $capabilities;
}
/*
Add Capability
*/
public function wpse64458_add_caps(){
global $wp_roles;
if ( ! class_exists( 'WP_Roles' ) ) {
return;
}
if ( ! isset( $wp_roles ) ) {
$wp_roles = new WP_Roles();
}
$capabilities = $this->wpse64458_set_caps();
foreach ( $capabilities as $cap_group ) {
foreach ( $cap_group as $cap ) {
$wp_roles->add_cap( 'editor', $cap );
$wp_roles->add_cap( 'administrator', $cap );
}
}
}
public function wpse64458_modify_cpt_registry( $args, $post_type ){
// Do not filter any other post type
if ( 'member' !== $post_type ) {
// Give other post_types their original arguments
return $args;
}
if( current_user_can('editor') ) {
$args['capabilities']['create_posts'] = false;
}
// Give the custom-css-js post type it's arguments
return $args;
}
}
}
then inherite the class with new WPSE64458_CPT_Register();
With this example I disable editor role to add new member post functionality. modify whatever you like, or you can do this others as well. but you previously mention that you already tried to follow WooCommerce, actually they also do this way,
Hope it make sense to you.
HappyCodding!
You can restrict specific user role to custom post by below script :
Add custom Role
add_action('init','add_my_custom_role');
function add_my_custom_role() {
add_role('my_custom_role',
'Custom Role',
array(
'read' => true,
'edit_posts' => false,
'delete_posts' => false,
'publish_posts' => false,
'upload_files' => false,
'publish_posts' => false,
'create_posts' => false,
)
);
}
Register Custom post
add_action( 'init', 'my_custom_post_type');
function my_custom_post_type() {
$args = array(
'label' => __( 'Custom post', 'custom-text-domain' ),
'description' => __( 'Custom post', 'custom-text-domain' ),
'labels' => $labels,
'supports' => array( 'title', 'comments', 'revisions', ),
'hierarchical' => false,
'public' => true,
'show_ui' => true,
'rewrite' => $rewrite,
'capability_type' => array('custom_post','custom_post'),
'map_meta_cap' => true, // Set to `false`, if users are not allowed to edit/delete existing posts
);
register_post_type( 'custom_post', $args );
}
Allow user capabilities for post on the basis of roles
add_action('admin_init','custom_post_add_role_caps',999);
function custom_post_add_role_caps() {
// Add the roles you'd like to administer the custom post types
$roles = array('my_custom_role','editor');
// Loop through each role and assign capabilities
foreach($roles as $the_role) {
$role = get_role($the_role);
$role->add_cap( 'read' );
$role->add_cap( 'read_custom_post');
$role->add_cap( 'read_private_custom_post' );
$role->add_cap( 'edit_custom_post' );
$role->add_cap( 'edit_custom_post' );
$role->add_cap( 'edit_others_custom_post' );
$role->add_cap( 'edit_published_custom_post' );
$role->add_cap( 'publish_custom_post' );
$role->add_cap( 'delete_others_custom_post' );
$role->add_cap( 'delete_private_custom_post' );
$role->add_cap( 'delete_published_custom_post' );
}
}
I hope this will help you, to get more help please visit
https://codex.wordpress.org/Function_Reference/register_post_type
and
https://codex.wordpress.org/Roles_and_Capabilities

How to change custom post type pemalink Hierarcy

When we set permalink as Post name and go to wordpress any default post Like "Testing 123" single page its link looks like this
localhost/foo_articles/testing-123
Now i when we change our permalink to Custom Structure and set value like %category%/%postname%, the link looks like this
http://localhost/foo_articles/testing/testing-123/
testing is my category slug
Now the main part of my question is
I make a plugin where i create a post type foo_articles and custom taxonomy foo_categories
Its work perfectly. When i click on a category its link looks like this
http://localhost/foo_articles/foo_category/junk-food/
and when i click on an article for a single page, its link looks like this
http://localhost/foo_articles/foo_articles/how-to-reduce-the-intake-of-junk-food-in-children/
foo_articles is my post type and its a change able
Now my question is how can i set links that when a user set permalinks Custom Structure and set value like %category%/%postname% my link also change like above default post single page.
http://localhost/foo_articles/article cat slug/how-to-reduce-the-intake-of-junk-food-in-children/
Here is custom post type code:
add_action('init', 'foo_articles');
function foo_articles() {
$foo_slug = 'foo_articles';
$foo_slug = get_option('foo_plugin_slug');
$labels = array(
'name' => __('Foo', 'fff'),
'singular_name' => __('Foo', 'fff'),
'all_items' => __('Articles', 'fff'),
'add_new' => __('New Article', 'fff'),
'add_new_item' => __('Add New Article', 'fff'),
'edit_item' => __('Edit Article', 'fff'),
'new_item' => __('New Article', 'fff'),
'view_item' => __('View Articles', 'fff'),
'search_items' => __('Search Articles', 'fff'),
'not_found' => __('Nothing found', 'fff'),
'not_found_in_trash' => __('Nothing found in Trash', 'fff'),
'parent_item_colon' => ''
);
$foo_rewrite = array(
'slug' => FOO_PLUGIN_SLUG, // i define this in plugin index file
'with_front' => true,
'pages' => false,
'feeds' => true,
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'query_var' => true,
'menu_icon' => plugin directory.'images/icon-foo.png',
'capability_type' => 'post',
'hierarchical' => false,
'menu_position' => 3,
'supports' => array('title','editor','thumbnail','comments','tags'),
'rewrite' => $foo_rewrite,
'show_in_menu' => true,
'show_in_nav_menus' => true,
'show_in_admin_bar' => true,
'can_export' => true,
'has_archive' => true,
'exclude_from_search' => true
);
register_post_type( 'foo_articles' , $args );
flush_rewrite_rules();
}
add_action( 'init', 'foo_taxonomies', 0 );
// Article taxonamy
function foo_taxonomies() {
// Add new taxonomy, make it hierarchical (like categories)
$labels = array(
'name' => __( 'Article Category', 'fff'),
'singular_name' => __( 'Article Category', 'fff' ),
'search_items' => __( 'Search Article Category', 'fff' ),
'all_items' => __( 'All Article Categories', 'fff' ),
'parent_item' => __( 'Parent Article Category', 'fff' ),
'parent_item_colon' => __( 'Parent Article Category:', 'fff' ),
'edit_item' => __( 'Edit Article Category', 'fff' ),
'update_item' => __( 'Update Article Category', 'fff' ),
'add_new_item' => __( 'Add New Article Category', 'fff' ),
'new_item_name' => __( 'New Article Category Name', 'fff' ),
'menu_name' => __( 'Categories', 'fff' )
);
register_taxonomy( 'foo_categories', array( 'foo_articles' ), array(
'hierarchical' => true,
"labels" => $labels,
"singular_label" => __( 'Foo Category', 'foo'),
'show_ui' => true,
'query_var' => true,
'rewrite' => array( 'slug' => 'foo_category', 'with_front' => true )
));
flush_rewrite_rules();
}
Note: i change my post type slug by plugin settings and its option_name is foo_plugin_slug (its a client idea)
So please tell me how can i do this. Is there any hook or filter or htaccess code
You can use WP Walker concept. Please check this
WP Walker
Eg:
Use ACF plugin to get custom field.
List pages code :-
$args = array(
'child_of' => $post->ID,
'date_format' => get_option('date_format'),
'post_type' => 'page',
'title_li' => __(''),
'walker' => new my_page_walker
);
wp_list_pages( $args );
Extend Walker_page in function.php
In function.php
class my_page_walker extends Walker_Page {
public function start_el( &$output, $page, $depth = 0, $args = array(), $current_page = 0 ) {
if ( $depth ) {
$indent = str_repeat( "\t", $depth );
} else {
$indent = '';
}
$css_class = array( 'page_item', 'page-item-' . $page->ID );
if ( isset( $args['pages_with_children'][ $page->ID ] ) ) {
$css_class[] = 'page_item_has_children';
}
if ( ! empty( $current_page ) ) {
$_current_page = get_post( $current_page );
if ( $_current_page && in_array( $page->ID, $_current_page->ancestors ) ) {
$css_class[] = 'current_page_ancestor';
}
if ( $page->ID == $current_page ) {
$css_class[] = 'current_page_item';
} elseif ( $_current_page && $page->ID == $_current_page->post_parent ) {
$css_class[] = 'current_page_parent';
}
} elseif ( $page->ID == get_option('page_for_posts') ) {
$css_class[] = 'current_page_parent';
}
$css_classes = implode( ' ', apply_filters( 'page_css_class', $css_class, $page, $depth, $args, $current_page ) );
if ( '' === $page->post_title ) {
$page->post_title = sprintf( __( '#%d (no title)' ), $page->ID );
}
$args['link_before'] = empty( $args['link_before'] ) ? '' : $args['link_before'];
$args['link_after'] = empty( $args['link_after'] ) ? '' : $args['link_after'];
$page_permalink = get_permalink( $page->ID );
$user_defined_link = get_field('my-custom-field',$page->ID)['url'];
if (!is_null($user_defined_link)) {
$page_permalink = $user_defined_link;
}
$output .= $indent . sprintf(
'<li class="%s">%s%s%s',
$css_classes,
$page_permalink,
$args['link_before'],
apply_filters( 'the_title', $page->post_title, $page->ID ),
$args['link_after']
);
if ( ! empty( $args['show_date'] ) ) {
if ( 'modified' == $args['show_date'] ) {
$time = $page->post_modified;
} else {
$time = $page->post_date;
}
$date_format = empty( $args['date_format'] ) ? '' : $args['date_format'];
$output .= " " . mysql2date( $date_format, $time );
}
}
}
The final link will be the value from the custom field.

Wordpress: Custom Taxonomy Not Consistently in URL

I have a custom post type and custom taxonomy set up using the code below in functions.php.
The URL writes correctly when clicking through on the archive pages on the front end and when clicking "View Post" in the admin edit screen. But when the post is returned in site search results, the custom taxonomy is literally missing. The URL on search results is http://www.example.com/foo//postname.
Any idea why the custom taxonomy in the URL would work in some situations but not in others?
add_action( 'init', 'create_foo_posttype' );
function create_foo_posttype() {
$tax_labels = array(
'name' => _x( 'Foo Categories', 'taxonomy general name' ),
'singular_name' => _x( 'Foo Category', 'taxonomy singular name' ),
'all_items' => __( 'All Foo Categories' ),
'parent_item' => null,
'parent_item_colon' => null,
'edit_item' => __( 'Edit Foo Category' ),
'update_item' => __( 'Update Foo Category' ),
'add_new_item' => __( 'Add New Foo Category' ),
'new_item_name' => __( 'New Foo Category Name' ),
);
register_taxonomy('foo_categories','foo',array(
'labels' => $tax_labels,
'hierarchical' => true,
'has_archive' => true,
'show_admin_column' => true,
'query_var' => true,
'rewrite' => array( 'slug' => 'foo' )
));
register_post_type( 'foo',
array(
'labels' => array(
'name' => __( 'Foo' ),
'singular_name' => __( 'Foo' )
),
'public' => true,
'exclude_from_search' => false,
'show_ui' => true,
'show_in_menu' => true,
'menu_position' => 100,
'capability_type' => 'post',
'supports' => array( 'title', 'author', 'thumbnail', 'trackbacks', 'revisions' ),
'taxonomies' => array( 'foo_categories' ),
'has_archive' => true,
'rewrite' => array( 'slug' => 'foo/%foo_categories%')
)
);
flush_rewrite_rules();
}
add_action( 'init', 'cust_rewrite_init' );
function cust_rewrite_init() {
$GLOBALS['wp_rewrite']->use_verbose_page_rules = true;
}
add_filter( 'page_rewrite_rules', 'cust_rewrite_collect_page_rewrite_rules' );
function cust_rewrite_collect_page_rewrite_rules( $page_rewrite_rules )
{
$GLOBALS['cust_rewrite_page_rewrite_rules'] = $page_rewrite_rules;
return array();
}
add_filter( 'rewrite_rules_array', 'cust_rewrite_prepend_page_rewrite_rules' );
function cust_rewrite_prepend_page_rewrite_rules( $rewrite_rules )
{
return $GLOBALS['cust_rewrite_page_rewrite_rules'] + $rewrite_rules;
}
I found the problem. It wasn't in the code I posted originally. It was here:
add_filter('post_type_link', 'cust_permalink_structure', 1, 4);
function cust_permalink_structure($post_link, $post, $leavename, $sample)
{
if ( false !== strpos( $post_link, '%foo_categories%' ) ) {
$post_type_term = get_the_terms( $post->ID, 'foo_categories' );
$post_link = str_replace( '%foo_categories%', $post_type_term[0]->slug, $post_link );
}
return $post_link;
}
Using $post_type_term[0]->slug; worked if a post had more than one tax value, but failed when the post had only one (which all of my posts do). To fix it, I used array_pop instead of the other array call and it works fine. The resolved code:
add_filter('post_type_link', 'cust_permalink_structure', 1, 4);
function cust_permalink_structure($post_link, $post, $leavename, $sample)
{
if ( false !== strpos( $post_link, '%foo_categories%' ) ) {
$post_type_term = get_the_terms( $post->ID, 'foo_categories' );
$one_term = array_pop($post_type_term);
$post_link = str_replace( '%foo_categories%', $one_term->slug, $post_link );
}
return $post_link;
}

How to display meta_box field in listing

I am creating one post_type using register_post_type so i am getting add_new option there i am using meta_box to use my custom field.But in my listing it is showing only title column,How i can use my meta_box field as a column in listing page.
my code for register_post_type is -
// Create Brand Management
add_action('init', 'manage_brand');
function manage_brand() {
register_post_type('brand', array(
'labels' => array(
'name' => 'Manage Brand',
'singular_name' => 'Manage Brand',
'add_new' => 'Add New',
'add_new_item' => 'Add New Brand',
'edit' => 'Edit',
'edit_item' => 'Edit Brand',
'new_item' => 'New Brand',
'view' => 'View',
'view_item' => 'View Brand',
'search_items' => 'Search Brand',
'not_found' => 'No Brand',
'not_found_in_trash' => 'No Brand found in Trash',
'parent' => 'Parent News Brand'
),
'public' => true,
'menu_position' => 100,
'supports' => array('','thumbnail'),
'taxonomies' => array('project-cat'),
'menu_icon' => plugins_url('images/adv-.png', __FILE__),
'has_archive' => true,
)
);
}
and my code to add field using meta_box is -
//add meta data for brand
add_action('admin_init', 'brand_register_meta_boxes');
function brand_register_meta_boxes() {
if (!class_exists('RW_Meta_Box'))
return;
$prefix = 'brand_';
$meta_boxes[] = array(
'title' => 'Add Brand',
'pages' => array('brand'),
'fields' => array(
array(
'name' => __( 'Brand Name', 'rwmb' ),
'desc' => __( 'Add Brand Name', 'rwmb' ),
'id' => "{$prefix}code",
'type' => 'text',
'required' => true,
),
)
);
foreach ($meta_boxes as $meta_box) {
new RW_Meta_Box($meta_box);
}
}
my list page is coming like this with tile only -
how can i add my meta_box field also in this listing.
Assuming the value of the meta box is stored as post meta, you should (a) register a custom column using the dynamic manage_{$post_type}_posts_columns filter hook:
add_filter( 'manage_brand_posts_columns', 'so20352744_manage_brand_posts_columns', 25, 1 );
function so20352744_manage_brand_posts_columns( $cols )
{
$cols['brand'] = __( 'Brand', 'txt_domain' );
return $cols;
}
and (b) add content to the column using the manage_posts_custom_column action hook:
add_action( 'manage_posts_custom_column', 'so20352744_manage_posts_custom_column', 2, 1 );
function so20352744_manage_posts_custom_column( $col )
{
global $post;
switch ( $col )
{
case "brand" :
if( '' != get_post_meta( $post->ID, 'brand_code', true ) )
echo get_post_meta( $post->ID, 'brand_code', true );
else
echo __( 'N/A', 'txt_domain' );
break;
default :
break;
}
}
Both functions go in functions.php. More info: http://codex.wordpress.org/Plugin_API/Action_Reference/manage_posts_custom_column

Categories