admin管理员组

文章数量:1323731

I'm having troubles understanding how add_rewrite_rule works in my case. I have a page which lists news from an external source. All items are linked with a "read more". Those links look like: domain/news/single/?id=12345&title=title-of-this-news

Everything works fine. If I click the link the "single" page reads the "id" param and displays the output I want it to.

Well to make this pretty I want the links to look like this: domain/news/12345/title-of-this-news which means /single/ not part of the url - the first part is the ID I need to fetch it's data and the title the last part.

Can someone help me with this? Thanks!

EDIT: due to one of the answers I came up with this to match my URL, params, and so on - but it is not working (permalinks are resaved):

// Register the custom rewrite rule.
function wpse_373628_init() {
    add_rewrite_rule(
        // Matches /news/<id>/<title-slug> in the URL.
        '^news-events/single/(\d+)/([^/]+)/?$',

        // You could also add &news_title=$matches[2], but I think the ID is
        // enough for you to identify the single news being requested.
        'index.php?pagename=news-events/single&newsID=$matches[1]&newsTitle=$matches[2]', // query by slug
//      'index.php?page_id=123&news_id=$matches[1]',          // or query by ID

        'top'
    );
}
add_action( 'init', 'wpse_373628_init' );

// And register the custom query arg.
function wpse_373628_query_vars( $vars ) {
    $vars[] = 'newsID';
    $vars[] = 'newsTitle'; // if you're using news_title in the rewrite rule
    return $vars;
}
add_filter( 'query_vars', 'wpse_373628_query_vars' );

I'm having troubles understanding how add_rewrite_rule works in my case. I have a page which lists news from an external source. All items are linked with a "read more". Those links look like: domain/news/single/?id=12345&title=title-of-this-news

Everything works fine. If I click the link the "single" page reads the "id" param and displays the output I want it to.

Well to make this pretty I want the links to look like this: domain/news/12345/title-of-this-news which means /single/ not part of the url - the first part is the ID I need to fetch it's data and the title the last part.

Can someone help me with this? Thanks!

EDIT: due to one of the answers I came up with this to match my URL, params, and so on - but it is not working (permalinks are resaved):

// Register the custom rewrite rule.
function wpse_373628_init() {
    add_rewrite_rule(
        // Matches /news/<id>/<title-slug> in the URL.
        '^news-events/single/(\d+)/([^/]+)/?$',

        // You could also add &news_title=$matches[2], but I think the ID is
        // enough for you to identify the single news being requested.
        'index.php?pagename=news-events/single&newsID=$matches[1]&newsTitle=$matches[2]', // query by slug
//      'index.php?page_id=123&news_id=$matches[1]',          // or query by ID

        'top'
    );
}
add_action( 'init', 'wpse_373628_init' );

// And register the custom query arg.
function wpse_373628_query_vars( $vars ) {
    $vars[] = 'newsID';
    $vars[] = 'newsTitle'; // if you're using news_title in the rewrite rule
    return $vars;
}
add_filter( 'query_vars', 'wpse_373628_query_vars' );
Share Improve this question edited Sep 14, 2020 at 8:26 ggzone asked Aug 24, 2020 at 11:29 ggzoneggzone 1111 silver badge4 bronze badges 4
  • What are the single and news? Are they Pages, i.e. posts of the page type? Also, if the pretty URL doesn't include the id, then would you still be able to identify what the single news feed is based solely on the title (e.g. the title-of-this-news)? – Sally CJ Commented Aug 25, 2020 at 2:42
  • @SallyCJ /news/ = list view: /single/ = single view. this pages are page types. I need the ID param for the single view to fetch all its news data via a JSON feed. this all works. I just want to make the url pretty. no unfortunately it can not access the single news data with only the title, I need the ID parsed as param. Does it make a difference? – ggzone Commented Aug 25, 2020 at 7:20
  • 1 If the ID is required to display the correct content then it needs to be in the URL. You can't hide it entirely unless it's possible to retrieve the ID from the title. – Jacob Peattie Commented Aug 25, 2020 at 15:25
  • @JacobPeattie i see. thank you! I'll update my question – ggzone Commented Aug 26, 2020 at 8:45
Add a comment  | 

1 Answer 1

Reset to default 1

If you haven't already done so, I suggest you to check out this Codex article which gives a good introduction on how you can use add_rewrite_rule() to rewrite a URL in WordPress.

Now if the news and single are Pages (i.e. posts of the page type) and that single is a child of the news Page, then in the second parameter for add_rewrite_rule() (i.e. the redirect URL), you would want to use pagename=news/single which will load the single Page.

Alternatively, you can use page_id=<ID> to query the Page by its ID instead.

See the WP_Query class for more details regarding pagename and page_id.

Then you would also want to use a custom query arg for the single news ID because for example you wouldn't be able to retrieve the ID using $_GET['id']. And then you should add the custom arg to the public query args which WordPress reads from the URL and pass them to WP_Query.

So having said that, try the following:

// Register the custom rewrite rule.
function wpse_373628_init() {
    add_rewrite_rule(
        // Matches /news/<id>/<title-slug> in the URL.
        '^news/(\d+)/([^/]+)/?$',

        // You could also add &news_title=$matches[2], but I think the ID is
        // enough for you to identify the single news being requested.
        'index.php?pagename=news/single&news_id=$matches[1]', // query by slug
//      'index.php?page_id=123&news_id=$matches[1]',          // or query by ID

        'top'
    );
}
add_action( 'init', 'wpse_373628_init' );

// And register the custom query arg.
function wpse_373628_query_vars( $vars ) {
    $vars[] = 'news_id';
//  $vars[] = 'news_title'; // if you're using news_title in the rewrite rule
    return $vars;
}
add_filter( 'query_vars', 'wpse_373628_query_vars' );

And be sure to flush the rewrite rules by simply visiting the permalink settings page (wp-admin » Permalink Settings) so that WordPress recognizes the new rewrite rule (above) and saves it in the database.

And also, to retrieve the news ID, you can use get_query_var( 'news_id' ).

本文标签: permalinksHow to addrewriterule with two parameters to a single view page