i am developing a multivendor shop and i want the vendors to post products from a Template page. i am using Advance custom fields to achieve this functionality.
What i did by far is to create the page template and managed to display the form but i have some issue to validate the fields with the Product. i might need to create some functionalities ?
<?php
/**
* The template for displaying all pages.
* Template Name: Add Product Vendor
* This is the template that displays all pages by default.
* Please note that this is the WordPress construct of pages
* and that other 'pages' on your WordPress site will use a
* different template.
*
* #package Bober
*/
?>
<?php
acf_form_head();
get_header();
?>
<div id="content">
<?php
global $woocommerce;
acf_form(array(
$post_title = 'field_5a60022b402e2',
$post_categ = 'field_5a60028e402e3',
$post_descrip = 'field_5a600384402e4',
$post_img = 'field_5a6005e1402e7',
$post_price = 'field_5a61207ce5226',
/*'post_title' =>true,
'post_content' => true,*/
'uploader' => 'basic',
'post_id' => 'new_post',
'fields' => array($post_title, $post_descrip, $post_categ,$post_price, $post_img),
'new_post' => array(
'post_status' => 'draft',
'post_type' =>'product',
),
/*'fields' => array('field_5a60022b402e2', 'field_5a60028e402e3', 'field_5a600384402e4', 'field_5a6005e1402e7'),*/
'submit_value' => 'Add product'
));
?>
</div>
<?php get_footer(); ?>
At this point i was able to asign the title of the product and the content of by using the code below based on ACF form documentation.
'post_title' =>true,
'post_content' => true,
How do i assign the Title value, the description value, price value and image to the product post ? I don't necesary look for someone to provide me a code to replace, i want to know how to do it, give me some ideas, or where to read on how to do it.
Thank you in advance!
First, do an in-depth read of how acf_form() works.
The acf_form() code for adding a product in woocommerce could look like this:
$options = array(
'post_id' => 'new_post',
'post_title' => true,
'post_content' => true,
'new_post' => array(
'post_type' => 'product',
'post_status' => 'draft'
),
'field_groups' => [$field_group_id],
'form' => true,
'return' => '%post_url%', // so they could be redirected to the product page in a draft state - i imagine?!
'html_submit_button' => '<input type="submit" value="%s" />',
'updated_message' => 'Product Created',
'submit_value' => 'Submit Product'
);
acf_form($options);
Regarding the featured image of the product, create an image field and use the code below to sync the field with the featured image. You can read more about this by checking the ACF API reference for acf/update_value
add_filter('acf/update_value/name=featured_image', function ($value, $post_id, $field) {
if ($value != '') {
update_post_meta($post_id, '_thumbnail_id', $value);
} else {
delete_post_thumbnail($post_id);
}
return $value;
}, 10, 3);
Related
I use the Woocommerce “Handpicked products” Block in Wordpress Gutenberg to create a showcase of 3 products on my Frontpage. I saw that Woocommerce does not use Shortcodes for that, but that the page itself includes a paragraph which looks like this:
<!-- wp:woocommerce/handpicked-products {"contentVisibility":{"image":true,"title":true,"price":false,"rating":false,"button":false},"orderby":"menu_order","products":[181,225,179]} /-->"
I want to dynamically change the products (randomly shuffle) upon page load. Unfortunately, in the whole PHP-classes HandpickedProducts, AbstractProductGrid, AbstractDynamicBlock etc I do not see a Hook to change the Render parameter dynamically...
So what I found as possible solution is: To directly replace the product attribute in the Wordpress Post itself, therefore I implemented this hook:
function my_the_post_action(&$pobj) {
$pobj->post_content = str_replace('[181,225,179]', '[225, 220, 222]', $pobj->post_content );
}
add_action('the_post', 'my_the_post_action' );
It is actually replaced in the wp:woocommerce/handpicked-products paragraph, but doesnt take effect. Why does Woocommerce not consider the new Product IDs as parameters to his rendered block?
Thanks!!
Instead of modifying the "Blocks" entered via Pageeditor upon Pageload within the Frontpage - I came up with a better and cleaner option IMHO - by simply rendering such a Block within a customer Shortcode.
The following code consists of first the part where I randomly pick 3 products from the Database which have the Product-Tag "Featured" set so that the user can decide himself which products are open for selection ... and then I create my "Handpicked Products" block and render it:
add_shortcode('my_featured_prods', function($atts, $content = null)
{
// Get list of all Woocommerce products by Tag
$args = array(
'post_type' => 'product',
'posts_per_page' => 3,
'orderby' => 'rand',
'tax_query' => array(
array(
'taxonomy' => 'product_tag',
'field' => 'slug',
'terms' => 'featured'
)
)
);
$products = new WP_Query($args);
$ids = [$fix];
foreach($products->posts as $p)
$ids[] = $p->ID;
// Shuffle array:
shuffle($ids);
// Output Hand Picked Products Widget with my settings ...
$args = (object) [
'editMode' => 0,
'contentVisibility' => (object) [
'image' => 1,
'title' => 1,
'price' => 0,
'rating' => 0,
'button' => 0,
],
'orderby' => 'random',
'products' => $ids,
'alignButtons' => 1,
];
$args = sprintf(
'<!-- wp:woocommerce/handpicked-products %s /-->',
json_encode( $args )
);
return do_blocks($args);
});
I can get all the posts using this query. What I want to do is to add custom field key and value so that I will able to pass it along with the post object.
$args = array(
'p' => 996,
'status' => 'publish',
'post_type' => 'ajde_events',
'tax_query' => array(
array(
'taxonomy' => 'event_type',
'field' => 'slug',
'terms' => 'cursed-warriors',
),
),
);
$singlePost = new WP_Query($args);
while ($singlePost->have_posts()) : $singlePost->the_post();
endwhile;
If I query this $singlePost->posts I will have the result below
0: [,…]
0: {ID: 996, post_author: "1", post_date: "2019-11-13 11:15:09", post_date_gmt: "2019-11-13 11:15:09",…}
ID: 996
comment_count: "0"
comment_status: "open"
filter: "raw"
.....etc
I want to add something here
I want to know how I can add some keys there like
project_name: "some project"
Custom Fields can be used for this.
If you are using Gutenberg you will find them under the post's options in the post editor. Click the three dots on the top right, select options, toggle the custom fields on then hit the reload page button. After it loads back up you will see the custom fields metabox at the bottom of the editor.
If you are using classic then the custom fields toggle will be under screen options.
It looks like you have a good grasp of how to handle the data from there. You can use get_post_meta with the postID and the key you add or print all the post meta like you have done above.
What I understand is you want to create a field in your CPT then wants to pass its value in wp loop.
First register a metabox
Here you can do that
/**
* Register meta boxes.
*/
function nap_register_meta_boxes() {
add_meta_box('nap-1', __('NAP Details', 'nap'), 'nap_display_callback', 'nap_location');
add_meta_box('featured-nap-1', __('Featured NAP Location', 'featured-nap'), 'featured_nap_display_callback', 'nap_location');
}
add_action('add_meta_boxes', 'nap_register_meta_boxes');
/**
* Meta box display callback.
*
* #param WP_Post $post Current post object.
*/
function nap_display_callback($post) {
include plugin_dir_path(__FILE__) . '/nap-address-form-fields.php';
}
then add fields to it in nap-address-form-fields.php
<div class="nap_box">
<p class="meta-options nap_field">
<label for="project_name">Project Name</label>
<input id="project_name" value="<?php echo esc_attr(get_post_meta(get_the_ID(), 'project_name', true)); ?>" type="text" name="project_name">
</p>
</div>
Then now on main answer to your question , this is how you can pass it to query
$args = array(
'p' => 996,
'status' => 'publish',
'post_type' => 'ajde_events',
'meta_key' => 'project_name',
'meta_value' => 'some project',
'tax_query' => array(
array(
'taxonomy' => 'event_type',
'field' => 'slug',
'terms' => 'cursed-warriors',
),
),
);
I just found out that since $array->posts is an array of objects you need to do this in order to add new key and value to the result
foreach ($singlePost->posts as $po) {
$po->project_name = "My Project";
}
Having a bit of bother with the Wordpress Meta Box plugin, specifically with retrieving an image url from an image added to a custom post type.
I'm creating meta boxes in a custom plugin, like so:
add_filter( 'rwmb_meta_boxes', 'xxx_meta_register_meta_boxes' );
function xxx_meta_register_meta_boxes( $meta_boxes )
{
$prefix = 'xxx_meta_';
$meta_boxes[] = array(
'title' => esc_html__( 'Retailer Information', '' ),
'id' => 'advanced',
'post_types' => array( 'xxx_retailers' ),
'autosave' => true,
'fields' => array(
// PLUPLOAD IMAGE UPLOAD (WP 3.3+)
array(
'name' => esc_html__( 'Retailer Logo', '' ),
'id' => "{$prefix}plupload",
'type' => 'plupload_image',
'max_file_uploads' => 1,
),
// URL
array(
'name' => esc_html__( 'Link', '' ),
'id' => "{$prefix}url",
'desc' => esc_html__( 'Clicking the retailer logo will take the user to this URL', '' ),
'type' => 'url',
'std' => 'xxx',
),
)
);
return $meta_boxes;
}
So far so good, these boxes are relevant to a custom post type 'xxx_retailers'.
The problem comes with retrieving this data. I want to display my retailers in a widget. I've chopped and changed another piece of code I've used previously, but it's not returning the image URL, just the ID. Unfortunately I don't know enough php to figure out why.
// Create Retailers Widget
// Create the widget
class Retailers_Widget extends WP_Widget {
function __construct() {
parent::__construct(
// base ID of the widget
'retailers_widget',
// name of the widget
__('XXX Retailers List', '' ),
// widget options
array (
'description' => __( 'Shows a list of retailer logos', '' )
)
);
}
function widget( $args, $instance ) {
// kick things off
extract( $args );
echo $before_widget;
echo $before_title . 'Retailers' . $after_title;
// Pull through Retailers
$xxxretailers = get_posts(array(
'post_type' => 'xxx_retailers',
'orderby' => 'title',
'order' => 'asc',
));
// Display for each Retailer
foreach ($xxxretailers as $xxxretailer) {
$custom = get_post_custom($xxxretailer->ID);
$meta_ret_img = $custom["xxx_meta_plupload"][0];
$meta_ret_url = $custom["xxx_meta_url"][0];
// Display Retailers
echo "<li><a href='{$meta_ret_url}'><img src='{$meta_ret_img}' /></a></li>";
}
}
};
// Register widget
function register_retailers_widget() {
register_widget( 'Retailers_Widget' );
}
add_action( 'widgets_init', 'register_retailers_widget' );
The URLs are coming through correctly, so I know this is a problem with the line
$meta_ret_img = $custom["xxx_meta_plupload"][0];
But I can't figure out how to get the image URL from the data I presume is stored as an array. Any ideas?
Edit:
I should have mentioned, in a single post I can get a single image with:
$images = rwmb_meta( 'xxx_meta_plupload', 'size=medium' );
if ( !empty( $images ) ) {
foreach ( $images as $image ) {
echo "<img src='{$image['url']}' />";
}
}
But I want to show images from all my retailers post types, to create a list of logos.
Replace this statement:
$meta_ret_img = $custom["xxx_meta_plupload"][0];
with this:
$meta_ret_img_array = wp_get_attachment_image_src($custom["xxx_meta_plupload"][0]);
$meta_ret_img = $meta_ret_img_array[0];
also please remove all these curly braces from src and href attributes from your code.
if you are interested in any particular size of the image, then see the official document of wp_get_attachment_image_src() function here.
For e.g. for medium size image you can write it as:
wp_get_attachment_image_src($custom["xxx_meta_plupload"][0], 'medium');
I'm using Visual Composer in WordPress and I want to make a custom Post Grid. But the default elements that the post grid supplies are not enough. I want to show the author of the post, the number of comments it has, the category it has and the Tags it has as well. I'm not really familiar with Visual Composer, but I need a point in the right direction for me to get this data? What can I do? I've search their documents but with no luck. If I need to move around the php code I would like to know what I'm moving around is the right thing. Any ideas? If you need any more information please do ask :D
Thanks in advance for the help.
If anybody is still looking to find out how to to get the id in a post grid or create a specific widget for the grid you can use the following snippet I creatd for adding an icon before the post title. You will see inside the first function you can call $post-ID for use on any query.
//** Case Study Title Block Shortcodes ***********
//********************************
add_filter( 'vc_gitem_template_attribute_case_study_title','vc_gitem_template_attribute_case_study_title', 10, 2 );
function vc_gitem_template_attribute_case_study_title( $value, $data ) {
extract( array_merge( array(
'post' => null,
'data' => '',
), $data ) );
$atts_extended = array();
parse_str( $data, $atts_extended );
$atts = $atts_extended['atts'];
// write all your widget code in here using queries etc
$title = get_the_title($post->ID);
$link = get_permalink($post->ID);
$terms = get_the_terms($post->ID, 'case_categories');
$output = "<h4 class=\"case-title\">". get_the_icon($terms[0]->term_id) . $title ."</h4>";
return $output;
}
add_filter( 'vc_grid_item_shortcodes', 'case_study_title_shortcodes' );
function case_study_title_shortcodes( $shortcodes ) {
$shortcodes['vc_case_study_title'] = array(
'name' => __( 'Case Study Title', 'sage' ),
'base' => 'vc_case_study_title',
'icon' => get_template_directory_uri() . '/assets/images/icon.svg',
'category' => __( 'Content', 'sage' ),
'description' => __( 'Displays the case study title with correct icon', 'sage' ),
'post_type' => Vc_Grid_Item_Editor::postType()
);
return $shortcodes;
}
add_shortcode( 'vc_case_study_title', 'vc_case_study_title_render' );
function vc_case_study_title_render($atts){
$atts = vc_map_get_attributes( 'vc_case_study_title', $atts );
return '{{ case_study_title }}';
}
I got the same issue; here is how I solve it:
According to Visual Composer documentation: https://kb.wpbakery.com/docs/developers-how-tos/adding-custom-shortcode-to-grid-builder/
When you add the code below to functions.php, a new component will be added in your custom grid builder (in my example the name will be "Author"). There are a number of values you can get by post data template variable function and one of it not the name of the author but their ID (that's sad but at least you can use this value to get the author name).
The value is 'post_author' => ID of the author (for example '1')
Here is the function where I get the post author and display it (if author component was added to your custom grid in "custom grid builder"). Put it in functions.php of your child theme:
add_filter( 'vc_grid_item_shortcodes', 'my_module_add_grid_shortcodes' );
function my_module_add_grid_shortcodes( $shortcodes ) {
$shortcodes['vc_post_id'] = array(
'name' => __( 'Author', 'my-text-domain' ),
'base' => 'vc_post_id',
'category' => __( 'Content', 'my-text-domain' ),
'description' => __( 'Show current post author', 'my-text-domain' ),
'post_type' => Vc_Grid_Item_Editor::postType(),
);
return $shortcodes;
}
// output function
add_shortcode( 'vc_post_id', 'vc_post_id_render' );
function vc_post_id_render() {
$nn = '{{ post_data:post_author }}'; // usage of template variable post_data with argument "post_author"
return get_the_author($nn);
}
There is a little problem. It works but get_the_author is a deprecated function in WordPress. I'd appreciate any suggestions to make it more modern or if you name other alternatives please suggest.
Also, here is the list of available variables of vc_post_id_render from docs. Here they are:
WP_Post::__set_state(array(
'ID' => 69,
'post_author' => '1',
'post_date' => '2015-04-29 14:15:56',
'post_date_gmt' => '2015-04-29 14:15:56',
'post_content' => 'Your post content',
'post_title' => 'Your post title',
'post_excerpt' => '',
'post_status' => 'publish',
'comment_status' => 'open',
'ping_status' => 'open',
'post_password' => '',
'post_name' => 'post name',
'to_ping' => '',
'pinged' => '',
'post_modified' => '2015-06-17 11:18:41',
'post_modified_gmt' => '2015-06-17 11:18:41',
'post_content_filtered' => '',
'post_parent' => 0,
'guid' => 'http://wp.master/?p=69',
'menu_order' => 0,
'post_type' => 'post',
'post_mime_type' => '',
'comment_count' => '0',
'filter' => 'raw',
'filter_terms' =>
array (
),
))
this is your response
https://kb.wpbakery.com/docs/developers-how-tos/adding-custom-shortcode-to-grid-builder/
at Template variables usage
Exemple, in visual composer template you can use {{ post_date:ID }} to show post ID. I don't know how show tag.
I have a custom post type called tutorials.
I can go to mysite.com/tutorials and get a list of all the tutorials.
I have also created a custom taxonomy called tutorial_categories with the following code:
register_taxonomy(
'tutorial_categories',
'tutorials',
array(
'labels' => array(
'name' => 'Tutorial Categories',
'add_new_item' => 'Add New Tutorial Category',
'new_item_name' => "New Tutorial Category"
),
'show_ui' => true,
'show_tagcloud' => false,
'hierarchical' => true,
'hasArchive' => true
)
);
I think this is part of a plugin to allow me to do this.
How can I create a category page for a tutorial_category, so if someone goes to:
mysite.com/tutorials/php/
They will get a list of tutorials (custom post type) with the custom taxonomy of PHP.
Any help would be greatly appreciated as I have done some Googling and I cannot seem to find the answer to this question.
Thank you!
Leon.
First, make a new page template.
The easiest way is to copy your current page.php file and save it as: tutorials-page.php.
At the top include this:
<?php
/*
Template Name: Tutorials Page
*/
?>
Then replace the loop in the new tutorials-page.php file with the following custom loop:
<?php $args=array(
'post_type' => 'tutorials', //set the post_type to use.
'taxonomy' => 'tutorial_categories', // set the taxonomy to use.
'term' => 'php', //set which term to use.
'posts_per_page' => 10 // how many posts or comment out for all.
);
$tutorialsloop = new WP_Query($args);
if($tutorialsloop->have_posts()) : while($tutorialsloop->have_posts()) :
$tutorialsloop->the_post();
get_template_part( 'content' ); //or whatever method your theme uses for displaying content.
endwhile; endif; //end the custom post_type loop
?>
Then make a new page and assign this new page template to it.
Haven't tried this but looks promising.
http://wp-types.com/documentation/user-guides/creating-wordpress-custom-taxonomy-archives/