I have install plugin Yoast SEO Premium,
with this plugin have some field is
yoast_wpseo_metadesc,yoast_wpseo_focuskw
but I can't add althought I used:
add_post_meta($post_id, 'yoast_wpseo_metadesc',$my_post['post_excerpt']);
This problem may be due to several concerns, here are some ideas :
Prefix meta keys with "_"
Yoast SEO prefix these custom fields entries with a "_" in the database. The key is not "yoast_wpseo_metadesc" but "_yoast_wpseo_metadesc". Same for "yoast_wpseo_focuskw", it's actually "_yoast_wpseo_focuskw".
Use update_post_meta() instead of add_post_meta()
Add_post_meta() can create a custom field for a post if the field does not exist. If it exists, it does not update it. It's always better to use the update_post_meta() function, more flexible. If the custom field already exists, it will be updated. Otherwise, the function will call add_post_meta() to create it.
In your case, a field maybe already exists with that name.
Be careful to where you execute your code
I think we need more information on where you launch your add_post_meta() function. Depending on the context, the approach is different. Here are some examples:
In single post page
If it's on your single page, you can use :
<?php
global $post;
update_post_meta( $post->ID, '_yoast_wpseo_metadesc', $post->post_excerpt );
update_post_meta( $post->ID, '_yoast_wpseo_focuskw', my_focus_keyword' );
?>
In function.php
Place this code in functions.php, it do that after each post saving, in admin section.
<?php
// Launch the update_post_meta on post saving.
add_action( 'save_post', 'my_yoast_saved_datas' );
function my_yoast_saved_datas( $post_id, $post ) {
// Check that your post is what you want
if ( $_POST['post_type'] == 'post' ) {
// Check if user can't do that
if ( ! current_user_can( 'edit_post', $post_id ) )
return;
}
update_post_meta( $post_id, '_yoast_wpseo_metadesc', $post->post_excerpt );
update_post_meta( $post_id, '_yoast_wpseo_focuskw', 'my_focus_keyword');
}
?>
Loop to update custom fields in one time
Launch one time, in functions.php or pack it on a plugin to launch on activation.
<?php
global $post;
// Array of args, change to your need
$args = array( 'post_type' => 'post', 'posts_per_page' => -1, 'post_status'=> 'publish' );
// Get alls posts
$my_posts = get_posts( $args );
// Loop on post
foreach ( $myposts as $post ) {
setup_postdata( $post );
global $post;
// Update on create custom fields
update_post_meta( $post->ID, '_yoast_wpseo_metadesc', $post->post_excerpt );
update_post_meta( $post->ID, '_yoast_wpseo_focuskw', 'my_focus_keyword');
}
wp_reset_postdata();
?>
Related
I'm trying to add a new admin column to my custom post type using the content of a custom field (ACF). The field I want to add is a 'post object' field, but it just displays the post title instead of the linked post from the ACF. I added a screenshot.
This is what I have so far:
function add_new_realisaties_column($columns) {
$columns['realisatie_line'] = 'Line';
return $columns;
}
add_filter('manage_realisaties_posts_columns', 'add_new_realisaties_column');
function add_new_realisaties_admin_column_show_value( $column, $post_id ) {
if ($column == 'realisatie_line') {
$post_object = get_field('realisatie_line');
if( $post_object ):
// override $post
$post = $post_object;
setup_postdata( $post );
$evdate = the_title();
wp_reset_postdata(); // IMPORTANT - reset the $post object so the rest of the page works correctly ?>
<?php endif;
echo $evdate;
}
}
add_filter('manage_realisaties_posts_custom_column', 'add_new_realisaties_admin_column_show_value', 10, 2);
/* Make the column sortable */
function set_custom_realisaties_sortable_columns( $columns ) {
$columns['realisatie_line'] = 'realisatie_line';
return $columns;
}
add_filter( 'manage_edit-realisaties_sortable_columns', 'set_custom_realisaties_sortable_columns' );
function realisaties_custom_orderby( $query ) {
if ( ! is_admin() )
return;
$orderby = $query->get('orderby');
if ( 'realisatie_line' == $orderby ) {
$query->set( 'meta_key', 'realisatie_line' );
$query->set( 'orderby', 'meta_value' );
}
}
add_action( 'pre_get_posts', 'realisaties_custom_orderby' );
There's a couple things I notice. One is that you shouldn't actually need to use the setup_postdata() function, because the ACF Post Object field uses get_post() which returns a full object already. You'd only do this if you're intended to override the global $post object, say on a single-{post_type}.php template, for instance.
Another thing is that it's generally more common to use a switch statement instead of an if/else for post columns. A bit pedantic, but something to note.
Lastly, the_title() will echo the title by default, so assigning it, and then echoing it later, can cause issues (namely leaving variables littered around the document). Consider using get_the_title() if you plan on assigning it to a variable. Also, I won't go into excruciating detail, but just using setup_postdata may not be enough to get the post helper functions to pull the data from where you want.
Now, with all that said, you should be able to just echo the post_title field of the $post_object from get_field(), since it returns a full formed WP_Post object. I put this on a test site of mine and it worked just as intended:
add_filter('manage_realisaties_posts_custom_column', 'add_new_realisaties_admin_column_show_value', 10, 2);
function add_new_realisaties_admin_column_show_value( $column, $post_id ){
switch( $column ){
case 'realisatie_line':
if( $post_object = get_field('realisatie_line') ){
echo $post_object->post_title;
}
break;
}
}
And here's what it looks like in the admin, note I just grabbed a random post for the Post Object relational field:
Try changing your add_new_realisaties_admin_column_show_value function to the code below. If the ACF field name is realisatie_line you are going to need to also pass a $post_id to get the specific meta data back for each particular post.
function add_new_realisaties_admin_column_show_value( $column, $post_id ) {
//Try using a switch/case for the column name
switch ( $column ) {
case 'realisatie_line': //Name of new column from add_new_realisaties_column function
echo get_the_title( get_post_meta( $post_id, 'realisatie_line', true ) ); //Getting the ACF post meta using the $post_id, passing it through the get_the_title function to get title of attached post
break;
default:
break;
}
}
When a new Wordpress post is being created using post category "A" (or "B" or "C"), I need to automatically check the Woocommerce-Memberships Disable restrictions checkbox with a PHP hook. This will allow all viewers unrestricted access to view the post.
checkbox picture[1]
I have tried adding an action to the "save_post" hook to add the "_wc_memberships_force_public" value of "yes" to the {wp_prefix}_post_meta table and the checkbox will show as checked because of this, however, when viewing the post it is still restricted. When I remove the action (by commenting it out from my functions.php file) and check the Disable restrictions checkbox manually before saving the post, the post can be viewed without restriction (as expected).
add_action( 'save_post', 'action_save_post_force_public', 99, 3);
function action_save_post_force_public($post_id, $post, $is_update){
$already_forced = get_post_meta( $post_id, '_wc_memberships_force_public', $single=true );
if ( 'yes' === $already_forced ){ return; }
$categories = get_the_category( $post_id );
if ( empty( $categories ) ){ return; }
$force_public_slugs = array('A', 'B', 'C');
foreach ( $categories as $term ){
if ( in_array( $term->slug, $force_public_slugs ) ){
update_post_meta( $post_id, '_wc_memberships_force_public', 'yes' );
break;
}
}
}
I expect all viewers to have unrestricted access to view the post content whether this box is checked automatically or manually. Instead it only works when manually checking the box.
Instead of using update_post_meta( $post_id, '_wc_memberships_force_public', 'yes' );, try this:
// Disable post restrictions (Woocommerce Membership)
$wc_membership = \WC_Memberships::instance();
$wc_membership->get_restrictions_instance()->set_content_public($post);
It works well for me ;)
You can find an example of this piece of code in the file woocommerce-memberships/includes/admin/class-wc-memberships-admin.php
I have made a function to apply a taxonomy term to post, if it has a post meta value set to true. This works as should.
The problem I am facing is that it only updates after I have manually saved/updated the post.
Is there any way to schedule this or do it dynamically for all posts inside the custom post type?
My code for the taxonomy term function:-
function save_cp_term_meta( $post_id, $post, $update ) {
$termshouldbe='new';
$meta_value = get_post_meta( $post->ID, 'new_used_cat', true );
if (!empty( $meta_value ))
{
$termshouldbe='used';
}
else
{
}
wp_set_object_terms($post_id,$termshouldbe,'vehicle_condition',false);
}
add_action( 'save_post', 'save_cp_term_meta', 10, 3 );
You can use WP_Cron() to schedule a task to run at a specific time each day and perform the update.
// check if the next cron is ours, if not schedule it.
if ( ! wp_next_scheduled( 'prefix_save_cp_term_meta_cron' ) ) {
wp_schedule_event( strtotime( '5:15PM' ), 'daily', 'prefix_save_cp_term_meta_cron' );
}
/**
* function to query for posts of a certain post type and update
* some term_meta based on a post_meta value.
*/
function prefix_save_cp_term_meta_runner() {
// make sure to set the correct post type you want here.
$args = array(
'post_type' => array( 'your post type' ),
'meta_key' => 'new_used_cat',
'posts_per_page' => -1,
);
// run the query.
$query = new WP_Query( $args );
// if the query has posts...
if ( $query->have_posts() ) {
// loop through them...
while ( $query->have_posts() ) {
$query->the_post();
// default value to use as term.
$termshouldbe = 'new';
// get the current post_meta if it exists.
$meta_value = get_post_meta( $post->ID, 'new_used_cat', true );
if ( ! empty( $meta_value ) ) {
// update the value for term based on having a value for new_used_cat.
$termshouldbe = 'used';
// NOTE: you may want to delete the post_meta here so that next
// iteration this query doesn't need to work with this post
// again as it's already processed.
}
// set the term with a value (either 'new' or 'used').
wp_set_object_terms( $post->ID, $termshouldbe, 'vehicle_condition', false );
}
// restore the main query.
wp_reset_postdata();
}
} // End if().
add_action( 'prefix_save_cp_term_meta_cron', 'save_cp_term_meta_runner' );
NOTE: You may want to look at adding this in intervals instead of at a fixed time - or run it via a system level cron job instead. This answer details some issues when working with WP_Cron() that might help you decide which method is best for you: https://wordpress.stackexchange.com/a/179774/37158
I'm trying to edit a field in the meta data of a post before it is being displayed on the screen.
I have been looking at the 'load-post.php' hook, but this is called before the post is loaded (if I've understood that correctly), so the post id and meta data are null.
I've tried other hooks, but I haven't been able to make this work.
The following post meta field needs to be changed before it is displayed on the edit page.
$post_price = get_post_meta(get_the_ID(), 'price', TRUE);
Example: Price = 10 in the database, but I want it to be Price = 15 when it is displayed on the post edit page.
Any links, tips and ideas are much appreciated. :)
Edit:
My current solution:
add_action('load-post.php','calculate_price');
function calculate_price(){
$post_id = $_GET['post'];
//get price from post by post_id and do stuff
}
Is this the correct way?
The best hook I found is load-post.php using $current_screen.
For Woocommerce product, that works :
add_action('load-post.php', "calculate_price" );
function calculate_price( ){
global $current_screen;
if( is_admin() && $current_screen->post_type === 'product' ){
$post_id = (int) $_GET['post'];
$post = get_post( $post_id );
//Do something
}
}
EDIT: okay I thought you just need to work with ID of post. If you need to change post objects (already loaded from db and ready to be printed), you can use 'the_post' instead. Since you just need to access to post id, I would do something like this:
function my_the_post_action( $post ) {
$screen = get_current_screen();
if( is_admin() && $screen->parent_base == 'edit' && get_post_type() == 'product' ) {
$post_id = $post->ID;
$price = (int) get_post_meta( $post_id, 'price', true );
update_post_meta( $post_id, 'price', $price + 5 );
}
}
add_action( 'the_post', 'my_the_post_action' );
This part:
get_post_type() == 'product'
is not necessary, but you should determine for which kind of post (based on post type, category, metafield etc.) you want to run this piece of code. Without it will be executed everytime in admin query. This code is not tested, if something is wrong feel free to report.
I have created a short code to display short description in woo commerce but it is not working on all posts. It is displaying the short description on some posts and not on others.
Function to create that short code in functions.php
function product_shortdesc_shortcode( $atts ){
// use shortcode_atts() to set defaults then extract() to variables
extract( shortcode_atts( array( 'id' => false ), $atts ) );
// if an $id was passed, and we could get a Post for it, and it's a product....
if ( ! empty( $id ) && null != ( $product = get_post( $id ) ) && $product->post_type = 'product' ){
// apply woocommerce filter to the excerpt
echo apply_filters( 'woocommerce_short_description', $product->post_excerpt );
}
}
// process [product_shortdesc] using product_shortdesc_shortcode()
add_shortcode( 'product_shortdesc', 'product_shortdesc_shortcode' );
The way i am getting the data in my single.php file
$custom = get_post_custom(get_the_ID());
$my_custom_field = $custom['woo_id'];
foreach ( $my_custom_field as $key => $value ) {
echo do_shortcode('[product_shortdesc id='.$value.']');
}
PS: in my normal post i have a custom field which has the value of product id of the product in woo commerece.
Your issue is that you are expecting shortcodes to function which no longer exist. On new installs, these pages won't be created, but if you are updating you may already have those pages in place.
Although the upgrade script does attempt to trash them for you, this might not have happened if they were customised. Delete them. Delete edit-account and change password, then go to your 'my account' page and click the change password/edit account links. You'll be taken to and endpoint which offers the same functionality.
Thanks
Short Code must not echo code instead return the things that needs to be rendered
Change this
echo apply_filters( 'woocommerce_short_description', $product->post_excerpt );
to
return apply_filters( 'woocommerce_short_description', $product->post_excerpt );