Forum

Thread tagged as: Question

Pass a variable between layouts?

Hi,

Is there a way to set a variable in a perch_layout and use it in another perch_layout?

My setup

My page template has two layouts:

perch_layout('global/head')

and

perch_layout('global/footer')

In perch_layout('global/head') I've set a variable called $lang

I can echo the variable in perch_layout('global/head'); and it works.

I can't echo it in perch_layout('global/footer')


Looking at the docs, it looks like I need to pass a variable into perch_layout

I was hoping this would work,

perch_layout('global/footer', [
    'lang'=> $lang,
]); 

Inside the footer I'm using this:

perch_layout_var('lang');

It works if I hardcode the value, like this:

perch_layout('global/footer', [
    'lang'=> 'en',
]); 

Or, if I move the code used to set the variable out of perch_layout('global/head') and place it at the top of my page template.

This isn't ideal, as I'd like to use the variable in other templates. Is there a way to do this?


Summary

Perch Runway: 3.1.1, PHP: 7.1.12, MySQL: mysqlnd 5.0.12-dev - 20150407 - $Id: b396954eeb2d1d9ed7902b8bae237b287f21ad9e $, with PDO
Server OS: Darwin, cgi-fcgi
Installed apps: content (3.1.1), assets (3.1.1), categories (3.1.1)
App runtimes: <?php $apps_list = [ ];
PERCH_LOGINPATH: /perch
PERCH_PATH: /Users/stephen/Repositories/project/cms/perch
PERCH_CORE: /Users/stephen/Repositories/project/cms/perch/core
PERCH_RESFILEPATH: /Users/stephen/Repositories/project/cms/perch/resources
Image manipulation: GD
PHP limits: Max upload 32M, Max POST 32M, Memory: 128M, Total max file upload: 32M
F1: 3b606135b33e6a102526838f4152a807
Resource folder writeable: Yes
SCRIPT_NAME: /perch/core/settings/diagnostics/index.php
REQUEST_URI: /perch/core/settings/diagnostics/
DOCUMENT_ROOT: /Users/stephen/Repositories/project/cms
HTTP_HOST: project.local
Stephen Meehan

Stephen Meehan 4 points

  • 3 years ago

Yes. This is totally doable. You pass the variables on the perch_layout() method.

I am thinking the array is ‘path’, ‘variables’

When including the Layout on the page with the perch_layout() function, pass in a second argument after the name of the Layout. This argument is a PHP array, the key is the name of the variable and the value is what will be output when using this variable.

perch_layout('global.header', array( 'title'=>'Welcome to my site!', 'class'=>'home', ));

Drew McLellan

Drew McLellan 2638 points
Perch Support

In perch_layout('global/head') I've set a variable called $lang

Have you tried just using $lang in the footer? I think it should still be in scope.

Hi Robert/Drew

Thanks for the replies.

Robert: I can get perch_layout working if I hardcode the value, the problem I'm hitting is when I try to use a variable from a different perch_layout as the value.

This works

perch_layout('global/footer', [
'lang'=> 'en',
]); 

This doesn't

perch_layout('global/footer', [
'lang'=> $lang,
]); 

$lang is in perch_layout('global/head')


Drew: The example I gave was a simplified version. Ideally I'd like to set my variables in one place perch_layout('global/head') and have the ability to use the variables in other perch_layouts

Is it possible to set a variable in one perch_layout and pass it to another?

I've tried using $lang in the footer with the variable set in perch_layout('global/head'), it doesn't work. Debug reports Undefined variable: lang

Drew McLellan

Drew McLellan 2638 points
Perch Support

You'd need to define them in one place and then pass them into each layout as you use it.

Hi,

Thanks for replying, really appreciate it.

You'd need to define them in one place and then pass them into each layout as you use it.

That's exactly what I'm trying to do. Defining the variable in a perch_layout.

I've most likely got the wrong end of the stick :)


Another example, apologies I'm just trying to understand this.

perch_layout('global/head') contains $test_var = 'THIS IS A TEST';.

This is my test page-template.php

perch_layout('global/head')
perch_layout('content')
perch_layout('global/footer', [
    'test'=> $test_var,
]);

perch_layout('global/footer') contains perch_layout_var('test');.

Debug reports Undefined variable: test_var

If I move $test_var out of perch_layout('global/head') and place it in page-template.php like this:

perch_layout('global/head')
$test_var = 'THIS IS A TEST';
perch_layout('content')
perch_layout('global/footer', [
    'test'=> $test_var,
]);

It works.

But that means I have to add $test_var to every page template? Is that right?

I'll end up with multiple copies of the same variable in my page templates. I must be missing something.

I thought the benefit of using a variable is it can be set once, and accessed anywhere.

Drew McLellan

Drew McLellan 2638 points
Perch Support

But that means I have to add $test_var to every page template? Is that right?

No, that's not right. Use an include.

Hi,

Thanks, I didn't think to use an include, as I thought perch_layout was the 'Perch' equivalent.

I've added a file called vars.php to cms/perch/templates/pages/vars.php

Adding the include to any page template in the same pages folder works great!

include('vars.php');

However, I've have a few sub-folders in my pages folder. The include doesn't work with those page templates.

I thought I could just move back up a folder, like this include('../vars.php'); but it doesn't work.

What would be the correct path to make the include work with page templates in a pages sub-folder?

Fixed it.

I needed to add $_SERVER['DOCUMENT_ROOT'] to the include and the full path to vars.php

I add this to the top of any page template:

include($_SERVER['DOCUMENT_ROOT'].'/perch/templates/pages/vars.php');

vars.php contains this test variable:

$test_var = 'THIS IS A TEST';

I can then pass $test_var to a perch_layout like this:

perch_layout('global/footer', [
    'test'=> $test_var,
]); 

Finally, inside perch_layout('global/footer' I can use the variable like this:

perch_layout_var('test');

I'm curious why perch_layout doesn't allow variables to be used like this?

Drew McLellan

Drew McLellan 2638 points
Perch Support

Layouts have their own variable scope. You can pass variables into the layout's scope, but there's no mechanism to return values to the calling scope. Think of them like functions without the return keyword.

Ah, ok. Thanks for the support.