Display content according to current URL

The question:

I want to create most of the website structure based on the external API

Manufactures -> Brands

Here is how the output of API look like

array(2) {
  [0]=>
      object(stdClass)#448 (6) {
        ["id"]=>
        string(2) "17"
        ["full_name"]=>
        string(11) "manufacture 1"
        ["label"]=>
        string(8) "manufacture 1"
        ["Description"]=>
        string[25]  "Description manufacture 1"
        ["url"]=> 
        string(15) "/manufacture-1/"
        ["brands"]=>
        array(2) {
          [0]=>
          object(stdClass)#442 (27) {
            ["id"]=>
            string(3) "151"
            ["full_name"]=>
            string(34) "brand 1"
            ["label"]=>
            string(19) "brand 1"
            ["Description"]=>
            string[25]  "Description Brand 1"
            ["url"]=> 
            string(23) "/manufacture-1/brand-1/"
            }
          [1]=>
          object(stdClass)#142 (27) {
            ["id"]=>
            string(3) "152"
            ["full_name"]=>
            string(34) "brand 2"
            ["label"]=>
            string(19) "brand 2"
            ["Description"]=>
            string[25]  "Description Brand 2"
            ["url"]=> 
            string(23) "/manufacture-1/brand-2/"
          }
        }
      }
  [1]=>
      object(stdClass)#2448 (6) {
        ["id"]=>
        string(2) "19"
        ["full_name"]=>
        string(11) "manufacture 2"
        ["label"]=>
        string(8) "manufacture 2"
        ["Description"]=>
        string[25]  "Description manufacture 2"
        ["url"]=> 
        string(15) "/manufacture-2/"
        ["brands"]=>
        array(2) {
          [0]=>
          object(stdClass)#2442 (27) {
            ["id"]=>
            string(3) "351"
            ["full_name"]=>
            string(34) "brand 3"
            ["label"]=>
            string(19) "brand 3"
            ["Description"]=>
            string[25]  "Description Brand 3"
            ["url"]=> 
            string(23) "/manufacture-2/brand-3/"
            }
          [1]=>
          object(stdClass)#3442 (27) {
            ["id"]=>
            string(3) "352"
            ["full_name"]=>
            string(34) "brand 4"
            ["label"]=>
            string(19) "brand 4"
            ["Description"]=>
            string[25]  "Description Brand 4"
            ["url"]=> 
            string(23) "/manufacture-2/brand-4/"
          }
        }
      }
}

So based on above api I want to create link and display data according
For eg:

On home page I will display 2 manufacturers

if user click on manufacturer 1

he goes to page https:/example.com/manufacture-1

and then we display two brands – Brand 1 and Brand 2 and description of Manufacturer 1

If I click on Brand 1 then
he goes to page https:/example.com/manufacture-1/brand-1

and then we display data accordingle

SO how can I do this i.e
If I am on page https:/example.com/manufacture-1/brand-1 , I detect what is url and display content accordingly

Please point me in the right direction , how to proceed on this

EDIT ->

Based on your answer , @Jos Faber I added code but with a bit edit to accomodate 3rd quary var (Manufactures -> Brands -> Models)

following is the code

add_filter( 'rewrite_rules_array','jf_insert_rewrite_rules' );
function jf_insert_rewrite_rules( $rules ) {
  $newrules['^production(.*)/(.*)/(.*)/?$'] = 'index.php?manufacturer=$matches[1]&brand=$matches[2]&model=$matches[3]';
  return $newrules + $rules;
}

add_filter('query_vars', 'jf_add_query_vars');
function jf_add_query_vars( $vars ) {
    $vars[] = 'manufacturer'; 
    $vars[] = 'brand';
    $vars[] = 'model'; 
    return $vars;
} 

add_action('template_redirect', 'jf_manufacturer_brand_templates');
function jf_manufacturer_brand_templates() {
  if (get_query_var('manufacturer') || get_query_var('brand') || get_query_var('model')) {  
    if (file_exists(get_template_directory() . '/manu_brand.php')) {
      add_filter( 'template_include', function() {
        return get_template_directory() . '/manu_brand.php';
      });
    }
  }
}

code of manu_brands.php is

echo "Manufacturer=".get_query_var('manufacturer').'<br>';
echo "brand=". get_query_var('brand').'<br>';
echo "model=". get_query_var('model').'<br>';

var_dump(
    get_query_var('manufacturer'), 
    get_query_var('brand'),
    get_query_var('model')
);
  1. https://www.servers-hosting.com/production/manufacture-1/brand-1/model-1/ —- Works perfect

  2. https://www.servers-hosting.com/production/manufacture-1/brand-1/ — See page it returns wrong value for wrong query var

  3. https://www.servers-hosting.com/production/manufacture-1/ —- 404 error

Also for template redirect I had change to || instead of &&

Can you please help me out with this please

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

For this to work, you would have to add a rewrite that rewrites https://example.com/[manufacturer slug]/[brand slug] to index.php with e.g. manufacturer=[manufacturer slug]&brand=[brand slug].
e.g.:

add_filter( 'rewrite_rules_array','jf_insert_rewrite_rules' );
function jf_insert_rewrite_rules( $rules ) {
  $newrules['^(.*)/(.*)/?$'] = 'index.php?manufacturer=$matches[1]&brand=$matches[2]';
  return $newrules + $rules;
}

Remember to goto permalinks page and hit save for the rewrite rules to be updated.

Mind you! It would then not be possible anymore to have a level 1 subpage under a page e.g. /about/contact because this would be replaced with the /[manufacturer slug]/[brand slug] rewrite.
It would probably be better to prefix it with a tag, e.g. /production/manufacturer-1/brand-1 with a rewrite rule like this: ^production/(.*)/(.*)/?$

On top of that, you would need to register the query vars, e.g.:

add_filter('query_vars', 'jf_add_query_vars');
function jf_add_query_vars( $vars ) {
    $vars[] = 'manufacturer'; 
    $vars[] = 'brand'; 
    return $vars;
} 

You would probably want your own template for this pages, so that you can pull from the external api. That could be done by checking the existence of the manufacturer and brand params:

add_action('template_redirect', 'jf_manufacturer_brand_templates');
function jf_manufacturer_brand_templates() {
  if (get_query_var('manufacturer') && get_query_var('brand')) {  
    if (file_exists(get_template_directory() . '/manu_brand.php')) {
      add_filter( 'template_include', function() {
        return get_template_directory() . '/manu_brand.php';
      });
    }
  }
}

You could also have multiple cases here, for if only the manufacturer is available, to show brands per manufacturer. Or even brand only, to show brand detail.

In that template, you can grab the params like this:

var_dump(
    get_query_var('manufacturer'), 
    get_query_var('brand')
);

// hit API with these params and show the result


UPDATE

You had an error in your rewrite rule, the ^production(.*)/ would not match correctly, because my intention was to use production/....

The easiest is to add two more rewrite rules. It could be done in one rewrite rule, but for your understanding of these rules it’s better to make three of them, see code below.

I’ve also updated the function that handles the template selection, so you can see how you could select the correct template. This could also be done in one template, but it’s imho better to have separate templates and separate rules.

Let me know if this helped you ( and remember to goto permalinks page and hit save for the rewrite rules to be updated 😉 ).

add_filter('query_vars', 'jf_add_query_vars');
function jf_add_query_vars( $vars ) {
    $vars[] = 'manufacturer'; 
    $vars[] = 'brand'; 
    $vars[] = 'model'; 
    return $vars;
} 

add_action('template_redirect', 'jf_manufacturer_brand_templates');
function jf_manufacturer_brand_templates() {
  $manufacturer = get_query_var('manufacturer');
  $brand = get_query_var('brand');
  $model = get_query_var('model');
  if ( ! empty($manufacturer) && ! empty($brand) && ! empty($model) ) {  
    if (file_exists(get_template_directory() . '/model-detail.php')) {
      add_filter( 'template_include', function() { return get_template_directory() . '/model-detail.php'; });
    }
  } else if ( ! empty($manufacturer) && ! empty($brand) ) {
    if (file_exists(get_template_directory() . '/brand-detail.php')) {
      add_filter( 'template_include', function() { return get_template_directory() . '/brand-detail.php'; });
    }
  } else if ( ! empty($manufacturer) ) {
    if (file_exists(get_template_directory() . '/manufacturer-detail.php')) {
      add_filter( 'template_include', function() { return get_template_directory() . '/manufacturer-detail.php'; });
    }
  }
}

function jf_insert_rewrite_rules( $rules ) {
  $newrules['^production/(.*)/(.*)/(.*)/?$'] = 'index.php?manufacturer=$matches[1]&brand=$matches[2]&model=$matches[3]';
  $newrules['^production/(.*)/(.*)/?$'] = 'index.php?manufacturer=$matches[1]&brand=$matches[2]';
  $newrules['^production/(.*)/?$'] = 'index.php?manufacturer=$matches[1]';
  return $newrules + $rules;
}
add_filter( 'rewrite_rules_array','jf_insert_rewrite_rules' );

You can see output of working examples here:
https://jos.studioparkers.nl/wpplay/production/manufacturer-1/brand-1/model-1
https://jos.studioparkers.nl/wpplay/production/manufacturer-1/brand-1
https://jos.studioparkers.nl/wpplay/production/manufacturer-1


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment