Home › Toolset Professional Support › [Resolved] making a relationship with 3 variables
This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.
Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.
Sun | Mon | Tue | Wed | Thu | Fri | Sat |
---|---|---|---|---|---|---|
- | 9:00 – 13:00 | 9:00 – 13:00 | 9:00 – 13:00 | 9:00 – 13:00 | 9:00 – 13:00 | - |
- | 14:00 – 18:00 | 14:00 – 18:00 | 14:00 – 18:00 | 14:00 – 18:00 | 14:00 – 18:00 | - |
Supporter timezone: Asia/Karachi (GMT+05:00)
This topic contains 16 replies, has 2 voices.
Last updated by Waqar 2 years, 4 months ago.
Assisted by: Waqar.
Tell us what you are trying to do?
Im trying to make pages for services we offer for specific hardware
Im trying to get the system to create a page for a given location, for a model (of a PC) from the Brand of a PC
Ex. Dell Inspiron London (var1, var2, var3)
Your examples show 1-many or many to many but from 2 variables only. Itried to follow the video of relationships but couldnt get it.
I have created Post Type for Location, Brand and Model but dont know how to connect everything.
Is there any documentation that you are following?
Is there a similar example that we can see?
What is the link to your site?
Hi,
Thank you for contacting us and I'd be happy to assist.
From the performance standpoint, a better structure would be to use a single custom post type e.g. 'Service Items' and then attach the 3 variables using 3 custom taxonomies:
- Brands
- Models
- Locations
If for some reason, you'd prefer to keep using this custom post types and relationships approach, you'll need to introduce one central post type 'Service Items', that will connect the individual record of each hardware to their respective 3 variable posts.
So, in total, you'll have 4 custom post types:
1. Service Items
2. Brands
3. Models
4. Locations
And 3 one-to-many relationships, so that:
a). 1 Brand can be linked to many Service Items
b). 1 Model can be linked to many Service Items
c). 1 Location can be linked to many Service Items
I hope this helps and please let me know if you need any further assistance around this.
regards,
Waqar
Hi Waqar
Firstly - can I ask if these posts end up in the public domain or are private between me and Toolset? Id prefer to keep everything private.
Thank you for a detailed answer. But I need a little more help.
The option of using 3 taxonomies looks lke it will build a flat structure whereas what I want is a heirarchical structure. Correct me if I am wrong.
Service Item - Brand 1
Service Item - Model1
Service Item - Location 1
and so on
What I want is
Location1 - Brand1 - Model1,
Location1 - Brand1 - Model2
By Adding 10 locations, and 10 brands and 10 models, I should end up with 10x10x10 = 1000 pages whereas using taxonomies, it looks like I will end up with 30 pages.
Thank Waqar.
Thanks for writing back.
The support forum replies are public by default, but we can remove particular information or make specific replies private, as requested by the customer. So, just let me know and I'll do that.
It doesn't matter if you go with the approach of using the custom taxonomies or the post-relationships, the actual pages of interest would only be the individual posts pages in the post type 'Services Items' (call it 'service items', 'hardware pages', 'services page' etc as deemed fit for your project).
The use of custom taxonomy or the post-relationships is only the delivery or assignment method, to categorize those actual posts/records/pages, with respect to variables brand, model, and location.
The storage structure would be flat in both cases, but you'd be able to show those variables in the hierarchal form on the front end. It would be the responsibility of the admin person creating those posts/records/pages that the correct brand, model, and location are assigned.
I hope this makes sense and I'm setting your next reply as private so that you can share more specific details about what those service hardware pages actually represent and how you plan to show this data on the front end.
I'll be in a better position to guide you pick the more efficient approach, accordingly.
Thank you for sharing these details.
If your goal is to automatically create SEO’able pages, with all the possible combinations of locations and brands/models, you can add two custom taxonomies:
1. Locations.
This custom taxonomy will be flat or non-hierarchal.
Example terms:
- Birmingham
- London
- Manchester
2. Brands and Models
This custom taxonomy will be hierarchal because models need to be linked to their brands.
Example terms:
- Dell
-- Inspiron
-- Latitude
-- XPS
- HP
-- Envy
-- Pavilion
-- ProBook
- Lenovo
-- Carbon
-- Thinkpad
-- Yoga
There is no built-in feature available to automatically create pages/posts, so you'll need some custom code for that:
add_shortcode('custom_create_service_pages', 'custom_create_service_pages_func'); function custom_create_service_pages_func() { $target_post_type = 'service-page'; $location_taxonomy = 'location'; $brand_model_taxonomy = 'brand-and-model'; $location_terms = get_terms( $location_taxonomy, array('hide_empty' => false) ); $brand_model_terms = get_terms( $brand_model_taxonomy, array('hide_empty' => false) ); ob_start(); foreach ($location_terms as $location_term) { foreach ($brand_model_terms as $brand_model_term) { if ($brand_model_term->parent > 0) { $current_parent_term = get_term_by('id', $brand_model_term->parent, $brand_model_taxonomy); $check_title = $location_term->name.' '.$current_parent_term->name.' '.$brand_model_term->name; $found_post = post_exists( $check_title,'','',$target_post_type); if($found_post == 0) { $args = array( 'post_type' => $target_post_type, 'post_title' => $check_title, 'post_status' => 'publish', 'tax_input' => array( $location_taxonomy => array($location_term->term_id), $brand_model_taxonomy => array($current_parent_term->term_id, $brand_model_term->term_id), ), ); $post_id = wp_insert_post($args); if(!is_wp_error($post_id)){ echo 'Post '.$check_title.' with ID '.$post_id.' created!'; echo '<br>'; }else{ echo $post_id->get_error_message(); echo '<br>'; } } } } } return ob_get_clean(); }
The above code snippet can be included through either Toolset's custom code feature ( ref: https://toolset.com/documentation/adding-custom-code/using-toolset-to-add-custom-code/ ) or through the active theme's "functions.php" file.
Note: Please replace "service-page" with the slug of the actual post type, in which you'd like to insert these new posts/pages. For example, if you'd like to add them as regular pages, you'll use 'page'.
Likewise, replace 'location' and 'brand-and-model' with the actual slugs of your custom taxonomies.
To use this new custom code, you can create a new temporary page and insert the shortcode:
[custom_create_service_pages]
When you'll visit this page, the custom code will cycle through all the 'location' and 'brand-and-model' terms and create the pages/posts with all possible combinations, making sure to avoid any duplicates.
Once the posts/pages have been created, you can delete this temporary page.
Note: The custom code examples from our forum are shared to get you started in the right direction. You're welcome to adjust them as needed and for more personalized customization assistance, you can consider hiring a professional from our list of recommended contractors:
https://toolset.com/contractors/
Hi Waqar,
Thank you for your reply.
I think you may have overlooked one thing in the proposed solution. If I use taxonomy, I don’t think that I can bring in any page-specific pictures or content related to that page, purely from the taxonomy.
So as an example, a Brand has associated with it a logo. And a model has a picture of the computer or laptop on it. By bringing in this content into the created pages, it will make the page unique in terms of Location (vartype: text only), Brand (say Dell logo vartype:image), Model (Picture of Inspiron model, vartype:image) – and for SEO we need to create unique pages.
From your example, it looks like the code will create the pages but they will be blank pages and once created, Ill have to visit each page and amend the content in it.
What I really need is to create pages that will pull in field from the tables; (I think this is analogous to fields from a post type.)
To make my pages unique, I have the following fields which I will try to use in each created page.
Location
Vars Townname, County, Population
ComputerBrands
Vars LogoImage, DateEstablished, MarketShare
Computer Models
Vars Parent (the brand this belongs to), ModelImage
End Result – See the mockup page I have attached.
So question is – will the taxonomies setup you described in the last reply work for this or not? If not, what is the best path for me?
Thank you Sir.
> If I use taxonomy, I don’t think that I can bring in any page-specific pictures or content related to that page, purely from the taxonomy.
- Actually, you can store custom field data with each taxonomy term in these custom taxonomies, as needed.
If you'll go to WP Admin -> Toolset -> Custom Fields, you'll see the tabs, to add custom fields to either post, users or terms.
And, you can create a content template for your custom post type (e.g. "Service Page") in which these pages are being created and it will dynamically populate the content from the custom field data stored with the relevant taxonomy terms:
https://toolset.com/lesson-placement/lesson-placements-1621067-1621091/
Hi Waqar
If I go here WP Admin -> Toolset -> Custom Fields, I see the tabs, to add custom fields to either post, users or terms.
Which one should I set up ? And i see no way to connect the post fields to Taxonomy.
Also under Post Fields, I can see 3 Field Groups for ComputerBrands, ComputerModels and Location. These field groups contain all the variable information I actually need - and they were created when I was setting up the Custom Post Types.
So 2 questions for you today Waqar.
1) Are you still recommending the Taxonomy way to do this, and to use the code you sent me a couple of days ago to create the pages?
2) Under which tab shall I set up the custom fields that you are now suggesting (post, user or term fields) - and shall I delete the 3 "field group" mentioned above?
Thank you
Saeed
> 1) Are you still recommending the Taxonomy way to do this, and to use the code you sent me a couple of days ago to create the pages?
- Yes, based on the discussion that we've had so far over the requirements, I still believe that the custom taxonomy approach ( ref: https://toolset.com/forums/topic/making-a-relationship-with-3-variables/#post-2447001 ), will have its benefits over the post-relationships approach. The custom taxonomy approach would be simpler to set up/deploy, will have performance benefits, and will be easier to maintain, in a long run.
> 2) Under which tab shall I set up the custom fields that you are now suggesting (post, user or term fields) - and shall I delete the 3 "field group" mentioned above?
- I've checked the custom taxonomies, at WP Admin -> Toolset -> Taxonomies and noticed that the taxonomies that I recommended are not set up yet ( ref: https://toolset.com/forums/topic/making-a-relationship-with-3-variables/#post-2447001 ).
So, the first step would be setting those custom taxonomies.
After, that you can go to WP Admin -> Toolset -> Custom Fields and switch to "Term Fields" and add 3 custom field groups similar to how they are already added for the "Post Fields".
And yes, you can delete the 3 field groups that are added under the "Post Fields" tab, because they won't be needed in this custom taxonomy approach.
Note: The "Field group for Location" will be added for the custom taxonomy "Locations", and the "Field group for Brands" and the "Field group for Models" will be added for the custom taxonomy "Brands and Models".
( because in my proposed solution, you'll be using a single hierarchal taxonomy for both 'Brands' and "Models" )
Hi Waqar
I have defined the taxonomy and custom fields.
I couldn’t set up a taxonomy with slug “locations” as it is a reserved word – but I have set it up as SvcLocations.
1) I am not sure how to populate information in the custom fields for locations, brands-and-models taxonomies. I believe I should update the custom fields before running the code to create pages.
2) I cant see any way of inputting the [brand and model] data into a heirarchy.
3) Also once the data has been entered, and I create a temp page with the shortcode, [custom_create_service_pages], what will be the reference or templated page that will be used for the content, styling and layout?
4) Shall I delete the custom post types for locations, brands and models? (as these are likely to confuse me, if not needed.) I created these first before the taxonomy approach.
5) I am not a pro programmer, I have some limited coding experience but it looks like the 3 "foreach" loops will get all the custom terms in each taxonomy. If there are custom fields in [svclocation], is it going to get in a muddle when I create the pages?
6) If pages are created through the loop, and then recreated later because of amendment to the template, will the 1st set need to be deleted? Or will they update?
I have updated the code to reflect the names I am using – as follows, please check before I upload.:
add_shortcode('custom_create_service_pages', 'custom_create_service_pages_func');
function custom_create_service_pages_func() {
$target_post_type = 'service-page';
$location_taxonomy = 'svclocation';
$brand_model_taxonomy = 'brand-and-model';
$location_terms = get_terms( $location_taxonomy, array('hide_empty' => false) );
$brand_model_terms = get_terms( $brand_model_taxonomy, array('hide_empty' => false) );
ob_start();
foreach ($location_terms as $location_term) {
foreach ($brand_model_terms as $brand_model_term) {
if ($brand_model_term->parent > 0) {
$current_parent_term = get_term_by('id', $brand_model_term->parent, $brand_model_taxonomy);
$check_title = $location_term->name.' '.$current_parent_term->name.' '.$brand_model_term->name;
$found_post = post_exists( $check_title,'','',$target_post_type);
if($found_post == 0) {
$args = array(
'post_type' => $target_post_type,
'post_title' => $check_title,
'post_status' => 'publish',
'tax_input' => array(
$location_taxonomy => array($location_term->term_id),
$brand_model_taxonomy => array($current_parent_term->term_id, $brand_model_term->term_id),
),
);
$post_id = wp_insert_post($args);
if(!is_wp_error($post_id)){
echo 'Post '.$check_title.' with ID '.$post_id.' created!';
echo '<br>';
}else{
echo $post_id->get_error_message();
echo '<br>';
}
}
}
}
}
return ob_get_clean();
}
Based on your recent questions, I feel it would be better if I could create and share a basic demo website with you, with the proposed structure and some data items in place.
I'll work on this demo and will share it with you with the detailed steps and explanation, by tomorrow.
Thank you for your patience.
Sorry about the delay in getting back on this, as I had an unusually busy forum queue after the weekend.
The demo website will be ready today and I'll share its access details and the steps involved today too.
Thank you for waiting and here is the link to the demo website:
hidden link
Note: I'll share the admin access details, in the next private reply.
Here are some important points/steps:
1. I've added the custom post type "Service Pages" and the custom taxonomies "Locations" and "Brands and Models", exactly as I described in my earlier message:
https://toolset.com/forums/topic/making-a-relationship-with-3-variables/#post-2447001
2. I then added 3 term field groups "Location Fields", "Brand Fields", and "Model Fields" to add associate some demo fields for taxonomies.
3. Next, I added some example terms in the custom taxonomies "Locations" and "Brands and Models" and you can see them at WP Admin -> Service Pages -> Locations and WP Admin -> Service Pages -> Brands and Models
4. After that, I registered a custom shortcode to programmatically generate "Service Pages" posts with all possible combinations from all the terms available in the "Locations" and "Brands and Models" taxonomies. You can see that code at WP Admin -> Toolset -> Settings -> Custom Code, in the snippet named "custom-shortcode-for-auto-service-page-creation":
(it is slightly different from the code that I shared earlier)
add_shortcode('custom_create_service_pages', 'custom_create_service_pages_func'); function custom_create_service_pages_func() { $target_post_type = 'service-page'; $location_taxonomy = 'location'; $brand_model_taxonomy = 'brand-and-model'; $location_terms = get_terms( $location_taxonomy, array('hide_empty' => false) ); $brand_model_terms = get_terms( $brand_model_taxonomy, array('hide_empty' => false) ); ob_start(); foreach ($location_terms as $location_term) { foreach ($brand_model_terms as $brand_model_term) { if ($brand_model_term->parent > 0) { $current_parent_term = get_term_by('id', $brand_model_term->parent, $brand_model_taxonomy); $check_title = $location_term->name.' '.$current_parent_term->name.' '.$brand_model_term->name; $find_args = array("post_type" => $target_post_type, "name" => $check_title); $found_post = get_posts( $find_args ); if(empty($found_post)) { $args = array( 'post_type' => $target_post_type, 'post_title' => $check_title, 'post_status' => 'publish', 'tax_input' => array( $location_taxonomy => array($location_term->term_id), $brand_model_taxonomy => array($current_parent_term->term_id, $brand_model_term->term_id), ), ); $post_id = wp_insert_post($args); if(!is_wp_error($post_id)){ echo 'Post '.$check_title.' with ID '.$post_id.' created!'; echo '<br>'; }else{ echo $post_id->get_error_message(); echo '<br>'; } } } } } return ob_get_clean(); }
5. To use this custom shortcode, I created a new page "Page to auto create the service pages" and in its content added this shortcode:
[custom_create_service_pages]
When I visited the front end of this page, this shortcode created 27 posts in the "Service Pages" post type. When there are some new posts to be created using the terms in those custom taxonomies, you'll see the list of the created posts. But if posts of all possible combinations have already been created, it won't show anything.
When you've added more terms in those custom taxonomies, you can visit that page's front end again and it will add "Service Pages" posts for their possible combination too.
6. To show the content of the individual "Service Pages" posts, I create a new content template "CT for Service Pages" from WP Admin -> Toolset -> Content Templates and assigned it to be used for the Service Pages" posts.
7. I felt another custom shortcode was needed to get the current "Service Pages" post's attached location, brand, or model. For that, I registered another custom shortcode at WP Admin -> Toolset -> Settings -> Custom Code, in the snippet named "custom-shortcode-to-get-current-tax-term-id":
add_shortcode('get_terms_by_level', 'get_terms_by_level_func'); function get_terms_by_level_func($atts) { $level = $atts['level']; $return = $atts['return']; $postid = do_shortcode('[wpv-post-id]'); $location_taxonomy = 'location'; $brand_model_taxonomy = 'brand-and-model'; $results = array(); if($level == 'location') { $target_tax = $location_taxonomy; } elseif ( ($level == 'brand') || ($level == 'model') ) { $target_tax = $brand_model_taxonomy; } $terms = get_the_terms( $postid, $target_tax); if ( $terms && ! is_wp_error( $terms ) ) { foreach ($terms as $term) { if( ($level == 'model') && ($term->parent != 0) ) { $results[] = $term; } elseif ( ($level != 'model') && ($term->parent == 0) ) { $results[] = $term; } } if(!empty($results)) { ob_start(); foreach ($results as $result) { if($return == 'id') { echo $result->term_id; } elseif($return == 'name') { echo $result->name; } elseif($return == 'link') { echo '<a href="' . esc_url( get_term_link( $result->term_id, $target_tax) ) . '">' . $result->name . '</a>'; } } return ob_get_clean(); } } }
I also added "get_terms_by_level" shortcode name in the "Third-party shortcode arguments" section, at WP Admin -> Toolset -> Settings -> Front-end Content.
This single custom shortcode can be used to get either 'id', 'name', or 'term archive link' for the connected 'location', 'brand', or 'model'.
It accepts two attributes:
a). level: which can be 'location', 'brand', or 'model'
b). return: which can be 'id', 'name', or 'link'
Examples of usage:
// Get location term data: Location ID: [get_terms_by_level level='location' return='id'] Location Name: [get_terms_by_level level='location' return='name'] Location Archive Link: [get_terms_by_level level='location' return='link'] // Get brand term data: Brand ID: [get_terms_by_level level='brand' return='id'] Brand Name: [get_terms_by_level level='brand' return='name'] Brand Archive Link: [get_terms_by_level level='brand' return='link'] // Get model term data: Model ID: [get_terms_by_level level='model' return='id'] Model Name: [get_terms_by_level level='model' return='name'] Model Archive Link: [get_terms_by_level level='model' return='link']
You can see these shortcodes in use in the content template "CT for Service Pages" too. I've added them in different colored containers so that data from each type of term/object is easy to spot.
8. Once the ID of the connected taxonomy term is known, it can be used in the content template to get the term field data, using the Types Fields API:
https://toolset.com/documentation/customizing-sites-using-php/functions/
Examples of using term field data can also be seen in use in the content template "CT for Service Pages":
Location Field 1: [types termmeta="location-field-1" term_id="[get_terms_by_level level='location' return='id']"][/types] Location Field 2: [types termmeta="location-field-2" term_id="[get_terms_by_level level='location' return='id']"][/types] Brand Field 1: [types termmeta="brand-field-1" term_id="[get_terms_by_level level='brand' return='id']"][/types] Brand Field 2: [types termmeta="brand-field-2" term_id="[get_terms_by_level level='brand' return='id']"][/types] Model Field 1: [types termmeta="model-field-1" term_id="[get_terms_by_level level='model' return='id']"][/types] Model Field 2: [types termmeta="model-field-2" term_id="[get_terms_by_level level='model' return='id']"][/types]
So, in summary, you can see how each of those 27 'service page' posts shows dynamic content on the front end, from the attached taxonomy terms, without having any actual content in the posts themself. You'll change the data in the taxonomy term fields and it will automatically reflect/update on the relevant 'service page' posts too and you won't have to edit each of them.
I hope this demo website and explanation will make it more clear.
Hi Waqar
Thank you for the detailed response. I am in meetings this morning but will get a chance to go through the info later.
Thank you.
saeed
Glad I could help and please take your time.