Jump to content

Markup regions - how to include files in _main.php

Guy Incognito

Recommended Posts

I'm experimenting with markup regions for the first time instead of static output. Everything's going great other than I can't work out how to include other PHP files in my _main.php file that use PW functionality. Primarily I have a script that runs some checks against user permissions and runs a few PW selector queries to set up a few useful variables for a basic web app.

If I include this file into my _main.php the variables don't populate as it doesn't have access to things like the PW $pages object - presumably something to do with the load order?

What's the correct way to go about this, a new module seems overkill. Is it just a case of including the file at the top of every template, or is there a smarter way?

Link to comment
Share on other sites

I don't know if I understood correctly, but it looks like you can also use $files->include() or $files->render() methods in your _main.php file.
A simple example from the Regular Uikit 3 profile, which we will include the _header.php inside file _main.php with some variables:

<?php namespace ProcessWire;
// _main.php template file, called after a page’s template file

$home = pages()->get('/'); // homepage
$siteTitle = 'Regular';
$siteTagline = $home->summary;

// as a convenience, set location of our 3rd party resources (Uikit and jQuery)...
urls()->set('uikit', 'wire/modules/AdminTheme/AdminThemeUikit/uikit/dist/');
urls()->set('jquery', 'wire/modules/Jquery/JqueryCore/JqueryCore.js');
// ...or if you prefer to use CDN hosted resources, use these instead:
// urls()->set('uikit', 'https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-beta.40/');
// urls()->set('jquery', 'https://code.jquery.com/jquery-2.2.4.min.js');

<!-- HEADER -->
	$files->include('_header', ['home' => $home, 'siteTitle' => $siteTitle, 'siteTagline' => $siteTagline]);
	// echo $files->render('_header', ['home' => $home, 'siteTitle' => $siteTitle, 'siteTagline' => $siteTagline]);


<?php namespace ProcessWire;
// _header.php file
<!DOCTYPE html>
<html lang='en'>
<head id='html-head'>
	<meta http-equiv="content-type" content="text/html; charset=utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<title id='html-title'><?=page()->title?></title>
	<meta name="description" content="<?=page()->summary?>">

	<link rel="stylesheet" href="<?=urls()->uikit?>css/uikit.min.css" />
	<link rel="stylesheet" href="<?=urls()->templates?>styles/main.css">

	<script src="<?=urls()->jquery?>"></script>
	<script src="<?=urls()->uikit?>js/uikit.min.js"></script>
	<script src="<?=urls()->uikit?>js/uikit-icons.min.js"></script>
<body id='html-body'>

	<!-- MASTHEAD -->
	<header class='uk-background-muted'>
		<div id='masthead' class="uk-container">
			<h2 id='masthead-logo' class='uk-text-center uk-margin-medium-top uk-margin-small-bottom'>
				<a href='<?=urls()->root?>'>
					<img src='<?=urls()->templates?>styles/images/coffee4.svg' alt='coffee'><br />
			<p id='masthead-tagline' class='uk-text-center uk-text-small uk-text-muted uk-margin-remove'>
			<nav id='masthead-navbar' class="uk-navbar-container" uk-navbar>
				<div class="uk-navbar-center uk-visible@m">
					<?=ukNavbarNav($home->and($home->children), [
						'dropdown' => [ 'basic-page', 'categories' ]

It is also important to include <?php namespace ProcessWire; ?> in each of template files.
Sometimes it also helps to enable $config->useFunctionsAPI in the config.php file ( Allow most API variables to be accessed as functions? ), this will be more useful in your custom functions, where for example you can call page()->title instead of $page->title, which will not work inside a your custom function if you do not enter any arguments, as in the example below:

	function showTitle() {
		echo '<h1>' . page()->title . '</h1>'; // This work
		// echo $page->title; // This not work
  // Show Title

The setting() helper function is a good addition to the _init.php file, to which I usually attach the most important page options, which are also available in custom functions without entering arguments such as the init.php file:

<?php namespace ProcessWire;

 * This _init.php file is called automatically by ProcessWire before every page render
 * Get or set a runtime site setting
 * @link https://processwire.com/api/ref/functions/setting/

/** @var ProcessWire $wire */

// set or replace multiple settings
	'siteTitle' => 'ProcessWire CMS / CMF',
	'siteDescription' => 'ProcessWire is like a power tool for your website, able to deliver any output, at any scale, to any number of people. ',

// Your custom functions that are better placed in the _func.php or _uikit.php file (this is just an example)
function siteBranding() {
	echo "<h1>" . setting('siteTitle') . "</h1>";
	echo "<h2>" . setting('siteDescription') . "</h2>";


Now you can display the function wherever you want:

<?php siteBranding() ?>

For example, in this Site Profile I have put site options or translations inside file _init.php:

<?php namespace ProcessWire;

 * This _init.php file is called automatically by ProcessWire before every page render
 * Get or set a runtime site setting
 * @link https://processwire.com/api/ref/functions/setting/

// as a convenience, set location of our 3rd party resources (jQuery)...
urls()->set('jquery', 'https://code.jquery.com/jquery-3.4.1.min.js');

$home = pages('/');
$blog = pages()->get("template=blog");
$options = pages()->get('/options/');

// Basic Settings
// Custom html classes
	'htmlClasses' => WireArray([
		'template-' . page()->template->name,
		'page-' . page()->id,
// Basic
	'home' => $home,
	'privacyPolicy' => pages()->get("template=privacy"),
	'options' => $options,
	'siteName' => $options->text,
	'logo' => $options->logo,
	'favicon' => $options->favicon,
	'socialProfiles' =>$options->social_profiles,
	'metaTitle' => page('meta_title|title'),
	'metaDescription' => page()->meta_description,
	'noindex' => false,
	'poweredUrl' => 'https://processwire.com',
// Home Sections
	'hero' => $home,
	'about' => pages()->get("template=about"),
	'projects'=> pages()->get("template=projects"),
	'recent' => $blog->child(),
// Path to template parts
	'homeParts' => 'parts/home',
	'blogParts' => 'parts/blog',
// Blog
	'blog' => $blog,
	'disableComments' => $options->more_options->get("name=disable-comments"),
// Contact Page
	'saveMessages' => $options->more_options->get("name=save-messages"),
// Images
	'img' => page()->images && page()->images->count() ? page()->images : '',
// Main
	'mainTitle' => page('title'),
	'mainImage' => true, // Set basic background image for all pages
// Bottom Panel
	'bottomPanel' => $options->bottom_panel,
// Basic Translations
	'lang' => __('en'),
	'edit' => __('Edit'),
	'next' => __('Next'),
	'previous' => __('Previous'),
	'search' => __('Search'),
	'search-site' => __('Search the entire site'),
	'found-matches' => __('Found %d page(s)'),
	'no-results' => __('Sorry, no results were found.'),
	'maintenance-mode' => __('Maintenance Mode'),
	'site-disabled' => __('Our site is currently disabled.'),
	'to-top' => __('To top'),
	'we-sociable' => __('We are sociable'),
	'powered' => __('Probably supported by ProcessWire CMS'),
// Contact Page Translate
	'message-error' => __('Some errors, please update your form'),
	'message-success' => __('Success, your message has been sent'),
	'txt-from' => __('From'),
	'form-legend' => __('Contact Us'),
	'form-name' => __('Name'),
	'form-email' => __('Email'),
	'form-privacy' => __('I agree with the %s terms.'),
	'form-message' => __('Message'),
	'form-spam' => __('To help prevent automated spam, please answer this question'),
	'fs-placeholder' => __('* Using only numbers, what is 10 plus 15?'),
	'fs-error' => __('Fill out the spam prevention box correctly'),
	'form-submit' => __('Submit'),
// Blog Translate
	'in-blog' => __('In the blog'),
	'posted-in' => __('Posted in'),
	'all-posts' => __('All posts'),
	'recent-posts' => __('Recent posts'),
	'read-more' => __('
	'written-on' => __('Written on'),
	'byline-text' => __('Posted by %1$s on %2$s'),
	'also-like' => __('You might also like:'),
	'author' => __('Author'),
	'authors' => __('Authors'), // is also url segments ( blog/authors/author-mame )
	'category' => __('Category'),
	'tag' => __('Tag'),
	'author-checkbox' => __('You probably need to check the author checkbox in your user profile'),
	'rss' => __('RSS'),
	'recent-entries' => __('Recent entries'),
// Comments Form Translate
	'previous-comments' => __('Previous Comments'),
	'next-comments' => __('Next Comments'),
	'post-comment' => __('Post a comment'),
	'comment' => __('Comment'),
	'comments' => __('Comments'),
	'no-comments' => __('No Comments'),
	'comments-closed' => __('Comments are closed'),
	'comment-header' => __('Posted by {cite} on {created}'),
	'success-message' => __('Thank you, your comment has been posted.'),
	'pending-message' => __('Your comment has been submitted and will appear once approved by the moderator.'),
	'error-message' => __('Your comment was not saved due to one or more errors.') . ' ' .
	__('Please check that you have completed all fields before submitting again.'),
	'comment-cite' => __('Your Name'),
	'comment-email' => __('Your E-Mail'),
	'comment-website' => __('Website'),
	'comment-stars' => __('Your Rating'),
	'submit' => __('Submit'),
	'stars-required' => __('Please select a star rating'),
	'reply' => __('Reply')



  • Like 2
Link to comment
Share on other sites

Thank you. I did try most of the different ways of including files. The problem wasn’t with the include itself which was working fine.

The include itself was running some PW selectors and dynamically populating some variables critical to the rest of the page content. Seems that with a standard include things weren’t loading in the order I needed for this to work, but using an appended init file works fine 😊

  • Like 1
Link to comment
Share on other sites

  • 3 months later...

I have some trouble using setting() function - the setting() returns nothing in an included file.

I set the setting() inside a function - could this be the culprit?

_inti.php file, that is auto-included:

function calendar($source){
	setting('calendar', $source->id);


_head.php file, that returns nothing for this setting:


Is there an option to make it "global" from inside the function?


API functions are turned on, and those that are set "statically" (not within function) and works fine.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...