Skip Navigation

[Resolved] Assign Layouts conditionally

This thread is resolved. Here is a description of the problem and solution.

Problem:
How else can I assign or call a Layout conditionally?
I can assign a layout to a post in the backend.
But what if I want to do that dynamically, and call for each post eventually a different layout, at different times?

Solution:
There are basically 2 options:
- update the metafield

_layouts_template

of the Post with Custom PHP to store the Layout Slug you want to be assigned to the Post.
- call a Layout with an URL parameter added to the Post permalink:

?layout_id=X

where X is the Layouts ID.

This support ticket is created 7 years, 2 months ago. There's a good chance that you are reading advice that it now obsolete.

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.

No supporters are available to work today on Toolset forum. Feel free to create tickets and we will handle it as soon as we are online. Thank you for your understanding.

Sun Mon Tue Wed Thu Fri Sat
- - 14:00 – 20:00 14:00 – 20:00 14:00 – 20:00 14:00 – 20:00 14:00 – 20:00
- - - - - - -

Supporter timezone: Asia/Ho_Chi_Minh (GMT+07:00)

This topic contains 8 replies, has 2 voices.

Last updated by tinaH 7 years, 2 months ago.

Assisted by: Beda.

Author
Posts
#563741

Is there a way to select which layout to use with url parameter?
Instead of using the default post-type layout can I instead pass a slug for a Layout with url parameter?
Or if not, can I do it with content-templates?

Or can I define a layout based on conditional value of a field?
if field-x eq "something" then use layout "someslug"

example fantasy url (post-type bookings)
hidden link

#563804

In a URL parameter, it's more tricky than if you do that on a Post Creation moment, where you can just hook into the postmeta field with key "_layouts_template" (it's a hidden field) and store the slug of the Layout in there.

In an URL parameter, you are to late to update the postmeta and also, it makes no sense, as perhaps you will look at the same post from 2 computers at the same time, hence, this is not the way to go.

For sure this needs some custom code, but it should not be too difficult either.

1. You will need to integrate Layouts manually into your Theme
(Please ask me for assistance on this, if you do not know how to do that)
2. In the Template Files, you call the proper Layout by checking on your URL parameter.

Let's say you have 3 Layouts, "layout-one", "layout-two" and "layout-tree".
When the URL parameter "?layout_slug=" is one of them, then you want to load only exactly that Layout.

So your Layout integration must be in a conditional statement like the example below:

if ( $_GET['layout_slug'] == "layout-for-pages") {
  the_ddlayout('layout-for-pages');
}
else {
  the_ddlayout('layout-for-blog');
}

Above will call for all Posts displayed with this Template the layout-for-blog, unless the URL parameter is set to ?layout_slug=layout-for-pages.

#564656

I'm having problems with $_GET[].
Looks like I have to register the variable to the WordPress' array of 'recognised query variables'?
Any input, knowledge or opinion on that?

Other question:
Where are available layout functions documented?
Cannot find any info on the_ddlayout() function in the programmers reference.
Are there more functions/actions/filters available?

#564836

I am always checking the wrong option ... reopening 🙂

#564934

I just found that layout already has an url variable. (Why didn't you say so 🙂
Just add ?layout_id=X to a URL
(X = layout id)

I found it from the new cred edit post link ...

#565004

You are absolutely right.

I did not see the tree in the forest, here.
I thought, initially, you want to call a layout conditionally to a URL parameter, not directly IN the parameter.

hidden link (or any other ID of an existing Layout) will call that Layout.

#565627

Yes but building the url conditionally is another story 🙂
And that was the easy part ...

#565768

The correct way to assign a Layout (and that is also the correct way to call it) generally is to update the post meta field I elaborated.

Now, to call it dynamically via the URL you constructed, will of course not keep the layout assigned but just call it. It is not a docuemented approach, hence I cannot speak out of great experience with this method either. I know it works with CRED Forms, for wich this feature was developed.
It should not present issues with your approach either.

To construct the Layout assignement conditionally, you can either link to the Page in question from another location on your website, by using several HTML conditionals where you, depending on what conditions, show URL's to the target page with different Layouts in the URL parameter, or, you can do that only with PHP.

Where from you get the condition does not really matter. You could even check upon a Meta Field Content, correct?

The other method I elaborated will also just call a Layout, not assign it directly to the Post.
But also here, you will depend on your data for the condition.

May I ask based on what you will display which Layouts, to whom?
Maybe I can help to construct an easier solution.

#566573

Based on your feedback I ended up doing like this.
(The part with $the_parent is not related to this question.)

I never got the_ddlayout() to work.
I left it as a comment for you to see where I tried to add it.

function booking_status_redirect() {
    if (get_post_type(get_the_ID()) == 'bookings') {
        $post_id = get_the_ID();
        $booking_status = get_post_meta($post_id, 'wpcf-booking-status', true);
        if ($booking_status === "invoice") 
        {
            update_post_meta($post_id, '_layouts_template', 'booking-invoice');
            //the_ddlayout('booking-invoice');
        }
        $the_parent = get_post_meta($post_id, 'wpcf-booking-parent', true);
        if (!empty($the_parent)) 
        {
            $url = get_permalink($the_parent);
            wp_redirect($url);
            exit();
        }
    }
}
add_action( 'template_redirect', 'booking_status_redirect' );