For a custom post type in WordPress, I want to automatically use the post ID as a slug for the post. For this, I use the following code:
add_action( 'wp_insert_post', 'change_slug', 10, 3 );
function change_slug( $post_id, $post, $update ) {
if ( $post->post_type != 'custom_post_type' ) {
return;
}
wp_update_post(
array(
'ID' => $post_id,
'post_name' => $post_id, // slug
)
);
}
This code is based on a previous answer on so: https://wordpress.stackexchange.com/a/160483/181877
However, using this code I cannot even open the new post page for this CPT in WordPress. instead, I get a 503 Service unavailable message, which I believe is caused by a timeout.
I'm not sure what's wrong with my code. Any pointers?
Ok, I figured it out.
It seems like it resulted in an infinite loop, not sure why. But I included an extra if statement to check for the $update variable, making sure the code is not run during the update of a post and only when a new one is published. This seemed to have resolved it.
Below is my final code:
add_action( 'wp_insert_post', 'change_slug', 10, 3 );
function change_slug( $post_id, $post, $update ) {
if ( $post->post_type != 'custom_post_type' ) {
return;
}
if ( $update ) { // added this
return;
}
wp_update_post(
array(
'ID' => $post_id,
'post_name' => $post_id,
)
);
}
Related
I'd like to update post_author after update post by getting current user ID, but when I use this function wordpress created new post with correct author by copied current post
function change_author () {
if ( ! wp_is_post_revision( $post_id ) ){
$post= array(
'ID' => $post_id,
'post_author' => get_current_user_id(),
);
wp_update_post( $post );
}
}
add_action('save_post', 'change_author');
I'd use the wp_insert_post_data hook instead of save_post. Rather than updating the post after it's saved, it's probably better to change the data before it gets inserted into the database as part of the save post action. Here's what I'd do:
function change_author ( $data ) {
if ( ! wp_is_post_revision( $data['ID'] ) ){
$data['post_author'] = get_current_user_id();
}
return $data;
}
add_filter( 'wp_insert_post_data', 'change_author', 10, 1 );
I created a custom post type with a plugin. A registered user can insert a new post from front-end and it is saved as draft. When I edit it in back-end I need it is saved with private visibility.
I found this snippet to set visibility by default:
public function force_dpa_request_private( $data , $postarr ) {
if( empty( $data['post_name'] ) && 'my-cpt' == $postarr['post_type'] )
$data[ 'post_status' ] = 'private';
return $data;
}
but it works only on first insert, when I edit it the visibility change to public...
You can hook to the save_post which is called after the post is created or updated.
<?php
add_action( 'save_post', 'callback_save_post', 10, 3);
function callback_save_post( $post_ID, $post, $update ){
if ( 'my-cpt' === get_post_type( $post_ID) && ! wp_is_post_revision( $post_ID ) ) {
// unhook this function so it doesn't loop infinitely
remove_action('save_post', 'callback_save_post', 10 );
// Make the post private if it is edited else make it draft.
if ( $update ) {
$postarr = array(
'ID' => $post_ID,
'post_status' => 'private'
);
} else {
$postarr = array(
'ID' => $post_ID,
'post_status' => 'draft'
);
}
// Update the post.
wp_update_post( $postarr );
// re-hook this function.
add_action( 'save_post', 'callback_save_post', 10, 3);
}
}
Reference:
https://developer.wordpress.org/reference/hooks/save_post/
https://codex.wordpress.org/Function_Reference/wp_update_post
Slight variation from your question, but you can still edit the post on creation, if you make all your post type private. Thus this works.
function force_type_private($post)
{
if ($post['post_type'] == 'Your Post Type')
$post['post_status'] = 'private';
return $post;
}
add_filter('wp_insert_post_data', 'force_type_private');
I am wondering if you're able to help me with the following WordPress customization. We're using the WP Job Manager plugin (https://wpjobmanager.com/) and I'd need a little help with a slug/permalink edit.
In the documentation is an article available which explains the following: at the current situation links are generated as follows: domain.com/job/job-name. However, I need the following structure: domain.com/job-category/job-name.
Please check: https://wpjobmanager.com/document/tutorial-changing-the-job-slugpermalink/
The article explains this. Please check the code on: Example: Adding the category to the base URL. When I remove the 'job' in the following code, the job listings are working fine, but the rest of my website returns in a 404 error (also after saving the permalinks).
$args['rewrite']['slug'] = 'job/%category%';
To
$args['rewrite']['slug'] = '%category%';
Full code:
function job_listing_post_type_link( $permalink, $post ) {
// Abort if post is not a job
if ( $post->post_type !== 'job_listing' )
return $permalink;
// Abort early if the placeholder rewrite tag isn't in the generated URL
if ( false === strpos( $permalink, '%' ) )
return $permalink;
// Get the custom taxonomy terms in use by this post
$terms = wp_get_post_terms( $post->ID, 'job_listing_category', array( 'orderby' => 'parent', 'order' => 'ASC' ) );
if ( empty( $terms ) ) {
// If no terms are assigned to this post, use a string instead (can't leave the placeholder there)
$job_listing_category = _x( 'uncat', 'slug' );
} else {
// Replace the placeholder rewrite tag with the first term's slug
$first_term = array_shift( $terms );
$job_listing_category = $first_term->slug;
}
$find = array(
'%category%'
);
$replace = array(
$job_listing_category
);
$replace = array_map( 'sanitize_title', $replace );
$permalink = str_replace( $find, $replace, $permalink );
return $permalink;
}
add_filter( 'post_type_link', 'job_listing_post_type_link', 10, 2 );
function change_job_listing_slug( $args ) {
$args['rewrite']['slug'] = 'job/%category%';
return $args;
}
add_filter( 'register_post_type_job_listing', 'change_job_listing_slug' );
Well, I was also stuck in some type of error once. But in my case, I was creating everything my self. So I change the template accordingly.
However, In you case, I think it relates to URL Re-Writing. Please check out the following links. I hope those will help.
http://www.wpbeginner.com/plugins/how-to-change-custom-post-type-permalinks-in-wordpress/
https://codex.wordpress.org/Rewrite_API/add_rewrite_rule
https://paulund.co.uk/rewrite-urls-wordpress
i want to call my function when user or admin or another plugin sending publish post.
any hook exist for this ?
i try some hook like publish_post.
but this work just if i put my code in that plugin which sending post.
i want my plugin Independent and when sending post in any plugin or admin or every where .... , my function in my plugin do something.
this is for SEO reason and its hard to say why i want do this.
some code i write
function post_published_notification($post) {
$ID= $post->ID;
$my_post = array(
'ID' => $ID,
'post_title' => "anything"
);
wp_update_post( $my_post );
}
add_action( 'publish_post', 'post_published_notification', 10, 2 );
There's are hook called save_post - do_action( 'save_post', $post_ID, $post, $update );. You could check if $post->post_status is set to published and maybe keep your own record of whether it's had the published status before.
Example on how to use it:
function post_published_notification( $post_ID, $post, $update ) {
if ( $post->post_status == 'publish' && ! get_post_meta( $post_ID, 'published_notification_set', true ) ) {
update_post_meta( $post_ID, 'published_notification_set', 1 );
}
}
add_action( 'save_post', 'post_published_notification', 10, 3 );
I originally wanted to be able to password protect a category. At the very least I wanted it to be password-protected, but preferably a username and password login. Since I have been unsuccessful for days at finding a solution I have now resorted to using WordPress's built-in password protection for posts.
The issue I am having is I will be posting via e-mail and in order to have these posts password-protected I need to login to Wordpress and then manually select password-protected and enter a password in the dashboard.
I would like to be able to have all posts that appear in a specific category be password-protected with the same password by default. Eliminating having to log in to Wordpress and manually select password protect.
I know there is a function <?php post_password_required( $post ); ?> that I need to use but I am not sure how to implement it or where.
Based on this WordPress StackExchange answer. Tested only with a regular dashboard. Publishing via email has to be tested, but I suppose the hook gets called in this kind of posting.
add_action( 'save_post', 'wpse51363_save_post' );
function wpse51363_save_post( $post_id ) {
//Check it's not an auto save routine
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
//Check it's not an auto save routine
if ( wp_is_post_revision( $post_id ) )
return;
//Perform permission checks! For example:
if ( !current_user_can( 'edit_post', $post_id ) )
return;
$term_list = wp_get_post_terms(
$post_id,
'category',
array( 'fields' => 'slugs' )
);
if( in_array ( 'the-category-slug', $term_list ) )
{
// Unhook this function so it doesn't loop infinitely
remove_action( 'save_post', 'wpse51363_save_post' );
// Call wp_update_post update, which calls save_post again.
wp_update_post( array(
'ID' => $post_id,
'post_password' => 'default-password' )
);
// Re-hook this function
add_action( 'save_post', 'wpse51363_save_post' );
}
}
add_filter( 'wp_insert_post_data', function( $data, $postarr ){
if ( 'book' == $data['post_type'] && 'auto-draft' == $data['post_status'] ) {
$data['post_password'] = wp_generate_password();
}
return $data;
}, '99', 2 );