Home WordpressWordPress cơ bản Tìm hiểu về WordPress Rewrite

Tìm hiểu về WordPress Rewrite

by admincp

wordpress rewrite
Sau khi cấu hình đường dẫn trong wordpress bằng cách vào menu settings->permalinks có 6 lựa chọn:
Default: không sử dụng rewrite, để nhìn được bản chất wordpress url mà rewrite convert thành:
eg: post url có dạng http://localhost/test-wordpress/?p=123
Day and name: base-url/ngày,tháng,năm/post-name
Month and name: base-url/năm,tháng/sample-post
Post name: base-url/post-name
Custom structure: sử dụng rewrite tag, chúng ta có 1 số rewrite tag:
%category%: category name
%postname%: post name
%tag%: post tag
%author%: user
%pagename%

%postname%

%post_id%

%year%

%day%

%hour%

%minute%
%second%
%monthnum%

%posttype%

đây là rewrite tag mặc định của wordpress được sinh ra từ post,tag..
Nếu bạn dùng custom post type và muốn sử dụng rewrite tag cho custom post thì cài plugin “Custom Post Type Permalinks”
Sau khi cài sẽ có thêm phần custom post type permalink ở cuối menu settings->permalinks và sử dụng rewrite tag trong đường dẫn custom post.
custom post type permalink - hoangweb.com

Sau đó chúng thể dùng được rewrite tag cho custom post. ví dụ chằng hạn bạn có tạo custom post: “tutorial” thì taxonomy tag là %tutorial_taxonomy%
Để xem rewrite tag của custom post permalinks sử dụng filter hook post_type_link.

add_filter('post_type_link', 'filter_post_type_link', 10, 3);
function filter_post_type_link($link, $post,$leavename)
{
	print_r($link);
	return $link;
}

Chú ý: post_type link filter cần phải trả về giá trị không sẽ bị lỗi.
custom post taxonomy chứa giá trị của query category_name, nó có thể là 1 term taxonomy slug hoặc nhiều hơn một nếu post thiết lập nhiều categories.

category_name=slug1/slug2/sulg3

Nếu category bao gồm category mẹ (parent) và category con (sub category) trong custom post URL bạn có thể làm gọn đi chỉ sử dụng 1 category slug. Copy đoạn code sau vào functions.php và tuỳ chỉnh thêm theo ý bạn.

function filter_post_type_link($link, $post,$leavename)
{
    if ($post->post_type != 'tutorial_posttype' || 'publish' != $post->post_status)
        return $link;        
    if (($cats = (array)wp_get_post_terms($post->ID, tutorial_tax)))
    {
       $cat=reset($cats);
        while($cat && $cat->parent){
            $cat=get_term_by('id',$cat->parent,$cat->taxonomy);
            break;
        }
        //if(!$cat) return $link;
        $link = str_replace('%tutorial_taxonomy%',$cat->slug, $link); // see custom function defined below
        $pt=get_post_type_object($post->post_type); 
        $link = str_replace( '/' . $pt->rewrite['slug'] . '/', '/', $link );
    }
    return $link;
}
add_filter('post_link', 'filter_post_type_link', 10, 3);
add_filter('post_type_link', 'filter_post_type_link', 10, 3);

filter “post_type_link” sẽ thay đổi lại post url. Một vài trường hợp gây ra lỗi 404 not found là do mất một số tham số query post_type,page…hãy sử dụng thêm action “pre_get_posts” để xác định dữ liệu. Ví dụ code sau đây xác định lại post_type trước khi lấy posts data tránh xẩy ra lỗi 404.

add_action( 'pre_get_posts', 'my_post_queries' );
function my_post_queries( $query ) {
    global $wp_query;
    // Only noop the main query
    if ( ! $query->is_main_query() )
        return;
    // do not alter the query on wp-admin pages and only alter it if it's the main query    
    if ($query->is_main_query()){   
        $query->set( 'numberposts', -1 );
        
        if((is_single() || is_home() || is_search() ) && !$query->get('post_type')){
             $posttype=get_post_types();   
             if(!is_search()) unset($posttype['page']);
             unset($posttype['nav_menu_item']);
             $query->set('post_type',$posttype);
        }
        // alter the query for the home and category pages
        if(is_home() || is_search()){            
            $query->set('posts_per_page', get_option('posts_per_page'));
            
        }
    }
    return $query;
}

THam khảo ví dụ khác về filter post_type_link.

// Add filter to plugin init function
add_filter('post_type_link', 'gallery_permalink', 10, 3);
// Adapted from get_permalink function in wp-includes/link-template.php
function gallery_permalink($permalink, $post_id, $leavename) {
    $post = get_post($post_id);
    $rewritecode = array(
        '%year%',
         '%monthnum%',
         '%day%',
          '%hour%',
          '%minute%',
                   '%second%',
                   $leavename? '' : '%postname%',
                   '%post_id%',
                   '%category%',
                   '%author%',
                   $leavename? '' : '%pagename%',);
if ( '' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft')) ) {
                   $unixtime = strtotime($post->post_date);

                   $category = '';
                   if ( strpos($permalink, '%category%') !== false ) {
                   $cats = get_the_category($post->ID);
                   if ( $cats ) {
                   usort($cats, '_usort_terms_by_ID'); // order by ID
                   $category = $cats[0]->slug;
                   if ( $parent = $cats[0]->parent )
                   $category = get_category_parents($parent, false, '/', true) . $category;
                   }
                   // show default category in permalinks, without
                   // having to assign it explicitly
                   if ( empty($category) ) {
                   $default_category = get_category( get_option( 'default_category' ) );
                   $category = is_wp_error( $default_category ) ? '' : $default_category->slug;
                   }
                   }

                   $author="";
                   if ( strpos($permalink, '%author%') !== false ) {
                   $authordata = get_userdata($post->post_author);
                   $author = $authordata->user_nicename;
                   }

                   $date = explode(" ",date('Y m d H i s', $unixtime));
                   $rewritereplace =
                   array(
                   $date[0],
                   $date[1],
                   $date[2],
                   $date[3],
                   $date[4],
                   $date[5],
                   $post->post_name,
                   $post->ID,
                   $category,
                   $author,
                   $post->post_name,
                   );
                   $permalink = str_replace($rewritecode, $rewritereplace, $permalink);
} else { // if they're not using the fancy permalink option
}
return $permalink;
}
add_filter( 'page_rewrite_rules', 'wpse7243_page_rewrite_rules' );
function wpse7243_page_rewrite_rules( $rewrite_rules )
{
    // The most generic page rewrite rule is at end of the array
    // We place our rule one before that
    end( $rewrite_rules );
    $last_pattern = key( $rewrite_rules );
    $last_replacement = array_pop( $rewrite_rules );
    $rewrite_rules +=  array(
        '(.+?)/([0-9]+)/([^/]+)/([^/]+)/?$' => 'index.php?pagename=$matches[1]&id=$matches[2]&fname=$matches[3]&lname=$matches[4]',
        $last_pattern => $last_replacement,
    );
    return $rewrite_rules;
}

Add new rewrite rules

Mỗi khi bạn có 1 cấu trúc url mới, ví dụ: thì cần thêm rewrite rule.

add_filter('rewrite_rules_array','wp_insertMyRewriteRules');
// Adding a new rule
function wp_insertMyRewriteRules($rules)
{
    $newrules = array();
    $newrules['(profile)/(.*)$'] = 'index.php?pagename=profile&profile=$matches[2]';
    return $newrules + $rules;
}

Nhớ sau khi thêm cấu trúc mới thì update rewrite bằng cách gọi $wp_rewrite->flush_rules(); và thiết lập lại ở trong mục settings->permalinks là được, nếu chưa được thì load page và đợi vài giây.
Để lấy tham số trong url, bạn không dùng được $_GET vì phải nhìn thấy tham số trên địa chỉ, trong wordpress có hàm get_query_var() sẽ giúp bạn nhưng trước tiên phải đăng ký url query var.

add_filter('query_vars','wp_insertMyRewriteQueryVars');	
// Adding the id var so that WP recognizes it
function wp_insertMyRewriteQueryVars($vars)
{
    array_push($vars, 'profile');
    return $vars;
}

Đoạn code trên tôi đăng ký tham số ‘profile’ ở url: ‘/profile/huyhoang08’ theo rewrite url ở trên thì ‘huyhoang08’ là giá trị của tham số profile, bạn sẽ lấy tham số này như sau:

echo get_query_var('profile');

Cuối cùng update lại rewrite:

add_filter('init','flushRules');
// Remember to flush_rules() when adding rules->nhớ là pải chạy cái này (hay pải flush) thì rewrite mới có tác dụng.
function flushRules(){
    global $wp_rewrite;
    $wp_rewrite->flush_rules();
}

Mình lấy ví dụ là, bạn muốn tạo các url có cấu trúc sau:
www.example.com/events/?location=nsw,qld&industry=web+mobile
rewrite: www.example.com/events/location/nsw,qld/industry/web+mobile/
Tạo rewrite rules nhanh sử dụng action “generate_rewrite_rules”.

add_action( 'generate_rewrite_rules', 'eg_add_rewrite_rules' );
function eg_add_rewrite_rules() {
    global $wp_rewrite;
 
    $new_rules = array(
        'event/(industry|location)/(.+?)/(industry|location)/(.+?)/?$' => 'index.php?post_type=eg_event&' . $wp_rewrite->preg_index(1) . '=' . $wp_rewrite->preg_index(2) . '&' . $wp_rewrite->preg_index(3) . '=' . $wp_rewrite->preg_index(4),
        'event/(industry|location)/(.+)/?$' => 'index.php?post_type=eg_event&' . $wp_rewrite->preg_index(1) . '=' . $wp_rewrite->preg_index(2)
    );
    $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}

Hàm Tạo permlinks.

function eg_get_filter_permalink( $taxonomy_slug, $term ) {
    global $wp_query;
 
    // If there is already a filter running for this taxonomy
    if( isset( $wp_query->query_vars[$taxonomy_slug] ) ){
        // And the term for this URL is not already being used to filter the taxonomy
        if( strpos( $wp_query->query_vars[$taxonomy_slug], $term ) === false ) {
            // Append the term
            $filter_query = $taxonomy_slug . '/' . $wp_query->query_vars[$taxonomy_slug] . '+' . $term;
        } else {
            // Otherwise, remove the term
            if( $wp_query->query_vars[$taxonomy_slug] == $term ) {
                $filter_query = '';
            } else {
                $filter = str_replace( $term, '', $wp_query->query_vars[$taxonomy_slug] );
                // Remove any residual + symbols left behind
                $filter = str_replace( '++', '+', $filter );
                $filter = preg_replace( '/(^+|+$)/', '', $filter );
                $filter_query = $taxonomy_slug . '/' . $filter;
            }
        }
    } else {
        $filter_query = $taxonomy_slug . '/' . $term;
    }
 
    // Maintain the filters for other taxonomies
    if( isset( $wp_query->tax_query ) ) {
 
        foreach( $wp_query->tax_query->queries as $query ) {
 
            $tax = get_taxonomy( $query['taxonomy'] );
 
            // Have we already handled this taxonomy?
            if( $tax->query_var == $taxonomy_slug )
                continue;
 
            // Make sure taxonomy hasn't already been added to query string
            if( strpos( $existing_query, $tax->query_var ) === false )
                $existing_query .= $tax->query_var . '/' . $wp_query->query_vars[$tax->query_var] . '/';
        }
 
    }
 
    if( isset( $existing_query ) )
        $filter_query = $existing_query . $filter_query;
 
    return trailingslashit( get_post_type_archive_link( 'eg_event' ) . $filter_query );
}

-Ví dụ bạn tạo permalinks cho custom post taxonomy với taxonomy=’location’ và term=’nsw’ , bạn chỉ việc gọi:

// Link to page with only events in NSW
echo eg_get_filter_permalink( 'location', 'nsw' );
</pre>
Cuối cùng Generate Rewrite Rule.
<pre lang="php">
function eg_generate_rewrite_rules( $post_type, $query_vars = array() ) {
    global $wp_rewrite;
 
    if( ! is_object( $post_type ) )
        $post_type = get_post_type_object( $post_type );
 
    $new_rewrite_rules = array();
 
    $taxonomies = get_object_taxonomies( $post_type->name, 'objects' );
 
    // Add taxonomy filters to the query vars array
    foreach( $taxonomies as $taxonomy )
        $query_vars[] = $taxonomy->query_var;
 
    // Loop over all the possible combinations of the query vars
    for( $i = 1; $i <= count( $query_vars );  $i++ ) {
 
        $new_rewrite_rule =  $post_type->rewrite['slug'] . '/';
        $new_query_string = 'index.php?post_type=" . $post_type->name;
 
        // Prepend the rewrites & queries
        for( $n = 1; $n <= $i; $n++ ) {
            $new_rewrite_rule .= "(' . implode( '|', $query_vars ) . ')/(.+?)/';
            $new_query_string .= '&' . $wp_rewrite->preg_index( $n * 2 - 1 ) . '=' . $wp_rewrite->preg_index( $n * 2 );
        }
 
        // Allow paging of filtered post type - WordPress expects 'page' in the URL but uses 'paged' in the query string so paging doesn't fit into our regex
        $new_paged_rewrite_rule = $new_rewrite_rule . 'page/([0-9]{1,})/';
        $new_paged_query_string = $new_query_string . '&paged=' . $wp_rewrite->preg_index( $i * 2 + 1 );
 
        // Make the trailing backslash optional
        $new_paged_rewrite_rule = $new_paged_rewrite_rule . '?$';
        $new_rewrite_rule = $new_rewrite_rule . '?$';
 
        // Add the new rewrites
        $new_rewrite_rules = array( $new_paged_rewrite_rule => $new_paged_query_string,
                                    $new_rewrite_rule       => $new_query_string )
                             + $new_rewrite_rules;
    }
 
    return $new_rewrite_rules;
}

Using rewrite tag

Sử dụng rewrite tag với custom post thì có plugin “custom post type permalinks”, tuy nhiên bạn sẽ tự học được cách tạo rewrite tag riêng mà không dùng plugin. Rewrite tag còn gọi là custom variables.

function rewrite_bank(){
	// add to our plugin init function
	global $wp_rewrite;
	$gallery_structure="/bank/%year%/%monthnum%/%bank%";
	$wp_rewrite->add_rewrite_tag("%bank%", '([^/]+)', "bank=");
	$wp_rewrite->add_permastruct('bank', $gallery_structure, false);
}
add_action('init','rewrite_bank');

Hoặc Sử dụng hàm add_rewrite_tag. Ví dụ sau đăng ký rewrite tag %film_title%

add_rewrite_tag('%film_title%','([^&]+)');

Dùng rewrite tag để đặt vào rewrite URL.e.g:
/films/%film_title%.html
tương ứng với URL: /films/phim-bo-ba-di-thoa.html
thì giá trị của tag %film_title% sẽ là ‘phim-bo-ba-di-thoa’. Để lấy giá trị rewrite tag ta dùng hàm query_vars hoặc get_query_var.

$wp_query->query_vars['film_title']

Để nhận được bài viết mới vui lòng đăng ký kênh kiến thức WordPress từ A-Z ở Form bên dưới. Bạn cũng có thể nhận được sự trợ giúp trên TwitterFacebook

Liên hệ

Công ty chuyên Thiết kế website uy tín nhất Miền Bắc: http://vinastar.net

Hotline tư vấn: 0989 48 3456

Nguồn: Sưu tầm trên internet

You may also like

Leave a Comment