ILIAS  release_7 Revision v7.30-3-g800a261c036
All Data Structures Namespaces Files Functions Variables Modules Pages
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 
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 }
registerResources(\ILIAS\UI\Implementation\Render\ResourceRegistry $registry)
Definition: Renderer.php:139
Class Factory.
checkComponent(Component $component)
Check if a given component fits this renderer and throw if that is not the case. ...
Class ChatMainBarProvider .
additionalRenderBulky(Component\Button\Button $component, RendererInterface $default_renderer, $tpl)
Definition: Renderer.php:290
maybeRenderId(Component\JavaScriptBindable $component, $tpl)
Definition: Renderer.php:226
toJS($key)
Add language var to client side (il.Language)
renderToggle(Component\Button\Toggle $component)
Definition: Renderer.php:158
renderButton(Component\Button\Button $component, RendererInterface $default_renderer)
Definition: Renderer.php:42
renderMonth(Component\Button\Month $component, RendererInterface $default_renderer)
Definition: Renderer.php:236
render(Component $component, Renderer $default_renderer)
Render the component if possible and delegate additional rendering to the default_renderer.
if($DIC->http() ->request() ->getMethod()=="GET" &&isset($DIC->http() ->request() ->getQueryParams()['tex'])) $tpl
Definition: latex.php:41
getTemplate($name, $purge_unfilled_vars, $purge_unused_blocks)
Get template of component this renderer is made for.
additionalRenderTag(Component\Button\Tag $component, $tpl)
Definition: Renderer.php:271
$i
Definition: metadata.php:24
bindJavaScript(JavaScriptBindable $component)
Bind the component to JavaScript.