Version 1
[yaffs-website] / web / modules / contrib / slick / slick.api.php
1 <?php
2
3 /**
4  * @file
5  * Hooks and API provided by the Slick module.
6  *
7  * Modules may implement any of the available hooks to interact with Slick.
8  */
9
10 /**
11  * Slick may be configured using the web interface via sub-modules.
12  *
13  * However below is a few sample coded ones. The simple API is to achieve
14  * consistent markups working for various skins, and layouts for both coded
15  * and sub-modules implementations.
16  *
17  * The expected parameters are:
18  *   - items: A required array of slick contents: text, image or media.
19  *   - options: An optional array of key:value pairs of custom JS options.
20  *   - optionset: An optional optionset object to avoid multiple invocations.
21  *   - settings: An array of key:value pairs of HTML/layout related settings.
22  *
23  * @see \Drupal\slick\Plugin\Field\FieldFormatter\SlickImageFormatter
24  * @see \Drupal\slick_views\Plugin\views\style\SlickViews
25  */
26
27 /**
28  * Quick sample #1.
29  *
30  * @see \Drupal\slick\SlickManager::build()
31  * @see template_preprocess_slick_wrapper()
32  * @see template_preprocess_slick()
33  *
34  * @return array
35  *   The renderable array of a slick instance.
36  */
37 function my_module_render_slick() {
38   // Invoke the plugin class, or use a DI service container accordingly.
39   $slick = \Drupal::service('slick.manager');
40
41   // Access the formatter service for image-related methods:
42   $formatter = \Drupal::service('slick.formatter');
43
44   $build = [];
45
46   // Caption contains: alt, data, link, overlay, title.
47   // Each item has keys: slide, caption, settings.
48   $items[] = [
49     // Use $formatter->getImage($element) to have lazyLoad where $element
50     // contains:
51     // item: Drupal\image\Plugin\Field\FieldType\ImageItem.
52     'slide'   => '<img src="https://drupal.org/files/One.gif" />',
53     'caption' => ['title' => t('Description #1')],
54   ];
55
56   $items[] = [
57     'slide'   => '<img src="https://drupal.org/files/Two.gif" />',
58     'caption' => ['title' => t('Description #2')],
59   ];
60
61   $items[] = [
62     'slide'   => '<img src="https://drupal.org/files/Three.gif" />',
63     'caption' => ['title' => t('Description #3')],
64   ];
65
66   // Pass the $items to the array.
67   $build['items'] = $items;
68
69   // If no optionset name is provided via $build['settings'], slick will
70   // fallback to 'default'.
71   // Optionally override 'default' optionset with custom JS options.
72   $build['options'] = [
73     'autoplay' => TRUE,
74     'dots'     => TRUE,
75     'arrows'   => FALSE,
76   ];
77
78   // Build the slick.
79   $element = $slick->build($build);
80
81   // Prepare $variables to pass into a .twig.html file.
82   $variables['slick'] = $element;
83
84   // Render the slick at a .twig.html file.
85   // {{ slick }}
86   // Or simply return the $element if a renderable array is expected.
87   return $element;
88 }
89
90 /**
91  * Detailed sample #2.
92  *
93  * This can go to some hook_preprocess() of a target html.twig, or any relevant
94  * PHP file.
95  *
96  * The goal is to create a vertical newsticker, or tweets, with pure text only.
97  * First, create an unformatted Views block, says 'Ticker' containing ~ 10
98  * titles, or any data for the contents -- using EFQ, or static array will do.
99  *
100  * @return array
101  *   The renderable array of a slick instance.
102  */
103 function my_module_render_slick_detail() {
104   // Invoke the plugin class, or use a DI service container accordingly.
105   $slick = \Drupal::service('slick.manager');
106
107   // Access the formatter service for image related methods:
108   $formatter = \Drupal::service('slick.formatter');
109
110   $build = [];
111
112   // 1.
113   // Optional $settings, can be removed.
114   // Provides HTML settings with optionset name and ID, none of JS related.
115   // To add JS key:value pairs, use #options below instead.
116   // @see \Drupal\slick\SlickDefault for most supported settings.
117   $build['settings'] = [
118     // Optional optionset name, otherwise fallback to default.
119     // 'optionset' => 'blog',
120     // Optional skin name fetched from hook_slick_skins_info(), otherwise none.
121     // 'skin' => 'fullwidth',
122     // Define the main ID. The rest are managed by the module.
123     // If you provide ID, be sure unique per instance as it is cached.
124     // Leave empty to be provided by the module.
125     'id' => 'slick-ticker',
126
127     // Define the cache max-age, default to -1 (Cache::PERMANENT) to permanently
128     // cache the results. Hence a 1 hour is passed. Be sure it is an integer!
129     'cache' => 3600,
130   ];
131
132   // 3.
133   // Obligatory #items, as otherwise empty slick.
134   // Prepare #items contents, note the 'slide' key is to hold the actual slide
135   // which can be pure and simple text, or any image/media file.
136   // Meaning $rows can be text only, or image/audio/video, or a combination
137   // of both.
138   // To add caption/overlay, use 'caption' key with the supported sub-keys:
139   // alt, data, link, overlay, title for complex content.
140   // Sanitize each sub-key content accordingly.
141   // @see template_preprocess_slick_slide() for more info.
142   $items = [];
143   foreach ($rows as $key => $row) {
144     // Each item has keys: slide, caption, settings.
145     $items[] = [
146       'slide' => $row,
147
148       // Optional caption contains: alt, data, link, overlay, title.
149       // If the above slide is an image, to add text caption, use:
150       'caption' => ['title' => 'some-caption data'],
151
152       // Optional slide settings to manipulate layout, can be removed.
153       // Individual slide supports some useful settings like layout, classes,
154       // etc.
155       // Meaning each slide can have different layout, or classes.
156       // @see src/Plugin/Field/README.txt
157       'settings' => [
158
159         // Optionally add a custom layout, can be a static uniform value, or
160         // dynamic one based on the relevant field value.
161         // @see src/Plugin/Field/README.txt for the supported layout keys.
162         'layout' => 'bottom',
163
164         // Optionally add a custom class, can be a static uniform class, or
165         // dynamic one based on the relevant field value.
166         'class' => 'slide--custom-class--' . $key,
167       ],
168     ];
169   }
170
171   // Pass the $items to the array.
172   $build['items'] = $items;
173
174   // 4.
175   // Optional specific JS options, to re-use one optionset, can be removed.
176   // Play with speed and options to achieve desired result.
177   // @see config/install/slick.optionset.default.yml
178   $build['options'] = [
179     'arrows'    => FALSE,
180     'autoplay'  => TRUE,
181     'vertical'  => TRUE,
182     'draggable' => FALSE,
183   ];
184
185   // 5.
186   // Build the slick with the arguments as described above.
187   $element = $slick->build($build);
188
189   // Prepare $variables to pass into a .twig.html file.
190   $variables['slick'] = $element;
191
192   // Render the slick at a .twig.html file.
193   // {{ slick }}
194   // Or simply return the $element if a renderable array is expected.
195   return $element;
196 }
197
198 /**
199  * AsNavFor sample #3.
200  *
201  * The only requirement for asNavFor is:
202  * @code
203  *   $build['settings']['optionset'] = 'optionset_name';
204  *   $build['settings']['optionset_thumbnail'] = 'optionset_thumbnail_name';
205  * @endcode
206  *
207  * The rest are optional, and will fallback to default:
208  *   - $build['settings']['optionset_thumbnail'] = 'optionset_thumbnail_name';
209  *     Defined at the main settings.
210  *
211  *   - $build['settings']['id'] = 'slick-asnavfor';
212  *     Only main display ID is needed. The thumbnail ID will be
213  *     automatically created: 'slick-asnavfor-thumbnail', including the content
214  *     attributes accordingly. If none provided, will fallback to incremented
215  *     ID.
216  *
217  * See the HTML structure below to get a clear idea.
218  *
219  * 1. Main slider:
220  * \n @code
221  *   <div id="slick-asnavfor" class="slick">
222  *     <div class="slick__slider slick-initialized slick-slider">
223  *       <div class="slick__slide"></div>
224  *     </div>
225  *   </div>
226  * @endcode \n
227  * 2. Thumbnail slider:
228  * \n @code
229  *   <div id="slick-asnavfor-thumbnail" class="slick">
230  *     <div class="slick__slider slick-initialized slick-slider">
231  *       <div class="slick__slide"></div>
232  *     </div>
233  *   </div>
234  * @endcode \n
235  * The asnavfor targets are the 'slick-initialized' attributes, and managed by
236  * the module automatically when using SlickManager::build().
237  *
238  * @return array
239  *   The renderable array of slick instances.
240  */
241 function my_module_render_slick_asnavfor() {
242   // Invoke the plugin class, or use a DI service container accordingly.
243   $slick = \Drupal::service('slick.manager');
244
245   // Access the formatter service for image related methods:
246   $formatter = \Drupal::service('slick.formatter');
247
248   $build = [];
249
250   // 1. Main slider ------------------------------------------------------------
251   // Add the main display items.
252   $build['items'] = [];
253
254   // Use theme_slick_image to have lazyLoad, or theme_image_style/theme_image.
255   $images = [1, 2, 3, 4, 6, 7];
256   foreach ($images as $key) {
257     // Each item has keys: slide, caption, settings.
258     $build['items'][] = [
259
260       // Use $formatter->getImage($element) to have lazyLoad where $element
261       // contains:
262       // item: Drupal\image\Plugin\Field\FieldType\ImageItem.
263       'slide'   => '<img src="/sites/all/images/image-0' . $key . '.jpg" width="1140" />',
264
265       // Main caption contains: alt, data, link, overlay, title keys which serve
266       // the purpose to have consistent markups and skins without bothering much
267       // nor remembering what HTML tags and where to place to provide for each
268       // purpose cosnsitently. CSS will do layout regardless HTML composition.
269       // If having more complex caption data, use 'data' key instead.
270       // If the common layout doesn't satisfy the need, just override the twig.
271       'caption' => ['title' => 'Description #' . $key],
272     ];
273   }
274
275   // Optionally override the optionset.
276   $build['options'] = [
277     'arrows'        => FALSE,
278     'centerMode'    => TRUE,
279     'centerPadding' => '',
280   ];
281
282   // Satisfy the asnavfor main settings.
283   // @see \Drupal\slick\SlickDefault for most supported settings.
284   $build['settings'] = [
285     // The only required is 'optionset_thumbnail'.
286     // Define both main and thumbnail optionset names once at the main display.
287     'optionset' => 'optionset_main_name',
288     'optionset_thumbnail' => 'optionset_thumbnail_name',
289
290     // The rest is optional, just FYI.
291     'id' => 'slick-asnavfor',
292     'skin' => 'skin-main-name',
293     'skin_thumbnail' => 'skin-thumbnail-name',
294   ];
295
296   // 2. Thumbnail slider -------------------------------------------------------
297   // The thumbnail array is grouped by 'thumb'.
298   $build['thumb'] = ['items' => []];
299   foreach ($images as $key) {
300     // Each item has keys: slide, caption, settings.
301     $build['thumb']['items'][] = [
302       // Use $formatter->getThumbnail($settings) where $settings contain:
303       // uri, image_style, height, width, alt, title.
304       'slide'   => '<img src="/sites/all/images/image-0' . $key . '.jpg" width="210" />',
305
306       // Thumbnail caption accepts direct markup or custom renderable array
307       // without any special key to be simple as much as complex.
308       // Think Youtube playlist with scrolling navigation: thumbnail, text, etc.
309       'caption' => ['#markup' => 'Description #' . $key],
310     ];
311   }
312
313   // Optionally override 'optionset_thumbnail_name' with custom JS options.
314   $build['thumb']['options'] = [
315     'arrows'        => TRUE,
316     'centerMode'    => TRUE,
317     'centerPadding' => '10px',
318
319     // Be sure to have multiple slides for the thumbnail, otherwise nonsense.
320     'slidesToShow'  => 5,
321   ];
322
323   // Build the slick once.
324   $element = $slick->build($build);
325
326   // Prepare variables to pass into a .twig.html file.
327   $variables['slick'] = $element;
328
329   // Render the slick at a .twig.html file.
330   // {{ slick }}
331   // Or simply return the $element if a renderable array is expected.
332   return $element;
333 }
334
335 /**
336  * Implements hook_slick_skins_info().
337  *
338  * Registers a class that should hold skin definitions and implements
339  * \Drupal\slick\SlickSkinInterface.
340  *
341  * @deprecated, will be removed anytime when a core solution is available.
342  * @see #2233261
343  * Postponed till D9.
344  *
345  * @see slick_hook_info()
346  * @see slick_example.module
347  * @see slick_extras.module
348  * @see \Drupal\slick\SlickSkinInterface
349  */
350 function hook_slick_skins_info() {
351   return '\Drupal\hook\HookSlickSkin';
352 }
353
354 /**
355  * Implements SlickSkinInterface as registered via hook_slick_skins_info().
356  *
357  * The class must implement \Drupal\slick\SlickSkinInterface, and it has 3
358  * supported methods: ::skins(), ::dots(), ::arrows() to have skin options for
359  * main/thumbnail/overlay/nested displays, dots, and arrows skins respectively.
360  * The declared skins will be available for custom coded, or UI selections.
361  */
362 class HookSlickSkin implements SlickSkinInterface {
363
364   /**
365    * {@inheritdoc}
366    */
367   public function skins() {
368     $theme_path = base_path() . drupal_get_path('theme', 'my_theme');
369
370     return [
371       'skin_name' => [
372         // Human readable skin name.
373         'name' => 'Skin name',
374         // Description of the skin.
375         'description' => t('Skin description.'),
376         // To reduce confusion on form selection: main, thumbnail.
377         'group' => 'main',
378         // Optional module name to prefix the library name.
379         'provider' => 'my_module',
380         'css' => [
381           'theme' => [
382             // Full path to a CSS file to include with the skin.
383             $theme_path . '/css/my-theme--slider.css' => [],
384             $theme_path . '/css/my-theme--carousel.css' => [],
385           ],
386         ],
387         'js' => [
388           // Full path to a JS file to include with the skin.
389           $theme_path . '/js/my-theme--slider.js' => [],
390           $theme_path . '/js/my-theme--carousel.js' => [],
391           // If you want to act on afterSlick event, or any other slick events,
392           // put a lighter weight before slick.load.min.js (0).
393           $theme_path . '/js/slick.skin.menu.min.js' => ['weight' => -2],
394         ],
395       ],
396     ];
397   }
398
399   /**
400    * Returns the Slick dot skins.
401    *
402    * The provided dot skins will be available at sub-module UI form.
403    * A skin dot named 'hop' will have a class 'slick-dots--hop' for the UL.
404    *
405    * The array is similar to the self::skins(), excluding group, JS.
406    *
407    * @return array
408    *   The array of the dot skins.
409    */
410   public function dots() {
411     // Create an array of dot skins.
412     return [];
413   }
414
415   /**
416    * Returns the Slick arrow skins.
417    *
418    * The provided arrow skins will be available at sub-module UI form.
419    * A skin arrow 'slit' will have a class 'slick__arrow--slit' for the NAV.
420    *
421    * The array is similar to the self::skins(), excluding group, JS.
422    *
423    * @return array
424    *   The array of the arrow skins.
425    */
426   public function arrows() {
427     // Create an array of arrow skins.
428     return [];
429   }
430
431 }