mirror of
https://github.com/cosmocode/dokuwiki-plugin-struct.git
synced 2025-08-13 13:37:20 +00:00
added classes config parameter
This allows users to set custom CSS classes on aggregations potentially restyling them differently for different use cases. This makes startScope and finishScope part of the public API of the Aggregation class. It should no longer be called within render() but is instead called outside. This might potentially break plugins implementing their own aggregations. Needs to be checked
This commit is contained in:
@ -21,7 +21,8 @@ class ConfigParserTest extends StructTest
|
||||
"cols : %pageid%, count",
|
||||
"sort : ^count",
|
||||
"sort : %pageid%, ^bam",
|
||||
"align : r,l,center,foo"
|
||||
"align : r,l,center,foo",
|
||||
"class : foo, bar",
|
||||
];
|
||||
|
||||
$configParser = new meta\ConfigParser($lines);
|
||||
@ -85,6 +86,7 @@ class ConfigParserTest extends StructTest
|
||||
'align' => ['right', 'left', 'center', null],
|
||||
'nesting' => 0,
|
||||
'index' => 0,
|
||||
'classes' => ['struct-custom-foo', 'struct-custom-bar'],
|
||||
];
|
||||
|
||||
$this->assertEquals($expected_config, $actual_config);
|
||||
|
@ -53,6 +53,7 @@ class InlineConfigParserTest extends StructTest
|
||||
'widths' => [],
|
||||
'nesting' => 0,
|
||||
'index' => 0,
|
||||
'classes' => [],
|
||||
];
|
||||
|
||||
$this->assertEquals($expected_config, $actual_config);
|
||||
|
@ -231,6 +231,9 @@ class SearchConfigParameterTest extends StructTest
|
||||
],
|
||||
'rownumbers' => '1',
|
||||
'limit' => '5',
|
||||
'nesting' => 0,
|
||||
'index' => 0,
|
||||
'classes' => [],
|
||||
];
|
||||
|
||||
$R = new \Doku_Renderer_xhtml();
|
||||
@ -238,7 +241,9 @@ class SearchConfigParameterTest extends StructTest
|
||||
$INPUT->set(meta\SearchConfigParameters::$PARAM_OFFSET, 5);
|
||||
$searchConfig = new meta\SearchConfig($data);
|
||||
$aggregationTable = new meta\AggregationTable('test_pagination', 'xhtml', $R, $searchConfig);
|
||||
$aggregationTable->startScope();
|
||||
$aggregationTable->render();
|
||||
$aggregationTable->finishScope();
|
||||
|
||||
$rev = time();
|
||||
|
||||
|
@ -73,9 +73,67 @@ abstract class Aggregation
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the table on the renderer
|
||||
* Return the list of classes that should be added to the scope when rendering XHTML
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getScopeClasses()
|
||||
{
|
||||
// we're all aggregations
|
||||
$classes = ['structaggregation'];
|
||||
|
||||
// which type of aggregation are we?
|
||||
$class = get_class($this);
|
||||
$class = substr($class, strrpos($class, "\\") + 1);
|
||||
$class = strtolower($class);
|
||||
$classes[] = 'struct' . $class;
|
||||
|
||||
// config options
|
||||
if ($this->data['nesting']) {
|
||||
$classes[] = 'is-nested';
|
||||
}
|
||||
if ($this->data['index']) {
|
||||
$classes[] = 'is-indexed';
|
||||
}
|
||||
|
||||
// custom classes
|
||||
$classes = array_merge($classes, $this->data['classes']);
|
||||
return $classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the actual output to the renderer
|
||||
*
|
||||
* @param bool $showNotFound show a not found message when no data available?
|
||||
*/
|
||||
abstract public function render($showNotFound = false);
|
||||
|
||||
/**
|
||||
* Adds additional info to document and renderer in XHTML mode
|
||||
*
|
||||
* Called before render()
|
||||
*
|
||||
* @see finishScope()
|
||||
*/
|
||||
public function startScope()
|
||||
{
|
||||
if ($this->mode == 'xhtml') {
|
||||
$classes = $this->getScopeClasses();
|
||||
$this->renderer->doc .= '<div class="' . join(' ', $classes) . '">';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes anything opened in startScope()
|
||||
*
|
||||
* Called after render()
|
||||
*
|
||||
* @see startScope()
|
||||
*/
|
||||
public function finishScope()
|
||||
{
|
||||
if ($this->mode == 'xhtml') {
|
||||
$this->renderer->doc .= '</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,37 +32,11 @@ class AggregationCloud extends Aggregation
|
||||
public function render($showNotFound = false)
|
||||
{
|
||||
$this->sortResults();
|
||||
$this->startScope();
|
||||
$this->startList();
|
||||
foreach ($this->result as $result) {
|
||||
$this->renderTag($result);
|
||||
}
|
||||
$this->finishList();
|
||||
$this->finishScope();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds additional info to document and renderer in XHTML mode
|
||||
*
|
||||
* @see finishScope()
|
||||
*/
|
||||
protected function startScope()
|
||||
{
|
||||
// wrapping div
|
||||
if ($this->mode != 'xhtml') return;
|
||||
$this->renderer->doc .= "<div class=\"structcloud\">";
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the table and anything opened in startScope()
|
||||
*
|
||||
* @see startScope()
|
||||
*/
|
||||
protected function finishScope()
|
||||
{
|
||||
// wrapping div
|
||||
if ($this->mode != 'xhtml') return;
|
||||
$this->renderer->doc .= '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,7 +25,7 @@ class AggregationEditorTable extends AggregationTable
|
||||
*
|
||||
* @see finishScope()
|
||||
*/
|
||||
protected function startScope()
|
||||
public function startScope()
|
||||
{
|
||||
// unique identifier for this aggregation
|
||||
$this->renderer->info['struct_table_hash'] = md5(var_export($this->data, true));
|
||||
@ -39,7 +39,10 @@ class AggregationEditorTable extends AggregationTable
|
||||
$config = hsc(json_encode($config));
|
||||
|
||||
// wrapping div
|
||||
$this->renderer->doc .= "<div class=\"structaggregation structaggregationeditor\"
|
||||
$classes = $this->getScopeClasses();
|
||||
$classes[] = 'structaggregationeditor';
|
||||
$classes = join(' ', $classes);
|
||||
$this->renderer->doc .= "<div class=\"$classes\"
|
||||
data-schema=\"$table\" data-searchconf=\"$config\">";
|
||||
|
||||
// unique identifier for this aggregation
|
||||
|
@ -22,7 +22,6 @@ class AggregationList extends Aggregation
|
||||
/** @inheritdoc */
|
||||
public function render($showNotFound = false)
|
||||
{
|
||||
$this->startScope();
|
||||
if ($this->result) {
|
||||
$nestedResult = new NestedResult($this->result);
|
||||
$root = $nestedResult->getRoot($this->data['nesting'], $this->data['index']);
|
||||
@ -30,7 +29,6 @@ class AggregationList extends Aggregation
|
||||
} elseif ($showNotFound) {
|
||||
$this->renderer->cdata($this->helper->getLang('none'));
|
||||
}
|
||||
$this->finishScope();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -82,31 +80,6 @@ class AggregationList extends Aggregation
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds additional info to document and renderer in XHTML mode
|
||||
*
|
||||
* @see finishScope()
|
||||
*/
|
||||
protected function startScope()
|
||||
{
|
||||
// wrapping div
|
||||
if ($this->mode != 'xhtml') return;
|
||||
$this->renderer->doc .= "<div class=\"structaggregation listaggregation\">";
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes anything opened in startScope()
|
||||
*
|
||||
* @see startScope()
|
||||
*/
|
||||
protected function finishScope()
|
||||
{
|
||||
// wrapping div
|
||||
if ($this->mode != 'xhtml') return;
|
||||
$this->renderer->doc .= '</div>';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render the content of a single list item
|
||||
*
|
||||
|
@ -31,13 +31,10 @@ class AggregationTable extends Aggregation
|
||||
|
||||
// abort early if there are no results at all (not filtered)
|
||||
if (!$this->resultCount && !$this->isDynamicallyFiltered() && $showNotFound) {
|
||||
$this->startScope();
|
||||
$this->renderer->cdata($this->helper->getLang('none'));
|
||||
$this->finishScope();
|
||||
return;
|
||||
}
|
||||
|
||||
$this->startScope();
|
||||
$this->renderActiveFilters();
|
||||
|
||||
$rendercontext = array(
|
||||
@ -57,7 +54,6 @@ class AggregationTable extends Aggregation
|
||||
|
||||
// export handle
|
||||
$this->renderExportControls();
|
||||
$this->finishScope();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,14 +94,12 @@ class AggregationTable extends Aggregation
|
||||
*
|
||||
* @see finishScope()
|
||||
*/
|
||||
protected function startScope()
|
||||
public function startScope()
|
||||
{
|
||||
// unique identifier for this aggregation
|
||||
$this->renderer->info['struct_table_hash'] = md5(var_export($this->data, true));
|
||||
|
||||
// wrapping div
|
||||
if ($this->mode != 'xhtml') return;
|
||||
$this->renderer->doc .= "<div class=\"structaggregation\">";
|
||||
parent::startScope();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -113,16 +107,14 @@ class AggregationTable extends Aggregation
|
||||
*
|
||||
* @see startScope()
|
||||
*/
|
||||
protected function finishScope()
|
||||
public function finishScope()
|
||||
{
|
||||
// remove identifier from renderer again
|
||||
if (isset($this->renderer->info['struct_table_hash'])) {
|
||||
unset($this->renderer->info['struct_table_hash']);
|
||||
}
|
||||
|
||||
// wrapping div
|
||||
if ($this->mode != 'xhtml') return;
|
||||
$this->renderer->doc .= '</div>';
|
||||
parent::finishScope();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -33,8 +33,6 @@ class AggregationValue extends Aggregation
|
||||
*/
|
||||
public function render($show_not_found = 0)
|
||||
{
|
||||
$this->startScope();
|
||||
|
||||
// Check that we actually got a result
|
||||
if ($this->resultCount) {
|
||||
$this->renderValue($this->result[0]); // only one result
|
||||
@ -43,36 +41,6 @@ class AggregationValue extends Aggregation
|
||||
$this->renderer->cdata($this->helper->getLang('none'));
|
||||
}
|
||||
}
|
||||
|
||||
$this->finishScope();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds additional info to document and renderer in XHTML mode
|
||||
*
|
||||
* @see finishScope()
|
||||
*/
|
||||
protected function startScope()
|
||||
{
|
||||
// wrapping span
|
||||
if ($this->mode != 'xhtml') {
|
||||
return;
|
||||
}
|
||||
$this->renderer->doc .= "<span class=\"structaggregation valueaggregation\">";
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes anything opened in startScope()
|
||||
*
|
||||
* @see startScope()
|
||||
*/
|
||||
protected function finishScope()
|
||||
{
|
||||
// wrapping span
|
||||
if ($this->mode != 'xhtml') {
|
||||
return;
|
||||
}
|
||||
$this->renderer->doc .= '</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -41,6 +41,7 @@ class ConfigParser
|
||||
'csv' => true,
|
||||
'nesting' => 0,
|
||||
'index' => 0,
|
||||
'classes' => array(),
|
||||
);
|
||||
// parse info
|
||||
foreach ($lines as $line) {
|
||||
@ -125,6 +126,10 @@ class ConfigParser
|
||||
case 'index':
|
||||
$this->config['index'] = (int) $val;
|
||||
break;
|
||||
case 'class':
|
||||
case 'classes':
|
||||
$this->config['classes'] = $this->parseClasses($val);
|
||||
break;
|
||||
default:
|
||||
$data = array('config' => &$this->config, 'key' => $key, 'val' => $val);
|
||||
$ev = new \Doku_Event('PLUGIN_STRUCT_CONFIGPARSER_UNKNOWNKEY', $data);
|
||||
@ -312,4 +317,21 @@ class ConfigParser
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure custom classes are valid and don't clash
|
||||
*
|
||||
* @param string $line
|
||||
* @return string[]
|
||||
*/
|
||||
protected function parseClasses($line)
|
||||
{
|
||||
$classes = $this->parseValues($line);
|
||||
$classes = array_map(function ($class) {
|
||||
$class = str_replace(' ', '_', $class);
|
||||
$class = preg_replace('/[^a-zA-Z0-9_]/', '', $class);
|
||||
return 'struct-custom-' . $class;
|
||||
}, $classes);
|
||||
return $classes;
|
||||
}
|
||||
}
|
||||
|
@ -314,7 +314,7 @@ form.struct_newschema {
|
||||
|
||||
.dokuwiki .structaggregation {
|
||||
|
||||
&.listaggregation > ul li div {
|
||||
&.structaggregationlist > ul li div {
|
||||
display: inline;
|
||||
|
||||
p {
|
||||
@ -380,7 +380,7 @@ form.struct_newschema {
|
||||
}
|
||||
}
|
||||
|
||||
.dokuwiki .structcloud {
|
||||
.dokuwiki .structaggregationcloud {
|
||||
ul {
|
||||
text-align: center;
|
||||
|
||||
|
@ -94,7 +94,9 @@ class syntax_plugin_struct_cloud extends DokuWiki_Syntax_Plugin
|
||||
try {
|
||||
$search = new SearchCloud($data);
|
||||
$cloud = new AggregationCloud($INFO['id'], $mode, $renderer, $search);
|
||||
$cloud->startScope();
|
||||
$cloud->render();
|
||||
$cloud->finishScope();
|
||||
if ($mode == 'metadata') {
|
||||
/** @var Doku_Renderer_metadata $renderer */
|
||||
$renderer->meta['plugin']['struct']['hasaggregation'] = $search->getCacheFlag();
|
||||
|
@ -117,7 +117,9 @@ class syntax_plugin_struct_table extends DokuWiki_Syntax_Plugin
|
||||
|
||||
/** @var Aggregation $table */
|
||||
$table = new $this->tableclass($mainId, $format, $renderer, $search);
|
||||
$table->startScope();
|
||||
$table->render(true);
|
||||
$table->finishScope();
|
||||
|
||||
if ($format === 'metadata') {
|
||||
/** @var Doku_Renderer_metadata $renderer */
|
||||
|
@ -104,7 +104,9 @@ class syntax_plugin_struct_value extends DokuWiki_Syntax_Plugin
|
||||
|
||||
/** @var AggregationValue $value */
|
||||
$value = new AggregationValue($INFO['id'], $mode, $renderer, $search);
|
||||
$value->startScope();
|
||||
$value->render($show_not_found);
|
||||
$value->finishScope();
|
||||
|
||||
if ($mode == 'metadata') {
|
||||
/** @var Doku_Renderer_metadata $renderer */
|
||||
|
Reference in New Issue
Block a user