From 344a46df50fff96d73039b2fe72d1d0ee9cef57a Mon Sep 17 00:00:00 2001 From: Bigi Lui Date: Sat, 15 Apr 2017 15:39:44 -0700 Subject: [PATCH] Adding new UI plugin: Carousel --- PicoUICarousel.php | 199 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 PicoUICarousel.php diff --git a/PicoUICarousel.php b/PicoUICarousel.php new file mode 100644 index 0000000..aff18d6 --- /dev/null +++ b/PicoUICarousel.php @@ -0,0 +1,199 @@ +config['loadJquery'] = false; + $this->config['jqueryUrl'] = '//cdn.jsdelivr.net/jquery/3.2.1/jquery.min.js'; + $this->config['slickPath'] = '//cdn.jsdelivr.net/jquery.slick/1.6.0'; + $this->config['carouselRatio'] = '2.35:1'; + $this->config['carouselText'] = ''; + // load custom config if needed + if (isset($config['PicoUICarousel.loadJquery'])) { + $this->config['loadJquery'] = $config['PicoUICarousel.loadJquery']; + } + if (isset($config['PicoUICarousel.jqueryUrl'])) { + $this->config['jqueryUrl'] = $config['PicoUICarousel.jqueryUrl']; + } + if (isset($config['PicoUICarousel.slickPath'])) { + $this->config['slickPath'] = $config['PicoUICarousel.slickPath']; + } + if (isset($config['PicoUICarousel.carouselRatio'])) { + $this->config['carouselRatio'] = $config['PicoUICarousel.carouselRatio']; + } + if (isset($config['PicoUICarousel.cssClass.carouselText'])) { + $this->config['carouselText'] = $config['PicoUICarousel.cssClass.carouselText']; + } + // some postprocessing of config + list($cWidth, $cHeight) = explode(':', $this->config['carouselRatio']); + $this->config['heightMultiplier'] = max(0.01, min(floatval($cHeight) / floatval($cWidth), 10)) * 100; + } + + /** + * Triggered after Pico has prepared the raw file contents for parsing + * + * @see Pico::parseFileContent() + * @see DummyPlugin::onContentParsed() + * @param string &$content prepared file contents for parsing + * @return void + */ + public function onContentPrepared(&$content) + { + // we only do any processing at all if the page contains our tag, so we save time + if (strpos($content, '[ui.carousel') !== false) { + // below is our comprehensive regex to detect for the full [ui.card] tag, + // which includes the tag and its attributes, and the [title] and [text] subtags. + $config = $this->config; + $content = preg_replace_callback( + '/\[ui\.carousel((\s+[a-z]+\=[\'\"][^\'\"]*[\'\"])*)\s*\]\s*((\[slide((\s+[a-z]+\=[\'\"][^\'\"]*[\'\"])*)\s*\][^\[]*\[\/slide\]\s*)*)\[\/ui\.carousel\s*\]/', + function ($matches) use ($config) { + // $matches[1] contain the list of attributes + // $matches[3] contain the list of subtags + preg_match_all('/\s*([a-z]+)\=[\'\"]([^\'\"]*)[\'\"]/', $matches[1], $attributes); + // look for what we want from parent attributes + $carousel = array('ratio' => ''); + for ($i = 0; $i < count($attributes[0]); $i++) { + $carousel[ $attributes[1][$i] ] = $attributes[2][$i]; + } + if (!empty($carousel['ratio'])) { + list($cWidth, $cHeight) = explode(':', $carousel['ratio']); + $ratio = 'padding-bottom: '.(max(0.01, min(floatval($cHeight) / floatval($cWidth), 10)) * 100).'%;'; + $spacer = 'height: '.(max(0.01, min(floatval($cHeight) / floatval($cWidth), 10)) * 100).'vw;'; + } else { + // default + $ratio = ''; + $spacer = ''; + } + preg_match_all('/\[slide((\s+[a-z]+\=[\'\"][^\'\"]*[\'\"])*)\s*\]([^\[]*)\[\/slide\]\s*/', $matches[3], $rawSlides); + $slides = array(); + for ($i = 0; $i < count($rawSlides[0]); $i++) { + // $rawSlides[1][*] contain the list of attributes + // $rawSlides[3][*] contain the title text + $slides[$i] = array(); + $slides[$i]['text'] = $rawSlides[3][$i]; + preg_match_all('/\s*([a-z]+)\=[\'\"]([^\'\"]*)[\'\"]/', $rawSlides[1][$i], $slideAttributes); + for ($k = 0; $k < count($slideAttributes[0]); $k++) { + $slides[$i][ $slideAttributes[1][$k] ] = $slideAttributes[2][$k]; + } + } + + $result = ''; + // Pico's MD parsing wants this tag on the next line for some reaasons. + $result .= PHP_EOL.''; + return PHP_EOL.$result.PHP_EOL; + }, + $content); + } + } + + /** + * Triggered after Pico has rendered the page + * + * @param string &$output contents which will be sent to the user + * @return void + */ + public function onPageRendered(&$output) + { + // regular pages + // add css to end of + $output = str_replace('', ($this->buildExtraHeaders() . ''), $output); + // add js to end of + $output = str_replace('', ($this->buildExtraFooters() . ''), $output); + } + + /** + * Add some extra header tags for our styling. + */ + private function buildExtraHeaders() { + $headers = PHP_EOL.''; + $headers .= PHP_EOL.''; + // now set up card css classes + $headers .= ' + +'; + return $headers; + } + + /** + * Add some extra footer tags we need. + */ + private function buildExtraFooters() { + $footers = ''; + // if set to true, load from jquery cdn + if ($this->config['loadJquery'] === true) { + $footers .= PHP_EOL.''; + } + $footers .= PHP_EOL.''; + $footers .= ' + +'; + return $footers; + } +}