How to change custom post type, blog post and page permalink by template?

modify post works different than modify page than modify custom post type permalink. Here is how to modify all of them within your template code only and give the whole page a custom url structure.

modify custom post type permalink

add_action( 'init', 'rewriteCustomPostUrls' );

function rewriteUrls() {
    global $wp_rewrite;

    $version = '/product/%product%/version/%version%';
    $wp_rewrite->add_rewrite_tag( "%product%", '([^/]+)', "product=" );
    $wp_rewrite->add_rewrite_tag( "%version%", '([^/]+)', "version=" );
    $wp_rewrite->add_permastruct( 'version', $version, false );
}

modify post permalink

add_action( 'init', 'rewritePostPermalink' );

function rewritePostPermalink(){
    global $wp_rewrite;

   $wp_rewrite->permalink_structure = "/product/%product%/news/%postname%";

}

modify page permalink

add_action( 'init', 'rewritePostPermalink' );

public function rewritePagePermalink(){
    global $wp_rewrite;

    $wp_rewrite->page_structure = "/product/%product%/page/%pagename%";
}

After that it’s required to filter custom variables like %product% out of get_permalink response. For each type, post, page or custom there is a different filter. Heads up! page_link filter parameter 2 isn’t the $post as with post_type_link and post_link but the page_id.

add_filter( 'post_type_link', 'permalinkRewrite');
add_filter( 'post_link', 'permalinkRewrite' );
add_filter( 'page_link', 'permalinkRewrite' );

function permalinkRewrite( $permalink, $post ) {
    if (gettype($post) === "integer"){
        //page_link $post parameter is the ID instead of the object
        $post = get_post($post);
    }

    //removed code - get your variable here
    $product = "demoProduct";

    if ( $product ) {
            $permalink = str_replace( '%product%', $product->getSlug(), $permalink );
    }

    return $permalink;
}

Finally, add some rewrite rules to catch the new permalink.

add_filter( 'rewrite_rules_array', 'insertCustomRewriteRules' );

function insertCustomRewriteRules( $rules ) {
    $customRules                                         = [];
    $customRules[ 'product/([^/]+)/version/([^/]+)/?$' ] = 'index.php?version=$matches[2]'; //custom post type
    $customRules[ 'product/([^/]+)/news/([^/]+)/?$' ] = 'index.php?name=$matches[2]'; //post
    $customRules[ 'product/([^/]+)/page/([^/]+)/?$' ] = 'index.php?pagename=$matches[2]'; //page

    return $customRules + $rules;
}