1

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

1 Answer 1

3

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

8
  • This is exactly what I am looking for . but few issues .. How can I use template manufacture.php because for example.com/production/[manufacturer slug] and brand.php for example.com/production/[brand slug] > Also I tried to use it upto 3 levels i.e example.com/production/[manufacturer slug]/[brand slug] /[model slug] but it didn't work . posting code shortly
    – terminator
    Commented Jun 7, 2021 at 10:37
  • I have made the edits to the orgiinal question as per my last comment .. please have a look
    – terminator
    Commented Jun 7, 2021 at 11:19
  • 1
    Ha, you're almost there. I'll edit the answer for your case.
    – Jos
    Commented Jun 7, 2021 at 16:27
  • 1
    I have updated the original answer for you.
    – Jos
    Commented Jun 7, 2021 at 16:35
  • 1
    Nope, I never use a builder and as few plugs as possible
    – Jos
    Commented Jun 10, 2021 at 5:31

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.