Jump to content

New WireArray API additions on dev


ryan
 Share

Recommended Posts

Here are some API additions to the dev branch, primarily for WireArray/PageArray/etc. I've found these very handy lately, and would have on almost any project I worked on, so decided they'd add value to the core. I'll add these to the cheatsheet once 2.4 replaces 2.3, but for now, here they are. The examples here use PageArray, but note that these API additions apply to any WireArray derived type, not just PageArray. 

WireArray::implode()

Implode all elements to a delimiter-separated string containing the given property from each item. Similar to PHP's implode() function. 

 

Usage:

$string = $items->implode([$delimiter], $property, [$options]); 

Arguments:

  • $delimiter - The delimiter to separate each item by (or the glue to tie them together). May be omitted if not needed
  • $property - The property to retrieve from each item (i.e. "title"), or a function that returns the value to store. If a function/closure is provided it is given the $item (argument 1) and the $key (argument 2), and it should return the value (string) to use.
  • [$options] - This argument is optional. When used, it's an array with modifiers to the behavior: 
    skipEmpty: Whether empty items should be skipped (default=true)
    prepend: String to prepend to result. Ignored if result is blank.
    append: String to prepend to result. Ignored if result is blank.

Examples:

$items = $pages->find("template=basic-page"); 

// render all the titles, each separated by a <br>, for each page in $items
echo $items->implode('<br>', 'title'); 

// render an unordered list of each item's title
echo "<ul><li>";
echo $items->implode('</li><li>', 'title');
echo "</li></ul>";

// same as above, but using prepend/append options, 
// this ensures no list generated when $items is empty
echo $items->implode('</li><li>', 'title', array(
  'prepend' => '<ul><li>', 
  'append' => '</li></ul>'
)); 

// same as above, but with all items now presented as links
// this demonstrates use of $property as a function. note that
// we are also omitting the delimiter here as well, since we don't need it
echo $items->implode(function($item) {
  return "<li><a href='$item->url'>$item->title</a></li>";
}, array('prepend' => '<ul>', 'append' => '</ul>'));  

WireArray::explode()

Return a plain array of the requested property from each item. Similar to PHP's explode() function. The returned PHP array uses the same keys as the original WireArray (if that matters). 

Usage:

$array = $items->explode($property);

Arguments:

  • $property - The name of the property (string) to have in each array element (i.e. "title"). You may also provide a function/closure here that should return the value to store. When a function/closure is used it receives the $item as the first argument and the $key (if needed) as the second. 

Examples:

// get an array containing the 'title' of each page
$array = $items->explode('title'); 

// get an array containing the id, url and title of each page
$array = $items->explode(function($item) {
  return array(
    'id' => $item->id, 
    'url' => $item->url, 
    'title' => $item->title
  ); 
}); 

WireArray::data()

Store or retrieve an arbitrary/extra data value in this WireArray. This is exactly the same thing that it is jQuery. I've personally found this useful when building search engines: the search engine can store extra meta data of what was searched for as a data() property. Then any other functions receiving the WireArray/PageArray have access to this additional info. For example, the search engine portion of your site could populate an array of summary data about what was searched for, and the render/output code could render it to the user. 

Usage:

// Setting data
$items->data('key', 'value'); 

// Getting data
$value = $items->data('key'); 

// Get array (indexed by key) of all data 
$values = $items->data(); 

Arguments: 

The above usage section explains all that's needed to know about the arguments. The only additional comments I'd make are that 'key' should always be a string, and 'value' can be anything you want it to be. 

Example:

function findSkyscrapers() {
  $floors = (int) wire('input')->get->floors; 
  $year = (int) wire('input')->get->year;  
  $items = wire('pages')->find("template=skyscraper, floors=$floors, year=$year"); 
  $items->data('summary', array(
    'Number of floors' => $floors,
    'Year constructed' => $year
  )); 
  return $items;
}

// the render function can focus purely on output
function renderSkyscrapers($items) {
  echo "<h2>You searched for:</h2>";
  // render the summary of what was searched for
  foreach($items->data('summary') as $label => $value) {
    echo "<p>$label: $value</p>";
  } 
  echo "<h3>Skyscrapers found:</h3>";
  // note use of new implode() function, though a foreach() would be just as well here
  echo $items->implode(function($item) {
    return "<p><a href='$item->url'>$item->title</a></p>";
  }); 
}

WireArray::and() 

WireData::and()

Return a new copy of the WireArray with the given item(s) appended. Primarily as a syntax convenience for various situations. This is similar to jQuery's add() and andSelf() functions, but I've always felt "add" implied adding something to the original rather than creating a new combination, so went with "and" in this case. The term "and" is actually a reserved word in PHP, so you can't usually have a function named "and()", but through the magic of hooks, ProcessWire can. :) This function should reduce the instances in which you'd need to do "$a = new PageArray();" for example.  

Usage:

// create a new WireArray with $items and $item (appended)
$myItems = $items->and($item); 

// create a new WireArray with $items and $moreItems (appended)
$myItems = $items->and($moreItems); 

// create a new WireArray with $items and $item (prepended)
$myItems = $item->and($items); 

// create a new WireArray with $item and $anotherItem (appended)
$myItems = $item->and($anotherItem); 

// create a new WireArray 4 items
$family = $pappa->and($mamma)->and($brother)->and($sister); 

Examples:

// generate breadcrumb trail that includes current page
foreach($page->parents->and($page) as $item) {
  echo "<a href='$item->url'>$item->title</a> / ";
}

// check if page or its children has a featured checkbox
if($page->and($page->children)->has("featured=1")) {
  echo "<p>Featured!</p>";
}
  • Like 35
  • Thanks 1
Link to comment
Share on other sites

  • 2 months later...
  • 4 months later...
  • 1 month later...

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
 Share

  • Recently Browsing   0 members

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