1<?php 2/** 3 * DokuWiki Plugin structtemplating (Action Component) 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author Frieder Schrempf <dev@fris.de> 7 */ 8 9use Twig\Environment; 10use Twig\Loader\FilesystemLoader; 11 12use dokuwiki\plugin\struct\meta\AggregationTable; 13 14require_once __DIR__ . '/vendor/autoload.php'; 15 16// must be run within Dokuwiki 17if (!defined('DOKU_INC')) { 18 die(); 19} 20 21class action_plugin_structtemplating extends DokuWiki_Action_Plugin 22{ 23 24 /** 25 * Registers a callback function for a given event 26 * 27 * @param Doku_Event_Handler $controller DokuWiki's event controller object 28 * 29 * @return void 30 */ 31 public function register(Doku_Event_Handler $controller) 32 { 33 $controller->register_hook('PLUGIN_STRUCT_RENDER_SCHEMA_DATA', 'BEFORE', 34 $this, 'handle_struct_render_schema_data'); 35 $controller->register_hook('PLUGIN_STRUCT_RENDER_AGGREGATION_TABLE', 'BEFORE', 36 $this, 'handle_struct_render_aggregation_table'); 37 } 38 39 /** 40 * [Custom event handler which performs action] 41 * 42 * Called for event: PLUGIN_STRUCT_RENDER_SCHEMA_DATA 43 * 44 * @param Doku_Event $event event object by reference 45 * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 46 * handler was registered] 47 * 48 * @return void 49 */ 50 public function handle_struct_render_schema_data(Doku_Event $event, $param) 51 { 52 $schemadata = $event->data['schemadata']; 53 $meta = $event->data['meta']; 54 $renderer = $event->data['renderer']; 55 $format = $event->data['format']; 56 57 $schemadata->optionSkipEmpty(true); 58 $data = $schemadata->getData(); 59 if (!count($data)) 60 return; 61 62 $event->data['hasdata'] = true; 63 64 $path = array( 65 __DIR__ . '/assets/templates/schema', 66 __DIR__ . '/assets/templates/common', 67 ); 68 69 try { 70 $loader = new FilesystemLoader($path); 71 } catch (Exception $e) { 72 return; 73 } 74 75 $twig = new Environment($loader, [ 76 'debug' => true, 77 ]); 78 $twig->addExtension(new \Twig\Extension\DebugExtension()); 79 $twig->addExtension(new \MikeAlmond\TwigColorExtension\ColorExtension()); 80 81 foreach ($data as $field) { 82 $idx = strlen($renderer->doc); 83 $field->render($renderer, $format); 84 $field->rendered = substr($renderer->doc, $idx); 85 $renderer->doc = substr($renderer->doc, 0, $idx); 86 } 87 88 try { 89 $twigmarkup = $twig->render( 90 $schemadata->getSchema()->getTable() . '.twig', 91 [ 92 'schema' => $schemadata->getSchema(), 93 'data' => $data, 94 'meta' => $meta 95 ] 96 ); 97 $renderer->doc .= $twigmarkup; 98 } catch (Exception $e) { 99 return; 100 } 101 102 $event->preventDefault(); 103 } 104 105 /** 106 * [Custom event handler which performs action] 107 * 108 * Called for event: PLUGIN_STRUCT_RENDER_AGGREGATION_TABLE 109 * 110 * @param Doku_Event $event event object by reference 111 * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 112 * handler was registered] 113 * 114 * @return void 115 */ 116 public function handle_struct_render_aggregation_table(Doku_Event $event, $param) 117 { 118 $renderer = $event->data['renderer']; 119 $columns= $event->data['columns']; 120 $table = $event->data['table']; 121 $search = $event->data['search']; 122 $data = $event->data['data']; 123 $format = $event->data['format']; 124 125 $path = array( 126 __DIR__ . '/assets/templates/aggregation', 127 __DIR__ . '/assets/templates/common', 128 ); 129 130 try { 131 $loader = new FilesystemLoader($path); 132 } catch (Exception $e) { 133 return; 134 } 135 136 $twig = new Environment($loader, [ 137 'debug' => true, 138 ]); 139 $twig->addExtension(new \Twig\Extension\DebugExtension()); 140 $twig->addExtension(new \MikeAlmond\TwigColorExtension\ColorExtension()); 141 142 /* 143 * If the data covers a single schema, we look for a matching 144 * aggregation template, if none is found or the data spans 145 * over multiple schemas, we use the page id to lookup a template 146 * file. 147 */ 148 $templates = array(); 149 if (count($search->getSchemas()) === 1) 150 $templates[] = $search->getSchemas()[0]->getTable() . '.twig'; 151 152 $templates[] = $table->getID() . '.twig'; 153 154 /* 155 * For each field in the table we want to make sure that we 156 * have the rendered value available in the template. 157 */ 158 foreach ($data as $row) { 159 foreach ($row as $field) { 160 $idx = strlen($renderer->doc); 161 $field->render($renderer, $format); 162 $field->rendered = substr($renderer->doc, $idx); 163 $renderer->doc = substr($renderer->doc, 0, $idx); 164 } 165 } 166 167 foreach ($templates as $template) { 168 try { 169 $twigmarkup = $twig->render( 170 $template, 171 [ 172 'columns' => $columns, 173 'data' => $data 174 ] 175 ); 176 $renderer->doc .= $twigmarkup; 177 $event->preventDefault(); 178 return; 179 } catch (Exception $e) { 180 } 181 } 182 } 183} 184 185