On the site I'm working now on there's a number of links hardcoded into templates, such as

  • Privacy and cookies
  • Registration policy
  • Search help

and so on.

The pages that are linked to these don't have any special design, they just inherit the default page layout.

The project I'm working on uses GIT and a workflow with multiple environments (several locals for different developers, staging, production). On all of those DBs usually are completely independent and non shared or synchronized.

What is the best way to link to these pages on frontend? I've thought about three options for now of which I'm currently using the latter one.

  1. If I hardcode links to them just by referencing an ID of a page (via get_permalink for example) then on staging the ID might not be the same and the link will be broken. Also the page is not reassignable which might not be good.
  2. If the project uses some kind of custom fields plugin like ACF or Metabox.io we might use that to create global fields per each link to allow editors to reassign them.
  3. The pages can be linked via creating a custom template and then retrieving the link to the first page (thanks to 'meta_key' => '_wp_page_template' WP_Query parameter) that uses this template. This solution is not optimal because it spams the project with potentially increasing number of duplicate templates that are all empty and don't serve any meaningful function as a part of theme.

So the question is, is there a better way to do the same thing in a native and flexible manner? Has somebody had experience solving the same problem?

  • sounds like you are overthinking it, or at least it is not clear what difficulty you are afraid facing. So the DBs are different, so what? Commented Feb 21, 2017 at 12:17
  • 1
    so what?? as @laxmana said, just get something to select the pages, whatever you feel like (options are better performance but if you cache the page it makes little difference Commented Feb 21, 2017 at 17:22
  • 1
    ... and every user is responsible to configure his own special setup Commented Feb 21, 2017 at 17:24
  • 1
    hardcoding anything is usually just stupid in the long run. writing proper code always takes more time, which is usually offset very quickly by not having bugs and wasting hours on WTF moments Commented Feb 21, 2017 at 20:53
  • 1
    ... obviously some things need to be hardcoded. what are those depend on the project, but generally links to pages do not fall into that category Commented Feb 21, 2017 at 20:55

4 Answers 4


I think the best way is to create Theme Options and let the administrator decide which page is each one, with a dropdown for example.

This way you can get the selected page no matter the environment.

  • Thanks! This kind of answers the question as it's a native alternative to creating a global field via a custom field plugin or a theme options framework. A bit menacing as the native theme options way requires a lot of custom coding but may be OK if an optimal code is found and can be just reused then. Commented Feb 21, 2017 at 16:05
  • With ACF you can create this kind of option in one minute.
    – Laxmana
    Commented Feb 21, 2017 at 23:28

There are a few ways to do this:

  1. get_permalink( get_page_by_path( 'slug-goes-here' ) )
  2. get_permalink( get_page_by_title( 'title-goes-here' ) )
  3. home_url( '/slug-goes-here/' )

Any of the above will work for you, thiw way you can avoid using post IDs but as long as the slug/title stays the same it will work.

Is it possible to get a page link from its slug?

  • That's another way, but it's just not safe/flexible enough. Editor can change both slug and title, and then the link will be broken. Anyway, thanks for a fresh suggestion! Commented Feb 21, 2017 at 15:53

I'm adding my own answer after some research. Here are the best options, to my mind, that allow to keep the solution relatively flexible and fast to implement, and a solution that I've ended up with. I've struggled to find a solution which could be, while keeping the advantages above, native as well.

  1. If standalone links (let's not call them hardcoded as this creates some confusion evidently) are used on permanent basis in a theme and the site makes use of custom fields — one easy solution could be to create a field. I'm not sure how it could be designed — should it be repeater? checkbox? should it be global? remains to be clarified.
  2. If standalone links are just few, 1 or 2 — we can simply use native custom templates; a couple of empty templates that inherit generic page design from, say, page.php, arguably, won't do any harm. This is not a scalable solution, though.

The third — final — solution that I'm using now is not native, but still employs the custom templates mechanism. It uses a method for registering custom templates without actually creating them described here — I changed the code provided there a bit to allow setting template names from theme (github).

So, basically, if you've got a standalone link somewhere in layout that should always stay in a certain place and should lead to a page created via admin — you provide a "virtual" custom template filename/title in a hooked function, associate this custom template with a page via Template admin setting and then grab the link to this page with _wp_page_template meta-key post query.


You might be looking for

1- get_permalink( get_page_by_path( 'slug' ) )

2- get_permalink( get_page_by_title( 'slug' ) )

3- home_url( '/slug/' )

Function get_page_by_path and get_page_by_title returns the Post Object.


  1. get_page_by_path

get_page_by_path( string $page_path, string $output = OBJECT, string|array $post_type = 'page' )

  1. get_page_by_title

get_page_by_title( string $page_title, string $output = OBJECT, string|array $post_type = 'page' )


You can get page/post from the template you have selected.

$pages = get_pages(array(
    'meta_key' => '_wp_page_template',
    'meta_value' => 'custom-template.php'
foreach($pages as $page){
    echo $page->ID.'<br />';

Above code returns the array of post objects of the pages that has a custom-template.php template selected.

If you just wanted out the page ids in return then you could try out get_posts function

$args = array(
    'post_type' => 'page',
    'fields' => 'ids',
    'nopaging' => true,
    'meta_key' => '_wp_page_template',
    'meta_value' => 'page-special.php'
$pages = get_posts( $args );
foreach ( $pages as $page ) 
   echo $page . '</br>';

Reference: Get page id by template

  • I see your rationale. But slug is not constant, client could change it any moment and break the link without even knowing it. Commented Aug 28, 2019 at 8:00
  • @certainlyakey I have updated my answer. Hope you will be able to solve your problem. Commented Aug 28, 2019 at 13:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.