=====Generating Columns from an Array===== //Installed to support [[WikkaBetaFeatures alpha features]] on this server as of 2005-06-12.// >>See also: ~-ArrayToList ~-AdvancedBacklinksAction ~-AdvancedCategoryAction >>This page presents new code for the [[Docs:WikkaCore Wikka Core]] to generate columns of items from an array of items to be presented - without using a table for layout. ====Why?==== In many cases we get an array back from some procedure and want to display the result in the form of a number of easy to read columns. The current Wikka code now does this "manually" and generates a table layout which is not only not very structural code but also not very accessible. (Example: the [[Docs:CategoryActionInfo Category action]] can generate its output in "columns" but they need to be read horizontally rather than vertically - making it hard to "scan" so a particular name is hard to find - and the code generated is a layout table.) Using a standard way to generate columns is more efficient, can ensure consistent and structural code and makes it easier to write methods (or actions or handlers) that need columns of items as output. ====How?==== Two separate methods were written to make it easy to generate well-structured columns with 'hooks' for styling: the first does nothing but generate a list from an array (with an id); the second wraps that in a bit of code with a heading and a bit of text instead of the list if the array happens to be empty. ====The Code==== ===Constants=== The methods make use of some constants (limits and texts used for error messages, ready for internationalization) that should be defined in the constants section in wikka.php. See ArrayToList for the code and where to insert it. ===##""makeCols()""##=== This method does the hard work of creating columnar output from an array, using floated ##div##s instead of a layout table. It requires the ##""makeId()""## method to be already present - see GenerateUniqueId. Add the following code in the ##""//MISC""## section right after the ##""makeMemberList()""## method (see ArrayToList for that): **##""makeCols()""##** %%(php;1) /** * Build vertically-arranged columns from an array. * * Given an array and number of columns, this method builds vertically- * arranged columns (meaning they are read vertically, one by one) * implemented as floated divs. Column width is derived from the * specified number of columns, implemented as an embedded style because * it's dynamically generated; left float is added to the style (hardcoded * for now but alignment could become an option later). * * @author {@link http://wikka.jsnx.com/JavaWoman JavaWoman} * @copyright Copyright © 2005, Marjolein Katsma * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License * @version 0.4 * * @todo - make alignment configurable * - class as extra parameter (for each column) * - replace clear: both style at end with a class (?) * * @access public * * @param array $array required: flat array with content items; must be array but may be empty * @param integer $cols optional: number of columns to generate; default: 1 * (will be cast to positive integer) * @return string generated divs (or empty string if array was empty) */ function makeCols($array,$cols=1) { // validate/treat input if (!is_array($array)) { return '

'.sprintf(ERR_CANNOTGEN,STRUC_COLS,STRUC_ARRAY).'

'."\n"; } $cols = abs((int)$cols); # make sure we have a positive integer // build columns $count = count($array); $width = (int) (100 / $cols); $lines = ($count % $cols == 0) ? (int)($count / $cols) : (int)(($count + $cols) / $cols); $line = 0; $out = ''; // data columns foreach ($array as $val) { if (($line++ % $lines) == 0) $out .= "\n".'
'."\n"; $out .= ' '.$val.'
'."\n"; if (($line % $lines) == 0) $out .= "
"; } if ($count > 0) { if (($line % $lines) != 0) $out .= " "; $out .= '
'."\n"; } // return result return $out; } %% ===##""makeMemberCols()""##=== This method is a wrapper around the ##""makeCols()""## method: it wraps the output in a div and adds a heading or outputs a paragraph of text in case the array turns out to be empty. It's meant for cases where items are to be presented as "members" of a collection; the heading is used to indicate the number of members. As with the [[ArrayToList makeMemberList()]] method there is deliberately no 'outer' div with an id: this is so a wrapper div may be created with a single heading containing several occurrences of the output of this method. Such a wrapper should be generated in the calling code. Add the following code in the ##""//MISC""## section right after the ##""makeCols()""## method: **##""makeMemberCols()""##** %%(php;1) /** * Display members of a collection in vertical columns; a heading precedes * the columns; alternatively output is just a paragraph of text in case the * array provided turns out to be empty. * * There is deliberately no 'outer' div with an id: this is so a div may be * created with a single heading containing several occurrences of the * output of this method. Such a wrapper should be generated in the calling code. * * @author {@link http://wikka.jsnx.com/JavaWoman JavaWoman} * @copyright Copyright © 2005, Marjolein Katsma * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License * @version 0.6 * * @access public * @uses makeId() * @uses makeCols() * * @param array $array required: flat array with collection items * @param string $hd required: heading for the whole * @param string $hdid required: id for the heading * @param string $txtnone required: text to display when the array is empty * @param integer $level optional: level of the heading to generate; default: 6 * @return string div containing heading and list, or paragraph */ function makeMemberCols($array,$cols,$hd,$hdid,$txtnone,$level=6) { // validate/sanitize input if (!is_array($array)) { return '

'.sprintf(ERR_CANNOTGEN,STRUC_COLS,STRUC_ARRAY).'

'."\n"; } $cols = abs((int)$cols); # make sure we have a positive integer $level = max(min((int)$level,6),3); # make sure level is in range 3-6 // initializations $count = count($array); $out = ''; // build structure if ($count > 0) { $out .= '
'.$hd.'
'."\n"; $out .= $this->makeCols($array,$cols); } else { $out = '

'.$txtnone.'

'."\n"; } // return result return $out; } %% ====When and where to use==== In general, you can use these methods anywhere you get (or build) an array and want to display the result in the form of columns - for instance to avoid over-long pages when there are a lot of items to show. Several current actions and handlers could take advantage of these methods, in particular: ~-The [[Docs:BacklinksActionInfo Backlinks action]] simply lists pages in an unstructured list; it could use a structured list or columns like the category action instead.---//The AdvancedBacklinksAction already uses it - see WikkaBetaFeatures.// ~-The [[CategoryActionInfo Category action]] which can list category contents either as a list or columns.---//The AdvancedCategoryAction already uses it - see WikkaBetaFeatures.// Updates for these (and possibly others) taking advantage of these new methods will soon be published on this site! ====Status==== As can be seen from the @version numbers and @todo items in the docblocks, the code is far from "finished". Still, **code as published here //will// change** as it's being refined - so keep an eye on the page! ---- CategoryDevelopmentCore