Methods & Models Confusion

Im working on a site I didn’t build, and it has a whole bunch of page methods. I need to get the value of a variable set inside one method, and use its value in one of the other methods, and possibly the model too.

I’ve read the docs on these but i’m still confused

How do i do that?

I don’t understand anything. Can you post an example of what you are trying to achieve including the methods you are talking about, please.

In general:

A page model is a method that can be used only within a confined set of pages, i.e. the pages that belong to the model (i.e. use a particular template).

A custom page method usually lives in a plugin file and can be used anywhere.

Variables have a scope, if a variable only lives within a method, you can’t usually use it outside of it.

Well, unfortunately the project is private so i cant really share much but its basically a page method that rips through a structure field and turns each entry into a distinct area the page (banner, body text, image panel etc)

It also works out if the page has a banner background video or an image set, and after jumping through some hoops, if its an image, it sets the URL of the image url into a variable called $hero_bg.

Theres another method declared immediately under it to build the actual banner using bricks. I need to alter the structure, and for that i need the value of $hero_bg to use in the second method.

the first custom page method (in a plugin file) looks a bit like this (it’s huge)…

page::$methods['sectionBuild'] = function($page, $field='sections') {

	$content = '';

	foreach($page->{$field}()->toStructure() as $section):

		$classes = r($section->classes()->isNotEmpty(), str_replace(',',' ',$section->classes()->value()), false);
		$id = r($section->section_id()->isNotEmpty(), $section->section_id()->value(), false);
		$hero_bg = false;
		$video_hero = false;
		$modal = false;

		switch($section->type()->value()):
			case 'hero':
				$hero_results = $page->heroSectionBg();

				$text = $page->heroSection($section);
				// If image
				if($hero_results[1] == false):
					$hero_bg = $hero_results[0];
				// If video
				elseif($hero_results[1] == true):
					$video_hero = $hero_results[0];
					$text .= $hero_results[2];
					$hero_bg = $hero_results[3];
					$classes .= ' hero-video';
				endif;

				$classes = 'banner-innerpage-block blog-banner banner-pad'.r($classes, ' '.$classes);
				break;
			case 'top':
			default:
				$text = $page->textSection($section);
		endswitch;

                 $content.= r($modal, brick('div', $modal, ['id'=>$id]), brick('section', $video_hero.$text, ['class'=>$classes,'id'=>$id, 'style'=>$hero_bg]));

	endforeach;

	return $content;

};

Previously, the image was set as a background image via an inline style on the first method. For seo reasons, i need to make that an image tag inside the banner area instead, and for that i need the value $hero_bg available in the second method which looks like this:

page::$methods['heroSection'] = function($page, $section) {

$bannerimg = $hero_bg; // currently throws a woops
	
if(isset($page->heroParent) && $page->heroParent):
		$page = $page->parent();
		$section = $page;
	endif;

	if(!isset($page->headerField))
		$page->headerField = 'header';

	if(!isset($header))
		$page->header = $section->{$page->headerField}()->value();

	$text = brick('h1', $page->header);
	$text.= $page->breadcrumbs();
	$text = brick('div', $text, ['class'=>'inner-page-content']);

	$text = brick('div', brick('div', $text, ['class'=>'row']), ['class'=>'container-block']);

	$text.= brick('div', brick('img', false, ['src'=>url('assets/images/small-img/banner-logo.png')]), ['class'=>'banner-logo']);

	return $text;
};

How can get the value $hero_bg set in the first method in the second method as the value of $bannerimg variable?

The only way i can think is to just duplicate that case logic in the second method, but that seems a little sloppy. Must be a better way.

As far as I can see, you call the second method from within the first. That means, once you set the value for your $hero_bg, you might as well pass it as a parameter to the second method.

// first method
$hero_results = $page->heroSectionBg();

				
				// If image
				if($hero_results[1] == false):
					$hero_bg = $hero_results[0];
				// If video
				elseif($hero_results[1] == true):
					$video_hero = $hero_results[0];
					$text .= $hero_results[2];
					$hero_bg = $hero_results[3];
					$classes .= ' hero-video';
				endif;
$text = $page->heroSection($sectionbg, $hero_);
//rest of first method

// here we add the variable as a parameter to the second method
page::$methods['heroSection'] = function($page, $section, $hero_bg) {
/// code; the variable can then be used without the need to assign it to another variable, btw.
};

I don’t really understand why you are using methods for this, to be honest. The whole thing might as well be achieved with snippets and would be much more readable than this brick mess that mixes logic with presentation.

Also, you were talking about models, but I can’t see any models here?

Sure, i would totally have used snippets if i had built it. I inherited this site from someone else. Your right, its a mess, but for now i have to work with it. I would love to rebuild it my way.

I mentioned models, because for some pages the methods have been extended into models. It’s a real rats nest.

But thanks, you helped me to get the value to where i need it. :slight_smile:

Well, have fun then ;).