ILIAS  release_7 Revision v7.30-3-g800a261c036
Renderer.php
Go to the documentation of this file.
1<?php
2
3/* Copyright (c) 2016 Richard Klees <richard.klees@concepts-and-training.de> Extended GPL, see docs/LICENSE */
4
6
9use ILIAS\UI\Renderer as RendererInterface;
11
13{
17 public function render(Component\Component $component, RendererInterface $default_renderer)
18 {
19 $this->checkComponent($component);
20
21 if ($component instanceof Component\Button\Close) {
22 return $this->renderClose($component);
23 } elseif ($component instanceof Component\Button\Toggle) {
24 return $this->renderToggle($component);
25 } elseif ($component instanceof Component\Button\Month) {
26 return $this->renderMonth($component, $default_renderer);
27 } else {
31 return $this->renderButton($component, $default_renderer);
32 }
33 }
34
35
42 protected function renderButton(Component\Button\Button $component, RendererInterface $default_renderer)
43 {
44 $tpl_name = "";
45 if ($component instanceof Component\Button\Primary) {
46 $tpl_name = "tpl.primary.html";
47 }
48 if ($component instanceof Component\Button\Standard) {
49 $tpl_name = "tpl.standard.html";
50 }
51 if ($component instanceof Component\Button\Shy) {
52 $tpl_name = "tpl.shy.html";
53 }
54 if ($component instanceof Component\Button\Tag) {
55 $tpl_name = "tpl.tag.html";
56 }
57 if ($component instanceof Component\Button\Bulky) {
58 $tpl_name = "tpl.bulky.html";
59 }
60
61 $tpl = $this->getTemplate($tpl_name, true, true);
62
63 $action = $component->getAction();
64 // The action is always put in the data-action attribute to have it available
65 // on the client side, even if it is not available on rendering.
66 if (is_string($action)) {
67 $tpl->setCurrentBlock("with_data_action");
68 $tpl->setVariable("ACTION", $action);
69 $tpl->parseCurrentBlock();
70 }
71
72 $label = $component->getLabel();
73 if ($label !== null) {
74 $tpl->setVariable("LABEL", $component->getLabel());
75 }
76 if ($component->isActive()) {
77 // The actions might also be a list of signals, these will be appended by
78 // bindJavascript in maybeRenderId.
79 if (is_string($action) && $action != "") {
80 $component = $component->withAdditionalOnLoadCode(function ($id) use ($action) {
81 $action = str_replace("&amp;", "&", $action);
82
83 return "$('#$id').on('click', function(event) {
84 window.location = '{$action}';
85 return false;
86 });";
87 });
88 }
89
90 if ($component instanceof Component\Button\LoadingAnimationOnClick && $component->hasLoadingAnimationOnClick()) {
91 $component = $component->withAdditionalOnLoadCode(function ($id) {
92 return "$('#$id').click(function(e) { il.UI.button.activateLoadingAnimation('$id')});";
93 });
94 }
95 } else {
96 $tpl->touchBlock("disabled");
97 }
98 $aria_label = $component->getAriaLabel();
99 if ($aria_label != null) {
100 $tpl->setCurrentBlock("with_aria_label");
101 $tpl->setVariable("ARIA_LABEL", $aria_label);
102 $tpl->parseCurrentBlock();
103 }
104
105 if ($component instanceof Component\Button\Engageable
106 && $component->isEngageable()
107 ) {
108 if ($component->isEngaged()) {
109 $tpl->touchBlock("engaged");
110 $aria_pressed = 'true';
111 } else {
112 $aria_pressed = 'false';
113 }
114
115 //Note that Bulky Buttons need to handle aria_pressed seperatly due to possible aria_role conflicts
116 if (!($component instanceof Bulky)) {
117 $tpl->setCurrentBlock("with_aria_pressed");
118 $tpl->setVariable("ARIA_PRESSED", $aria_pressed);
119 $tpl->parseCurrentBlock();
120 }
121 }
122
123 $this->maybeRenderId($component, $tpl);
124
125 if ($component instanceof Component\Button\Tag) {
126 $this->additionalRenderTag($component, $tpl);
127 }
128
129 if ($component instanceof Component\Button\Bulky) {
130 $this->additionalRenderBulky($component, $default_renderer, $tpl);
131 }
132
133 return $tpl->get();
134 }
135
139 public function registerResources(\ILIAS\UI\Implementation\Render\ResourceRegistry $registry)
140 {
141 parent::registerResources($registry);
142 $registry->register('./src/UI/templates/js/Button/button.js');
143 $registry->register("./node_modules/moment/min/moment-with-locales.min.js");
144 $registry->register("./node_modules/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min.js");
145 }
146
147 protected function renderClose($component)
148 {
149 $tpl = $this->getTemplate("tpl.close.html", true, true);
150 // This is required as the rendering seems to only create any output at all
151 // if any var was set or block was touched.
152 $tpl->setVariable("FORCE_RENDERING", "");
153 $tpl->setVariable("ARIA_LABEL", $this->txt("close"));
154 $this->maybeRenderId($component, $tpl);
155 return $tpl->get();
156 }
157
158 protected function renderToggle(Component\Button\Toggle $component)
159 {
160 $tpl = $this->getTemplate("tpl.toggle.html", true, true);
161
162 $on_action = $component->getActionOn();
163 $off_action = $component->getActionOff();
164
165 $on_url = (is_string($on_action))
166 ? $on_action
167 : "";
168
169 $off_url = (is_string($off_action))
170 ? $off_action
171 : "";
172
173 $signals = [];
174
175 foreach ($component->getTriggeredSignals() as $s) {
176 $signals[] = [
177 "signal_id" => $s->getSignal()->getId(),
178 "event" => $s->getEvent(),
179 "options" => $s->getSignal()->getOptions()
180 ];
181 }
182
183 $signals = json_encode($signals);
184
185 $button_status = 'off';
186 if ($component->isEngaged()) {
187 $button_status = 'on';
188 }
189
190 if ($component->isActive()) {
191 $component = $component->withAdditionalOnLoadCode(function ($id) use ($on_url, $off_url, $signals) {
192 $code = "$('#$id').on('click', function(event) {
193 il.UI.button.handleToggleClick(event, '$id', '$on_url', '$off_url', $signals);
194 return false; // stop event propagation
195 });";
196 //var_dump($code); exit;
197 return $code;
198 });
199 $tpl->setCurrentBlock("with_on_off_label");
200 $tpl->setVariable("ON_LABEL", $this->txt("toggle_on"));
201 $tpl->setVariable("OFF_LABEL", $this->txt("toggle_off"));
202 $tpl->parseCurrentBlock();
203 } else {
204 $tpl->touchBlock("disabled");
205 $button_status = 'unavailable';
206 }
207
208 $tpl->touchBlock($button_status);
209
210 $label = $component->getLabel();
211 if (!empty($label)) {
212 $tpl->setCurrentBlock("with_label");
213 $tpl->setVariable("LABEL", $label);
214 $tpl->parseCurrentBlock();
215 }
216 $aria_label = $component->getAriaLabel();
217 if ($aria_label != null) {
218 $tpl->setCurrentBlock("with_aria_label");
219 $tpl->setVariable("ARIA_LABEL", $aria_label);
220 $tpl->parseCurrentBlock();
221 }
222 $this->maybeRenderId($component, $tpl);
223 return $tpl->get();
224 }
225
226 protected function maybeRenderId(Component\JavaScriptBindable $component, $tpl)
227 {
228 $id = $this->bindJavaScript($component);
229 if ($id !== null) {
230 $tpl->setCurrentBlock("with_id");
231 $tpl->setVariable("ID", $id);
232 $tpl->parseCurrentBlock();
233 }
234 }
235
236 protected function renderMonth(Component\Button\Month $component, RendererInterface $default_renderer)
237 {
238 $def = $component->getDefault();
239
240 for ($i = 1; $i <= 12; $i++) {
241 $this->toJS(array("month_" . str_pad($i, 2, "0", STR_PAD_LEFT) . "_short"));
242 }
243
244 $tpl = $this->getTemplate("tpl.month.html", true, true);
245
246 $month = explode("-", $def);
247 $tpl->setVariable("DEFAULT_LABEL", $this->txt("month_" . str_pad($month[0], 2, "0", STR_PAD_LEFT) . "_short") . " " . $month[1]);
248 $tpl->setVariable("DEF_DATE", $month[0] . "/1/" . $month[1]);
249 // see https://github.com/moment/moment/tree/develop/locale
250 $lang_key = in_array($this->getLangKey(), array("ar", "bg", "cs", "da", "de", "el", "en", "es", "et", "fa", "fr", "hu", "it",
251 "ja", "ka", "lt", "nl", "pl", "pt", "ro", "ru", "sk", "sq", "sr", "tr", "uk", "vi", "zh"))
252 ? $this->getLangKey()
253 : "en";
254 if ($lang_key == "zh") {
255 $lang_key = "zh-cn";
256 }
257 $tpl->setVariable("LANG", $lang_key);
258
259 $id = $this->bindJavaScript($component);
260
261 if ($id !== null) {
262 $tpl->setCurrentBlock("with_id");
263 $tpl->setVariable("ID", $id);
264 $tpl->parseCurrentBlock();
265 $tpl->setVariable("JSID", $id);
266 }
267
268 return $tpl->get();
269 }
270
271 protected function additionalRenderTag(Component\Button\Tag $component, $tpl)
272 {
273 $tpl->touchBlock('rel_' . $component->getRelevance());
274
275 $classes = trim(join(' ', $component->getClasses()));
276 if ($classes !== '') {
277 $tpl->setVariable("CLASSES", $classes);
278 }
279
280 $bgcol = $component->getBackgroundColor();
281 if ($bgcol) {
282 $tpl->setVariable("BGCOL", $bgcol->asHex());
283 }
284 $forecol = $component->getForegroundColor();
285 if ($forecol) {
286 $tpl->setVariable("FORECOL", $forecol->asHex());
287 }
288 }
289
290 protected function additionalRenderBulky(Component\Button\Button $component, RendererInterface $default_renderer, $tpl)
291 {
292 $renderer = $default_renderer->withAdditionalContext($component);
293 $tpl->setVariable("ICON_OR_GLYPH", $renderer->render($component->getIconOrGlyph()));
294 $label = $component->getLabel();
295 if ($label !== null) {
296 $tpl->setVariable("LABEL", $label);
297 }
298
299 $aria_role = $component->getAriaRole();
300 if ($aria_role != null) {
301 $tpl->setCurrentBlock("with_aria_role");
302 $tpl->setVariable("ARIA_ROLE", $aria_role);
303 $tpl->parseCurrentBlock();
304 }
305 if ($component->isEngageable()) {
306 if ($aria_role == Bulky::MENUITEM) {
307 $tpl->touchBlock("with_aria_haspopup");
308 } else {
309 //Note that aria-role='menuitems MUST-NOT have Aria-pressed to true;
310 $tpl->setCurrentBlock("with_aria_pressed");
311 if ($component->isEngaged()) {
312 $tpl->setVariable("ARIA_PRESSED", "true");
313 } else {
314 $tpl->setVariable("ARIA_PRESSED", "false");
315 }
316 $tpl->parseCurrentBlock();
317 }
318 }
319 }
320
324 protected function getComponentInterfaceName()
325 {
326 return array(Component\Button\Primary::class
327 , Component\Button\Standard::class
328 , Component\Button\Close::class
329 , Component\Button\Shy::class
330 , Component\Button\Month::class
331 , Component\Button\Tag::class
332 , Component\Button\Bulky::class
333 , Component\Button\Toggle::class
334 );
335 }
336}
An exception for terminatinating execution or to throw for unit testing.
additionalRenderBulky(Component\Button\Button $component, RendererInterface $default_renderer, $tpl)
Definition: Renderer.php:290
registerResources(\ILIAS\UI\Implementation\Render\ResourceRegistry $registry)
Definition: Renderer.php:139
renderToggle(Component\Button\Toggle $component)
Definition: Renderer.php:158
maybeRenderId(Component\JavaScriptBindable $component, $tpl)
Definition: Renderer.php:226
additionalRenderTag(Component\Button\Tag $component, $tpl)
Definition: Renderer.php:271
renderButton(Component\Button\Button $component, RendererInterface $default_renderer)
Definition: Renderer.php:42
getComponentInterfaceName()
Get the name of the component-interface this renderer is supposed to render.ATTENTION: Fully qualifie...
Definition: Renderer.php:324
renderMonth(Component\Button\Month $component, RendererInterface $default_renderer)
Definition: Renderer.php:236
getTemplate($name, $purge_unfilled_vars, $purge_unused_blocks)
Get template of component this renderer is made for.
bindJavaScript(JavaScriptBindable $component)
Bind the component to JavaScript.
checkComponent(Component $component)
Check if a given component fits this renderer and throw \LogicError if that is not the case.
toJS($key)
Add language var to client side (il.Language)
A component is the most general form of an entity in the UI.
Definition: Component.php:14
Interface to be extended by components that have the possibility to bind to Javascript.
render(Component $component, Renderer $default_renderer)
Render the component if possible and delegate additional rendering to the default_renderer.
An entity that renders components to a string output.
Definition: Renderer.php:15
if($DIC->http() ->request() ->getMethod()=="GET" &&isset($DIC->http() ->request() ->getQueryParams()['tex'])) $tpl
Definition: latex.php:41
$i
Definition: metadata.php:24
trait LoadingAnimationOnClick
Implements LoadingAnimationOnClick interface.
Class ChatMainBarProvider \MainMenu\Provider.
Class Factory.