WordPress and PHP: Removing Parent Slug from Child Page Permalink - php

I feel like I'm very close with the code I have so far, but something is still not working. None of the other similar questions on Stack Overflow solve this issue.
I have parent pages and child pages (not posts, not custom post type) in WordPress, and the default mydomain.com/%postname% structure selected.
Currently the permalink structure for pages is mydomain.com/parent-page/child-page
In the backend on the single page editor, the desired permalink displays correctly (with the parent page removed). i.e. mydomain.com/child-page
However when I visit mydomain.com/child-page I get a 404.
I have flushed rewrite rules by visiting the permalink settings page already.
What am I doing wrong?
function wpse_101072_flatten_hierarchies( $page_link, $post ) {
$post = get_post($post);
$uri = '';
if($post->post_parent !== 0) {
$uri = get_post( $post->post_parent )->post_name . "/" . $uri;
return str_replace( $uri, '', $page_link );
} else {
return $page_link;
}
}
add_filter( 'page_link', 'wpse_101072_flatten_hierarchies', 10, 2 );
function wp_pages_permalink( $permalink_structure, $post_id ) {
if ( empty( $post_id ) ) return $permalink_structure ;
$post = get_post( $post_id );
if($post->post_parent !== 0) {
$par = get_post($post->post_parent);
$parname = $par->post_name . '/';
$permalink_structure = str_replace( '%pagename%', $post->post_name, $permalink_structure);
return $permalink_structure;
}
}
add_filter( 'page_link', 'wp_pages_permalink', 10, 2 );

Related

wordpress custom post type with custom category

I have created a custom post with the "products" name in the template and I want to add a custom category (products_cat) to this custom post.
I followed the steps until now, the URLs used to open as below (no custom categories)
https://example.com/products/ custom post title
Now I want the URLs to open with custom categories that I have added to that product. ( As follows) :
https://example.com/products/term1/term2/ ... / term n/ custom post title
I wrote the following code which changes the addresses exactly as I want
function wpa_course_post_link( $post_link, $id = 0 ){
$post = get_post($id);
$array = array();
if ( is_object( $post ) || $post->post_type != 'products'){
$terms = wp_get_object_terms( $post->ID, 'products_cat' );
foreach ( $terms as $list ) {
array_push( $array, $list->slug );
}
$category = implode('/', $array);
if( $terms ){
return str_replace( '%products_cat%' , $category , $post_link );
} else {
return str_replace( '%products_cat%' , "" , $post_link );
}
}
return $post_link;
}
add_filter( 'post_type_link', 'wpa_course_post_link', 1, 3 );
But when I click on the product with a new link, I get a 404 error
Note: I have clicked save once in the permilink and i used:
flush_rewrite_rules();
Can anyone solve the problem?
thanks

Rewrite Rules WordPress Returning Category Page Instead of Individual post

I'm trying to change the permalink only to one specific category and it works good on the changing, but the content isn't right.
It's showing the categories page with a lot of posts instead of the proper content of that post.
Can someone help me with this?
The code:
function custom_permalink( $permalink, $post, $leavename ) {
// Get the categories for the post
$category = get_the_category($post->ID);
if ( !empty($category) && $category[0]->cat_name == "Educational" ) {
$permalink = trailingslashit( home_url('/Educational/'. $post->post_name .'/' ) );
}
return $permalink;
}
add_filter( 'post_link', 'custom_permalink', 10, 3);
function custom_rewrite_rules( $wp_rewrite ) {
// This rule will will match the post id in %postname%-%post_id% struture
$new_rules['^Educational/([^/]+)/?$'] = 'index.php?name=$matches[1]';
$new_rules['^Educational/([^/]+)/?$'] = 'index.php?name=$matches[2]';
$new_rules['^Educational/?$'] = 'index.php?cat=61';
$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
return $wp_rewrite;
}
add_action('generate_rewrite_rules', 'custom_rewrite_rules');

Limiting Wordpress Tag Pages for Tags with more than 10 associated posts

as the title said, I'm trying to write a custom WordPress filter which limits the creation of Tag pages so that Tag pages are only created if the Tag has more than 10 associated posts. This is because we have so many tags with <10 associated posts, and it's creating a lot of noise.
I've not worked with WordPress for almost 5 years now, so I'm a bit rusty.
Here's what I'm trying, and it's not quite working:
<?php
function limit_taxonomies_by_count( $args, $taxonomy, $object_type ) {
$terms = get_terms('post_tag');
foreach($term in $terms) {
if ($term->count < 10) {
$args = array(
'public' => false
)
}
}
return $args
}
add_filter('register_taxonomy_args', 'limit_taxonomies_by_count' );
?>
Please let me know what I'm missing!
You can do as follows to achieve your job done. You can remove those tags link whose associated posts count are less than 10, so visitors can never click on those tags.
function modify_term_link_url( $links ) {
global $post;
if( !$post ) return $links;
$terms = get_the_terms( $post->ID, 'post_tag' );
if ( is_wp_error( $terms ) ) {
return $terms;
}
if ( empty( $terms ) ) {
return false;
}
$links = array();
foreach ( $terms as $term ) {
if( $term->count < 10 ){
$link = '';
}else{
$link = get_term_link( $term, 'post_tag' );
if ( is_wp_error( $link ) ) {
return $link;
}
}
$links[] = '' . $term->name . '';
}
return $links;
}
add_filter( 'term_links-post_tag', 'modify_term_link_url' );
Codes goes to your active theme's functions.php
Instead of preventing the admins / editors from adding new tags, you could just "hide" Tag archive pages that don't meet the criteria (10 or more posts assigned to them). This way, admins/editors can still create / use new tags that might eventually reach 10 or more posts which will then make them visible to visitors.
To do so, you can use the template_redirect action hook to do something before the Tag archive page is loaded on screen (that something is explained next), then the is_tag() function to check whether the visitor is trying to access a Tag archive page, and finally the wp_redirect() function to do the actual redirection:
/**
* Redirects visitors to the homepage for Tags with
* less than 10 posts associated to them.
*/
function wp76515_tag_maybe_redirect(){
// We're viewing a Tag archive page
if ( is_tag() ) {
// Get Tag object
$tag = get_tag(get_queried_object_id());
// Tag's post count
$post_count = $tag->count;
// This tag has less than 10 posts,
// redirect visitor
if ( $post_count < 10 ) {
wp_redirect(
home_url(), // The URL we're sending the visitor to
'302' // The HTTP status, 302 = 'Moved Temporarily'
);
}
}
}
add_action('template_redirect', 'wp76515_tag_maybe_redirect', 5);
You may want to change the redirect code to 301 (Moved Permanently) to remove existing Tag pages with less than 10 posts from Google's index as well.

Remove parent page from URL without plugin?

On certain pages I'm looking to remove the parent page from the URL.
So instead of:
example.com/parent-page/child-page
I'd like it to display:
example.com/child-page
I have tried the following method but no luck:
function wpse_101072_flatten_hierarchies( $post_link, $post ) {
if ( 'page' != $post->post_type )
return $post_link;
$uri = '';
foreach ( $post->ancestors as $parent ) {
$uri = get_post( $parent )->post_name . "/" . $uri;
}
return str_replace( $uri, '', $post_link );
}
add_filter( 'post_type_link', 'wpse_101072_flatten_hierarchies', 10, 2 );
Is there any known solution that works without a plugin?

If has_term, load other Wordpress theme

This is what I want to accomplish. In Wordpress I've created a taxonomy called categorie with the terms app, web and branding. When a project has the term app, I want to load another theme / blog. When a project has the term web or branding, I want to load single.php. The last one works just fine.
This is my code so far
function load_single_template($template) {
$new_template = '';
if( is_single() ) {
global $post;
if( has_term('app', 'categorie', $post) ) {
$new_template = get_theme_roots('themeApp');
} else {
$new_template = locate_template(array('single.php' ));
}
}
return ('' != $new_template) ? $new_template : $template;
}
add_action('template_include', 'load_single_template');
So when a project has the term app, I want to load the theme themeApp. Any suggestions? Thanks in advance.
We had to accomplish a similar task in our plugin, AppPresser. You can see our solution here: https://github.com/WebDevStudios/AppPresser/blob/master/inc/theme-switcher.php
Basically, you need to change the theme name in 3 filters: 'template', 'option_template', 'option_stylesheet'.
Getting the category is not so simple though, because the template check happens early enough in the WordPress process that the global $post and $wp_query objects are not available.
Here is one way that can be accomplished:
<?php
add_action( 'setup_theme', 'maybe_theme_switch', 10000 );
function maybe_theme_switch() {
// Not on admin
if ( is_admin() )
return;
$taxonomy = 'category';
$term_slug_to_check = 'uncategorized';
$post_type = 'post';
// This is one way to check if we're on a category archive page
if ( false !== stripos( $_SERVER['REQUEST_URI'], $taxonomy ) ) {
// Remove the taxonomy and directory slashes and it SHOULD leave us with just the term slug
$term_slug = str_ireplace( array( '/', $taxonomy ), '', $_SERVER['REQUEST_URI'] );
// If the term slug matches the one we're checking, do our switch
if ( $term_slug == $term_slug_to_check ) {
return yes_do_theme_switch();
}
}
// Try to get post slug from the URL since the global $post object isn't available this early
$post = get_page_by_path( $_SERVER['REQUEST_URI'], OBJECT, $post_type );
if ( ! $post )
return;
// Get the post's categories
$cats = get_the_terms( $post, $taxonomy );
if ( ! $cats )
return;
// filter out just the category slugs
$term_slugs = wp_list_pluck( $cats, 'slug' );
if ( ! $term_slugs )
return;
// Check if our category to check is there
$is_app_category = in_array( $term_slug_to_check, $term_slugs );
if ( ! $is_app_category )
return;
yes_do_theme_switch();
}
function yes_do_theme_switch( $template ) {
// Ok, switch the current theme.
add_filter( 'template', 'switch_to_my_app_theme' );
add_filter( 'option_template', 'switch_to_my_app_theme' );
add_filter( 'option_stylesheet', 'switch_to_my_app_theme' );
}
function switch_to_my_app_theme( $template ) {
// Your theme slug
$template = 'your-app-theme';
return $template;
}

Categories