how to change edit url with "Id" to edit url with "Slug" in Wordpress - wordpress

I have this is WordPress Post editing Url:
https://example.com/wp-admin/post.php?post=ID&action=edit
and I want to change it to Slug Not the ID Like This:
https://example.com/wp-admin/post.php?post=Slug&action=edit
I was trying to edit the post with this Url but is not working:
https://example.com/wp-admin/post.php?post=MyPostSlug&action=edit

In order to change the edit post link structure, you can use the get_edit_post_link filter like so:
add_filter( 'get_edit_post_link', 'so_73914075_get_edit_post_link', 10, 3);
function so_73914075_get_edit_post_link($link, $post_id, $context) {
$post = get_post( $post_id );
if ( ! in_array( $post->post_type, array( 'post', 'page' ) ) ) {
return $link;
}
$post_type_object = get_post_type_object( $post->post_type );
if ( 'revision' === $post->post_type ) {
$action = '';
} elseif ( 'display' === $context ) {
$action = '&action=edit';
} else {
$action = '&action=edit';
}
if ( 'display' === $context ) {
$post_type = '&post-type=' . $post->post_type;
} else {
$post_type = '&post-type=' . $post->post_type;
}
$custom_edit_link = str_replace( '?post=%d', '?post-name=%s', $post_type_object->_edit_link );
return admin_url( sprintf( $custom_edit_link . $action . $post_type, $post->post_name ) );
}
This will change the edit links for regular posts and pages to something like this:
https://example.com/wp-admin/post.php?post-name=the-post-slug&action=edit&post-type=post
WARNING: make sure you limit this to only the post types you need to change the URL for. Making this change global will almost surely
have unintended effects over other plugins
However, making the admin panel actually load the edit screen is not that easy.
Looking at the source code of the wp-admin/post.php file, you will see that there is no way to hook into the flow and populate the $post_id variable with the post id matching the slug you are sending through.
That means you have 2 options:
RECOMMENDED Update the edit link to whatever format you want and then create an admin redirect function that pulls the slug from the initial URL and redirects to the actual edit page with the ?post=%d in it.
NOT RECOMMENDED Create a new admin edit page that will understand your URL structure and include the wp-admin/post.php after the code that pulls the $post_id based on the slug.
The 2nd method might come with lots of extra code you need to write to cover all the cases and all the instances a post reaches the post.php in the admin panel

Related

WordPress plugin to tag category while posting

I'm not a big programmer, but this week get in touch with Openai. It's my first experience with AI. I tried to create code that works as a Wordpress plugin to meet a need.
I make a lot of posts and each post I have to mark the same category. Then I thought that there should be a plugin to mark the category so that when I need to post again, the category would already have its checkbox checked, so I wouldn't need to scroll the selection box of the categories and mark the same category.
Openai generated this code, it didn't work, from what I noticed the cookie is not being created.
Plugin Name: Category Marker
Description: Checks the checkbox of the previously marked category when making a post
Version: 0.1
Author:
*/
//This is the first function
function catemarcada_create_cookie() {
global $post;
if ( isset( $post ) && 'post-new.php' == basename( $_SERVER['SCRIPT_FILENAME'] ) ) {
// Create cookie when making a post
if ( isset( $post->ID ) ) {
$categoryID = get_post_meta($post->ID, '_category_id', true);
setcookie( 'catemarcada', $categoryID, time() + (86400 * 30), "/"); // 86400 = 1 day
}
}
}
add_action( 'wp_loaded', 'catemarcada_create_cookie' );
//This is the second function
function catemarcada_get_cookie() {
global $post;
if ( isset( $post ) && 'post-new.php' == basename( $_SERVER['SCRIPT_FILENAME'] ) ) {
// Get cookie when accessing the post-new.php file
if ( isset( $_COOKIE['catemarcada'] ) ) {
$categoryfound = $_COOKIE['catemarcada'];
}
}
}
add_action( 'wp_loaded', 'catemarcada_get_cookie' );
//This is the third function
function catemarcada_check_category() {
global $post;
if ( isset( $post ) && 'post-new.php' == basename( $_SERVER['SCRIPT_FILENAME'] ) ) {
// Compare the value of the cookie with the category IDs in the WordPress database
$categories = get_categories();
foreach ( $categories as $category ) {
if ( $categoryfound == $category->cat_ID ) {
// Check the checkbox field of the category in the WordPress database
echo '<input type="checkbox" name="'.$category->cat_ID.'" checked="checked" />';
}
}
}
}
add_action( 'wp_loaded', 'catemarcada_check_category' );
// Redirect to post-new.php
add_action('post_updated', 'redirect_post_new', 10, 3);
function redirect_post_new( $post_id, $post, $update ){
if( $update ){
wp_redirect( admin_url( 'post-new.php' ) );
exit();
}
}
This is the description of the plugin I asked to be generated:
Write PHP code that works as a Wordpress plugin. The plugin will only work when I access the “post-new.php” file.
First function:
When making a post, the plug-in will create a cookie with the name “catemarcada”.
This cookie will store the selected category ID during text posting. The cookie must expire within 360 days.
Second function:
When accessing the “post-new.php” file, check if the cookie named “catemarcada” already exists. If it exists, do not create it again.
And every time I access the “post-new.php” file, the plug-in will look up the ID that was recorded in the cookie named “catemarcada” and record the ID in a variable called “categoryfound”.
Third function:
The plug-in should compare the ID that is in the variable called “categoryfound” with the IDs of the categories in the Wordpress database.
If the ID that is in the variable called “categoryfound” is the same as the ID of any of the categories in the Wordpress database, check the checkbox field of the category in the Wordpress database in question.
When making a post, redirect to the post-new.php file.

How can I replace a custom-post-type with a custom post category in permalink without getting a 404 in wordpress?

I'm a wordpress newbie. I will try to describe my problem in the clearest way possible.
I'm trying to do two things here:
Remove CPT from a permalink.
Add a custom taxonomy type where it used to be the CPT in the permalink.
Permalinks on site used to be like this:
http://example.com/custom-post-type/post-name
I managed to remove the CPT from the permalink based on this:
how to remove custom post type from wordpress url?
Then I modify my code to add the custom taxonomy type to the permalink to be like this:
http://example.com/post-category/post-name
This is my code:
function remove_cpt_slug( $post_link, $post ) {
if ( 'custom-post-type-name' === $post->post_type && 'publish' === $post->post_status ) {
$post_tags = get_the_terms($post->ID, 'custom-post-type-name-category');
$post_link = str_replace( '/' . $post->post_type . '/', '/' . $post_tags[0]->slug . '/', $post_link );
}
return $post_link;
}
add_filter( 'post_type_link', 'remove_cpt_slug', 10, 2 );
function add_cpt_post_names_to_main_query( $query ) {
// Return if this is not the main query.
if ( ! $query->is_main_query() ) {
return;
}
// Return if this query doesn't match our very specific rewrite rule.
if ( ! isset( $query->query['page'] ) || 2 !== count( $query->query ) ) {
return;
}
// Return if we're not querying based on the post name.
if ( empty( $query->query['name'] ) ) {
return;
}
// Add CPT to the list of post types WP will include when it queries based on the post name.
$query->set( 'post_type', array( 'post', 'page', 'custom-post-type-name' ) );
}
add_action( 'pre_get_posts', 'add_cpt_post_names_to_main_query' );
This worked but now every post from my CPT gives a 404. How can I solve this?

How to display a custom post type feed in the sidebar of a category page?

I have a custom post type setup and in the sidebar of every page on the site it is set to display a random post from that custom post type (named "reviews").
This works great everywhere except for category pages for the normal / standard / default post type of "post" where even though the query is setup to only use the custom post type "reviews" it only pulls from the default blog posts.
Is there something I am leaving out to make sure this works even on category pages?
Here is the code I am using that works fine on non category pages, you can see it is restricted to just the "reviews" post type:
// the query
$review_query = new WP_Query( array (
'post_type' => 'reviews', // Display just this post type
'orderby' => 'rand',
'posts_per_page' => 1,
)
);
You can create shortcode that you can put in any widget area you want.
Something like:
function wpb_rand_posts() {
if ( $the_query->have_posts() ) {
$string .= '<ul>';
while ( $the_query->have_posts() ) {
//do stuff
}
$string .= '</ul>';
/* Restore original Post Data */
wp_reset_postdata();
} else {
$string .= 'no posts found';
}
return $string;
}
add_shortcode('wpb-random-posts','wpb_rand_posts');
add_filter('widget_text', 'do_shortcode');
Ok so it turns out the code I had added to functions.php to make sure a different custom post type was displaying in the category feed was interfering.
So this was the original code snip I used to do that:
// Show notable cases in tag archives
function themeprefix_show_cpt_archives( $query ) {
if( is_category() || is_tag() && empty( $query->query_vars['suppress_filters'] ) ) {
$query->set( 'post_type', array(
'nav_menu_item', 'post', 'cases'
));
return $query;
}
}
And I changed that to this:
// Show notable cases in tag archives
function themeprefix_show_cpt_archives( $query ) {
if( empty( $query->query_vars['suppress_filters'] ) && ( is_category() || is_tag() ) ) {
$query->set( 'post_type', array(
'nav_menu_item', 'post', 'cases'
));
return $query;
}
}
And added suppress_filters' => true to my query, and this resolved my issue. If anyone else runs into this see what else in your theme may be modifying the query at a higher level through a function like this or plugin as this is a solution specific to the code in my theme.

How to mark wordpress posts as read?

I want to make something similar to what Techcrunch have on their site. For now I use wordpress plugin that mark posts as new and think to modified it to achieve similar functionality but the plugin won't work for ajax loading.
What I want to make is when user open new post, automatically after he returns to the front page, title and excerpt of the post to be color faded. How to make this with setting cookie and make it to work for title and excerpt on any page (for post list, grids etc.), instead of single post page. And also I need this to work when new posts are loaded with ajax.
I tried this function and It's work ok, but now I need text label to change to Old after user open the post, and then to inject some css to the title. Also, this is not perfect, because I want all posts to be New on first visit, an then to change to Old after user open them.
function wpb_lastvisit_set_cookie() {
if ( ! is_admin() && ! isset( $_COOKIE['lastvisit'] ) ) {
setcookie( 'lastvisit', $current, time() + 3600 * 24 * 100, COOKIEPATH, COOKIE_DOMAIN, false );
}
}
add_action( 'init', 'wpb_lastvisit_set_cookie');
function wpb_lastvisit_the_title ( $title, $id ) {
if ( !in_the_loop() || is_singular() || get_post_type( $id ) == 'page' ) return $title;
// if no cookie then just return the title
if ( !isset($_COOKIE['lastvisit']) || $_COOKIE['lastvisit'] == '' ) return $title;
$lastvisit = $_COOKIE['lastvisit'];
$publish_date = get_post_time( 'U', true, $id );
if ($publish_date > $lastvisit) $title .= ' New';
if ($publish_date < $lastvisit) $title .= ' Old';
return $title;
}
add_filter( 'the_title', 'wpb_lastvisit_the_title', 10, 2);

Wordpress next_posts_link Linking to wrong URL

I have next_posts_link setup on the single.php, and it generates the following URL:
http://mywebsite.com/news/article1/page/2
However, this url would be redirected to
http://mywebsite.com/news/article1
Any way to get to the second page?
It seems that it's an issue with Wordpress permalinks. I currently use a custom permalink structure
/%category%/%postname%/
Setting the permalinks as default fixes this issue, but this project needs to have the custom permalinks.
You should be using next_post_link() which is meant to navigate between single posts. next_posts_link naviugate between pages
If you however need to navigate a paged post (using <--nextpage-->), then you should make use of wp_link_pages
EDIT
I have recently did the same exact thing on WPSE. As I explain in that post, the structure you need is not available for any permalink structure outside the default permalink structure.
Just a note before I paste that answer, I have done that for the /%postname%/ permalink structure. Just change all instances of /%postname%/ to the appropriate structure
POST FROM WPSE
As I said, this whole setup you are after is not possible natively with pretty permalinks. Your setup probably works with default permalink structure as both queries (the main query and your custom query) read these permalinks in the same way. When you switch to pretty permalinks, the two queries on the single page interpret the URL differently causing one or the other to fail when you try to paginate your custom query
Single pages was never meant to be paginated in this manner, specially using pretty permalinks. I have gone and played around with a couple of ideas, and the best way to accomplish this is
To write your own pagination functions that can read the page number from the URL
Write your own function that can append the page number to the URL, something like adding /2/ to the URL of single pages.
I must stress, if you are paginating single post with <!--nextpage-->, your post will also paginate together with your custom query. Also, if your permalink structure is not set to /%postname%/, the code will fail and display an error message through wp_die()
THE CODE
Here is the code that will get the next/previous page and also add the pagenumber to the URL.
function get_single_pagination_link( $pagenum = 1 ) {
global $wp_rewrite;
if( is_singular() && $wp_rewrite->permalink_structure == '/%postname%/') {
$pagenum = (int) $pagenum;
$post_id = get_queried_object_id();
$request = get_permalink( $post_id );
if ( $pagenum > 1 ) {
$request = trailingslashit( $request ) . user_trailingslashit( $pagenum );
}
return esc_url( $request );
}else{
wp_die( '<strong>The function get_single_pagination_link() requires that your permalinks are set to /%postname%/</strong>' );
}
}
You can use this function as follow to get the link for any page in the single page when paginating your custom query
get_single_pagination_link( 'pagenumber_of_previous_or_next_page' );
Again, as I said, there is no pagination function that will be able to paginate your custom query or read pagenumbers from the URL, so you have to write your own.
Here is my idea of creating links to the next and previous pages in your custom query. If you look closely, you will see how I have used the previous declared function get_single_pagination_link() to get the links to the next and previous pages
function get_next_single_page_link ( $label = null, $max_page = 0 ) {
global $wp_query;
if ( !$max_page ) {
$max_page = $wp_query->max_num_pages;
}
$paged = ( get_query_var('page') ) ? get_query_var('page') : 1;
if( is_singular() ) {
$next_page = intval($paged) + 1;
if ( null === $label ) {
$label = __( 'Next Page »' );
}
if ( ( $next_page <= $max_page ) ) {
return '' . $label . '';
}
}
}
function get_previous_single_page_link( $label = null ) {
$paged = ( get_query_var('page') ) ? get_query_var('page') : 1;
if( is_singular() ) {
$prev_page = intval($paged) - 1;
if ( null === $label ) {
$label = __( '« Previous Page' );
}
if ( ( $prev_page > 0 ) ) {
return '' . $label . '';
}
}
}
You can now use this two functions in your code to paginate your custom query. Both functions work exactly the same as get_next_posts_link() and get_previous_posts_link() and uses the same exact parameters, so you'll need to keep in mind that you need to pass the $max_page parameter for your custom query
Here is your custom query with these functions.
function get_related_author_posts() {
global $authordata, $post;
$paged = ( get_query_var('page') ) ? get_query_var('page') : 1;
$args = array(
'posts_per_page' => 2,
'paged' => $paged
);
$authors_posts = new WP_Query( $args );
$output = '';
if( $authors_posts->have_posts() ) {
$output = '<ul>';
while( $authors_posts->have_posts() ) {
$authors_posts->the_post();
$output .= '<li>' . get_the_title() . '' . get_the_excerpt() . '</li>';
}
$output .= '</ul>';
$output .= get_previous_single_page_link();
$output .= get_next_single_page_link( null , $authors_posts->max_num_pages );
wp_reset_postdata();
}
return $output;
}
If you want your long post to be shown 2 or 3 pages . You just have to add <!--nextpage--> in your post . The content after it will be shown in the next page . Reference

Resources