Assigning Data
You assign data to specific template elements using the PHPFront::assign()
function.
This may be by far your most-used function.
This function adds an item to the internal data store - PHPFront::$data_stack
- the total collection of data it uses for rendering.
Every piece of data in the store is associated with an element.
PHPFront::assign()
used to be PHPFront::assignData()
in earlier, beta, versions of PHPFront.
Function
PHPFront::assign($element_selector, $data[, $replace = true, $recurse = true, $is_include_path = false]);
This function accepts two required parameters:
$element_selector
- always a string of either CSS selector or XPath query.
$data
- a string or an array. This parameter is interpreted as either of two things:
- A simple argument – a string of content or an array of contents.
- A compound argument – an array of other arguments.
Then there are three optional parameters:
$replace
- (boolean) Tells whether to replace data already assigned for the given $element_selector
or add to it. (Default: true - replace )
$recurse
- (boolean) Tells whether to replace data recursely or merge recursely. (Default: true - recurse )
$is_include_path
- (boolean) Tells whether to send $data
to PHPFront::$include_stack
or PHPFront::$data_stack
. (Default: false)
Usage
$PHPFront->assign($element_selector, $data);
All the examples on this page are built the Hello World setup example. Hope you're familiar with it.
$data As Simple Argument
Assigning Strings
A string is always content for the selected elements.
In the code below, our first argument to the assign()
function is a string of CSS selector and the second is a string of content for the targeted element.
<div id="content-box"></div>
Assignment
$PHPFront->assign('#content-box', 'This is simple content');
Result
<div id="content-box">This is simple content</div>
Preview your app.php in a browser to view this content.
If the element had initial text content or childnodes, they would all be replaced.
Use the CSS Pseudo classes: ::before, ::after to append or prepend to elements' exsting content.
If the selector applied to more than one element, they would all be affected.
Use the CSS Pseudo classes: first-of-type, last-of-type, nth-of-type(n) to target one out of many.
Assigning Arrays - Auto Population
An array targets the children of an element.
In the example below, our element has 3 childnodes, and our $data
is an array of 3 items.
The pieces of $data
will be distributed to, or populated on, the immediate childnodes of this element, and will not replace them.
<div id="content-box">
<span></span>
<span></span>
<small></small>
</div>
The $data
$data = array('this is a span element', 'this is a second span element', 'this is a small text');
Assignment
$PHPFront->assign('#content-box', $data);
Result
<div id="content-box">
<span>this is a span element</span>
<span>this is a second span element</span>
<small>this is a small text</small>
</div>
With just one line of code assign()
, we populated 3 elements!
Note that if the childnodes of #content-box
were in a different order, with the <small>
element as first child, result would be different.
Here we go:
<div id="content-box">
<small>this is a span element</small>
<span>this is a second span element</span>
<span>this is a small text</span>
</div>
This is called auto population, and is usually blind as the elements recieve their data based on their position and not based on their type, id, or class.
Where the number of items exceeds the number of child elements, PHPFront will repeat a child (or all the children) one or more times to fully render data.
This happens only on auto population.
Get started with repeats here.
Assigning Arrays - Associative Population
Remember, an array targets the children of an element.
It is possible to associate pieces of content in an array to named childnodes of an element.
To do this every piece of content in our array will be given a key – a childnode selector.
<div id="content-box">
<span id="childnode-1"></span>
<span id="childnode-2"></span>
<small id="childnode-3"></small>
</div>
The $data
$data = array('#childnode-3' => 'this is a span element', '#childnode-1' => 'this is a second span element', '#childnode-2' => 'this is a small text');
Assignment
$PHPFront->assign('#content-box', $data);
Result
<div id="content-box">
<span id="childnode-1">this is a span element</span>
<span id="childnode-2">this is a second span element</span>
<small id="childnode-3">this is a small text</small>
</div>
Note that, unlike blind population, items in our array did not need to be in the order of the childnodes.
The '::before' and '::after' pseudo classes also work for Associative Population
Content arrays can be nested to form multidimensional arrays. That's how you target descendants in any depth
$data As Compound Argument
As a simple argument, $data
supplies content for an element or its children.
But as a compound argument, it supplies a list of arguments or other rendering rules for manipulating an element - always in parameter_name => parameter_value
pairs.
Parameter names in $data
are always prefixed with the @ symbol; and PHPFront captures each argument and executes accordingly.
Basic Usage
In the example below, both content and attribute are being assigned to our usual #content-box
using the $data
compound argument.
<div id="content-box"></div>
The $data
$data = array(
'@content' => 'This is simple content',
'@attr' => array('class' => 'large-text')
);
Assignment
$PHPFront->assign('#content-box', $data);
Result
<div id="content-box" class="large-text">This is simple content</div>
In just one assignment, we set an element's content and classname.
We could have done the same thing in two assignments.
Like this:
$data_1 = 'This is simple content';
// Or, when in compound argument
$data_1 = array( '@content' => 'This is simple content');
$data_2 = array( '@attr' => array('class' => 'large-text'));
$PHPFront->assign('#content-box', $data_1);
$PHPFront->assign('#content-box', $data_2);
Parameters of the $data Compound Argument
The $data
compound argument has 7 parameters for element manipulation.
Parameters are executed in the order given below.
Now, you could achieve wonderful things on an element in just one assignment that combines these parameters.
$PHPFront->assign($element_selector, array(
// Take processing parameters
'@params' => array,
// Get external element
'@import' => string,
// Set element content
'@content' => string|array,
// Set element attribute
'@attr' => array,
// Distribute on children
'@children' => array,
// Change existence of this element
'@render' => string|bool,
// Repeat this element
'@repeat' => array,
));
PHPFront will complain when an unrecognized item is listed as parameter of compound argument. (Throws Exception!)
@params
Affects the runtime behavior of PHPFront on specific elements with quite a few settings supplied in key => value
pairs.
PHPFront strips each instruction and applies it on the current element.
The settings work per element, and sometimes, including its children.
See the chapter Setting Runtime Parameters for the current working properties of the @params
parameter.
@import
Imports some extra external elements or markup into a particular element.
There are 3 possible locations to import from: the current loaded document, a document elsewhere on the same server, a document on another server.
// Import the #menu element in this document into #parent-element - append
$PHPFront->assign('#parent-element', array(
'@import::after' => '#menu'
));
// Import the #menu element from another file in this server. (Relative and absolute paths acceptable.)
$PHPFront->assign('#parent-element', array(
'@import::after' => 'url(../../template_parts.html#menu)'
));
// Import the #menu element from another file in another server. (Absolute URL only.)
$PHPFront->assign('#parent-element', array(
'@import::after' => 'url(https://www.example.com/#menu)'
));
You can assign data to an element that is yet to be imported into the document.
This works because @import
commands are handled first before the other @ parameters - with the exception of @params
.
So by the time @content
is executed, the external element would have been imported and available to accept the assigned content.
In the example below, a class attribute has been assigned to a #menu
element that is yet to be imported and an array of content is waiting to be populated on all <li>
elements inside it.
// Import the #menu element in this document into #parent-element - append
$PHPFront->assign('#parent-element', array(
// Import #menu
'@import::after' => '#menu',
// Move on to Children
'@children' => array(
// There could be many children
// but choose the just-imported #menu
'#menu' => array(
// Set attribute
'@attr' => array('class' => 'submenu_item'),
// Then populate content on the list elements of #menu
'@children' => array(
'Home',
'About Us',
'Contact Us'
)
)
)
));
We just nested compound arguments in that example!
@content
Supplies content to an element as a string or an array.
This parameter is the same as $data
when functioning as simple argument.
Given the #content-box
element of previous examples, assignments A and B below are the same.
// A. Content from inside a compound argument
$PHPFront->assign('#content-box', array(
'@content::after' => 'This content is appearing after any existing content'
));
// B. Content as simple argument
$PHPFront->assign('#content-box::after', 'This content is appearing after any existing content');
We could also assign an array of content to an element; remember the auto population given earlier.
And don't forget, arrays target children, not the element itself.
$PHPFront->assign('#content-box', array(
'@content::after' => array('this is a span element', 'this is a second span element', 'this is a small text')
));
We placed the '::before' pseudo class on the @content
parameter and not on the element selector itself!
A '::before' or '::after' pseudo class on an element selector will apply generally on all the '@' parameters. Placing them on individual '@' parameters overrides that general rule.
@attr
Supplies a list of attributes to an element in key => value
pairs.
Let's add some values to any existing values for the class and style attributes in the #content-box
element.
$PHPFront->assign('#content-box::after', array('@attr' => array('class' => 'large-text boldened', 'style' => 'background:red')));
@children
Supplies an array of contents to an element's children.
This is an alias of the @content
parameter;
the difference being that @children
is always an array and always transferred to the element's children,
whereas @content
can be either a string meant for the element itself or an array meant for its children.
$PHPFront->assign('#content-box', array('@children' => array('content for childnode 1'));
Use @children
instead of @content
where an element's children are actually implied. This makes your code more understandable
@render
Modifies the existence of an element.
Can change the element's type (node type), or remove the element and its children, or, better still, leave children in place and remove element from document.
Here we go:
<div id="content-box">
<span></span>
<span></span>
<small></small>
</div>
The assignment
// Change the element type from div to nav
$PHPFront->assign('#content-box', array(
@render => 'nav'
));
Result
<nav id="content-box">
<span></span>
<span></span>
<small></small>
</nav>
The assignment (2)
// Remove the element but leave children in place.
// Notice that we're simply supplying an empty string.
$PHPFront->assign('#content-box', array(
@render => ''
));
Result (2)
<span></span>
<span></span>
<small></small>
The assignment (3)
// Finally, remove the element and its children.
$PHPFront->assign('#content-box', array(
@render => false
));
@repeat
Repeats an element as specified.
This element will be repeated next to itself as many times as needed to render the total number of items in array.
Consider a real case: we want to add many CSS scripts as links in the <head>
section of our page.
But we are providing just one empty <link>
element.
This will repeat itself to render whatever number of links are supplied.
<head>
<title>This Is Document Title</title>
<base href="http://example.com" />
<link />
</head>
The assignment
$PHPFront->assign('head link', array(
'@repeat' => array(
Array('@attr' => array('type' => 'text/css', 'href' => 'resources/main.css')),
Array('@attr' => array('type' => 'text/css', 'href' => 'resources/bootstrap.min.css')),
Array('@attr' => array('type' => 'text/css', 'href' => 'resources/slider.css'))
)
));
Result
<head>
<title>This Is Document Title</title>
<base href="http://example.com" />
<link type="text/css" href="resources/main.css" />
<link type="text/css" href="resources/bootstrap.min.css" />
<link type="text/css" href="resources/slider.css" />
</head>
Using @children
or @content
instead of @repeat
in this case
would attempt to create 3 children for the empty <link>
element, and that would be invalid markup.
Repeats are a great way to engineer a full-grown page from few strategic elements. That amounts to a DRY (Don't Repeat Yourself) approach.
And you could create patterns and grids (or tables) with this same principle. Repeats are covered here.
Summary
-
Using the
-
$element_selector
- is always a string of CSS selector or XPath query. -
$data
- simple argument- - when a string, means content for an element. Recall
- - when an array (indexed array), means content for an element's children in the order of their position. Recall
- - when an array (associative array), means content for an element's children matching the selectors in the array. Recall
- - when a multidimensional array (nested arrays), means content for an element's children and descendants. Recall
-
$data
- compound argument - represents a list of arguments, containing the parameters:@params
,@import
,@content
,@attr
,@children
,@render
, and@repeat
. Recall
PHPFront::assign()
function,
We just completed a whole chapter.