/** * Process a Link excerpt * * @param $excerpt * @param $page * @param string $type * @return mixed */ public static function processLinkExcerpt($excerpt, $page, $type = 'link') { $url = $excerpt['element']['attributes']['href']; $url_parts = parse_url(htmlspecialchars_decode(urldecode($url))); // if there is a query, then parse it and build action calls if (isset($url_parts['query'])) { $actions = array_reduce(explode('&', $url_parts['query']), function ($carry, $item) { $parts = explode('=', $item, 2); $value = isset($parts[1]) ? rawurldecode($parts[1]) : true; $carry[$parts[0]] = $value; return $carry; }, []); // valid attributes supported $valid_attributes = ['rel', 'target', 'id', 'class', 'classes']; // Unless told to not process, go through actions if (array_key_exists('noprocess', $actions)) { unset($actions['noprocess']); } else { // loop through actions for the image and call them foreach ($actions as $attrib => $value) { $key = $attrib; if (in_array($attrib, $valid_attributes)) { // support both class and classes if ($attrib == 'classes') { $attrib = 'class'; } $excerpt['element']['attributes'][$attrib] = str_replace(',', ' ', $value); unset($actions[$key]); } } } $url_parts['query'] = http_build_query($actions, null, '&', PHP_QUERY_RFC3986); } // if no query elements left, unset query if (empty($url_parts['query'])) { unset($url_parts['query']); } // set path to / if not set if (empty($url_parts['path'])) { $url_parts['path'] = ''; } // if special scheme, just return if (isset($url_parts['scheme']) && !Utils::startsWith($url_parts['scheme'], 'http')) { return $excerpt; } // handle paths and such $url_parts = Uri::convertUrl($page, $url_parts, $type); // build the URL from the component parts and set it on the element $excerpt['element']['attributes']['href'] = Uri::buildUrl($url_parts); return $excerpt; }
protected function inlineLink($excerpt) { if (isset($excerpt['type'])) { $type = $excerpt['type']; } else { $type = 'link'; } // do some trickery to get around Parsedown requirement for valid URL if its Twig in there if (preg_match($this->twig_link_regex, $excerpt['text'], $matches)) { $excerpt['text'] = str_replace($matches[1], '/', $excerpt['text']); $excerpt = parent::inlineLink($excerpt); $excerpt['element']['attributes']['href'] = $matches[1]; $excerpt['extent'] = $excerpt['extent'] + strlen($matches[1]) - 1; return $excerpt; } else { $excerpt = parent::inlineLink($excerpt); } // if this is a link if (isset($excerpt['element']['attributes']['href'])) { $url = parse_url(htmlspecialchars_decode($excerpt['element']['attributes']['href'])); // if there is no scheme, the file is local if (!isset($url['scheme']) && count($url) > 0) { // convert the URl is required $excerpt['element']['attributes']['href'] = Uri::convertUrl($this->page, Uri::buildUrl($url), $type); } } return $excerpt; }
protected function inlineLink($excerpt) { if (isset($excerpt['type'])) { $type = $excerpt['type']; } else { $type = 'link'; } // do some trickery to get around Parsedown requirement for valid URL if its Twig in there if (preg_match($this->twig_link_regex, $excerpt['text'], $matches)) { $excerpt['text'] = str_replace($matches[1], '/', $excerpt['text']); $excerpt = parent::inlineLink($excerpt); $excerpt['element']['attributes']['href'] = $matches[1]; $excerpt['extent'] = $excerpt['extent'] + strlen($matches[1]) - 1; return $excerpt; } else { $excerpt = parent::inlineLink($excerpt); } // if this is a link if (isset($excerpt['element']['attributes']['href'])) { $url = parse_url(htmlspecialchars_decode($excerpt['element']['attributes']['href'])); // if there is a query, then parse it and build action calls if (isset($url['query'])) { $actions = array_reduce(explode('&', $url['query']), function ($carry, $item) { $parts = explode('=', $item, 2); $value = isset($parts[1]) ? $parts[1] : true; $carry[$parts[0]] = $value; return $carry; }, []); // valid attributes supported $valid_attributes = ['rel', 'target', 'id', 'class', 'classes']; // Unless told to not process, go through actions if (array_key_exists('noprocess', $actions)) { unset($actions['noprocess']); } else { // loop through actions for the image and call them foreach ($actions as $attrib => $value) { $key = $attrib; if (in_array($attrib, $valid_attributes)) { // support both class and classes if ($attrib == 'classes') { $attrib = 'class'; } $excerpt['element']['attributes'][$attrib] = str_replace(',', ' ', $value); unset($actions[$key]); } } } $url['query'] = http_build_query($actions, null, '&', PHP_QUERY_RFC3986); } // if no query elements left, unset query if (empty($url['query'])) { unset($url['query']); } // if there is no scheme, the file is local and we'll need to convert that URL if (!isset($url['scheme']) && count($url) > 0) { $excerpt['element']['attributes']['href'] = Uri::convertUrl($this->page, Uri::buildUrl($url), $type, true); } else { $excerpt['element']['attributes']['href'] = Uri::buildUrl($url); } } return $excerpt; }
/** * Execute shortcode. * * @param Event $event An event object. * @return string|null Return modified contents. */ public function execute(Event $event) { /* @var \Grav\Common\Grav $grav */ $grav = $event['grav']; /* @var \Grav\Plugin\Shortcodes\Shortcodes $shortcodes */ $shortcodes = $event['shortcodes']; /* @var \Grav\Common\Data\Data $options */ $options = $event['options']; $options->setDefaults($this->defaults); $type = strtolower($options->get('type')); $body = trim(strip_tags($event['body'], '<link><script>')); if ($options->get('inline')) { $shortcodes->addExtra('assets', 'addInline' . ucfirst($type), $body); } else { /* @var \Grav\Common\Page\Page $page */ $page = $event['page']; /* @var UniformResourceLocator $locator */ $locator = $grav['locator']; /* @var Uri $uri */ $uri = $grav['uri']; $priority = $options->get('priority', 10); $pipeline = $options->get('pipeline', false); $loading = $options->get('load', ''); $entries = explode("\n", $body); $name = $type === 'css' ? 'addCss' : 'addJs'; foreach ($entries as $entry) { $url = $before = trim($entry, " \t"); // Don't process protocol agnostic or external URLs if (!$grav['uri']->isExternal($url) && substr($url, 0, 2) !== '//') { if (false !== strpos($url, '://')) { // Get relative path to the resource (or false if not found). if ($resource = $locator->findResource($url, false)) { $url = rtrim($uri->rootUrl(false), '/') . '/' . $resource; } } else { // Resolve URL (relative or absolute with respect to current page) $url = Uri::convertUrl($page, $url); } if (false === strpos($url, '://')) { $url = preg_replace('~^' . preg_quote($uri->rootUrl(false)) . '~i', '', $url); $url = rtrim($uri->rootUrl(true), '/') . $url; } } $shortcodes->addExtra('assets', $name, [$url, $priority, $pipeline, $loading]); } } }