diff --git a/CHANGELOG.md b/CHANGELOG.md index 992889e48..c830c70e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,14 @@ +# v1.7.28 +## mm/dd/2022 + +1. [](#new) + * Added links and modules support to `HtmlBlock` class + # v1.7.27.1 ## 01/12/2022 3. [](#bugfix) - * Fixed a typo in CSS Asset pipeline that was erroneously joining files with `;` + * Fixed a typo in CSS Asset pipeline that was erroneously joining files with `;` # v1.7.27 ## 01/12/2022 diff --git a/system/src/Grav/Framework/ContentBlock/HtmlBlock.php b/system/src/Grav/Framework/ContentBlock/HtmlBlock.php index 734d5077f..71cd9367f 100644 --- a/system/src/Grav/Framework/ContentBlock/HtmlBlock.php +++ b/system/src/Grav/Framework/ContentBlock/HtmlBlock.php @@ -29,6 +29,8 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface /** @var array */ protected $scripts = []; /** @var array */ + protected $links = []; + /** @var array */ protected $html = []; /** @@ -40,6 +42,7 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface $this->sortAssets($assets['styles']); $this->sortAssets($assets['scripts']); + $this->sortAssets($assets['links']); $this->sortAssets($assets['html']); return $assets; @@ -73,6 +76,15 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface return $this->getAssetsInLocation('scripts', $location); } + /** + * @param string $location + * @return array + */ + public function getLinks($location = 'head') + { + return $this->getAssetsInLocation('links', $location); + } + /** * @param string $location * @return array @@ -98,6 +110,9 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface if ($this->scripts) { $array['scripts'] = $this->scripts; } + if ($this->links) { + $array['links'] = $this->links; + } if ($this->html) { $array['html'] = $this->html; } @@ -117,6 +132,7 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface $this->frameworks = isset($serialized['frameworks']) ? (array) $serialized['frameworks'] : []; $this->styles = isset($serialized['styles']) ? (array) $serialized['styles'] : []; $this->scripts = isset($serialized['scripts']) ? (array) $serialized['scripts'] : []; + $this->links = isset($serialized['links']) ? (array) $serialized['links'] : []; $this->html = isset($serialized['html']) ? (array) $serialized['html'] : []; } @@ -229,8 +245,9 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface $src = $element['src']; $type = !empty($element['type']) ? (string) $element['type'] : 'text/javascript'; - $defer = isset($element['defer']); - $async = isset($element['async']); + $loading = !empty($element['loading']) ? (string) $element['loading'] : null; + $defer = !empty($element['defer']); + $async = !empty($element['async']); $handle = !empty($element['handle']) ? (string) $element['handle'] : ''; $this->scripts[$location][md5($src) . sha1($src)] = [ @@ -238,6 +255,7 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface ':priority' => (int) $priority, 'src' => $src, 'type' => $type, + 'loading' => $loading, 'defer' => $defer, 'async' => $async, 'handle' => $handle @@ -266,12 +284,80 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface $content = (string) $element['content']; $type = !empty($element['type']) ? (string) $element['type'] : 'text/javascript'; + $loading = !empty($element['loading']) ? (string) $element['loading'] : null; $this->scripts[$location][md5($content) . sha1($content)] = [ ':type' => 'inline', ':priority' => (int) $priority, 'content' => $content, - 'type' => $type + 'type' => $type, + 'loading' => $loading + ]; + + return true; + } + + /** + * @param string|array $element + * @param int $priority + * @param string $location + * @return bool + */ + public function addModule($element, $priority = 0, $location = 'head') + { + if (!is_array($element)) { + $element = ['src' => (string) $element]; + } + + $element['type'] = 'module'; + + return $this->addScript($element, $priority, $location); + } + + /** + * @param string|array $element + * @param int $priority + * @param string $location + * @return bool + */ + public function addInlineModule($element, $priority = 0, $location = 'head') + { + if (!is_array($element)) { + $element = ['content' => (string) $element]; + } + + $element['type'] = 'module'; + + return $this->addInlineScript($element, $priority, $location); + } + + /** + * @param array $element + * @param int $priority + * @param string $location + * @return bool + */ + public function addLink($element, $priority = 0, $location = 'head') + { + if (!is_array($element) || empty($element['rel']) || empty($element['href'])) { + return false; + } + + if (!isset($this->links[$location])) { + $this->links[$location] = []; + } + + $rel = (string) $element['rel']; + $href = (string) $element['href']; + + unset($element['rel'], $element['href']); + + $this->links[$location][md5($href) . sha1($href)] = [ + ':type' => 'file', + ':priority' => (int) $priority, + 'href' => $href, + 'rel' => $rel, + 'element' => $element, ]; return true; @@ -309,6 +395,7 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface 'frameworks' => $this->frameworks, 'styles' => $this->styles, 'scripts' => $this->scripts, + 'links' => $this->links, 'html' => $this->html ]; @@ -333,6 +420,14 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface } } + foreach ($blockAssets['links'] as $location => $links) { + if (!isset($assets['links'][$location])) { + $assets['links'][$location] = $links; + } elseif ($links) { + $assets['links'][$location] += $links; + } + } + foreach ($blockAssets['html'] as $location => $htmls) { if (!isset($assets['html'][$location])) { $assets['html'][$location] = $htmls; @@ -391,7 +486,7 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface */ protected function sortAssets(array &$array) { - foreach ($array as $location => &$items) { + foreach ($array as &$items) { $this->sortAssetsInLocation($items); } } diff --git a/system/src/Grav/Framework/ContentBlock/HtmlBlockInterface.php b/system/src/Grav/Framework/ContentBlock/HtmlBlockInterface.php index 686127f45..b151d7b8a 100644 --- a/system/src/Grav/Framework/ContentBlock/HtmlBlockInterface.php +++ b/system/src/Grav/Framework/ContentBlock/HtmlBlockInterface.php @@ -37,6 +37,13 @@ interface HtmlBlockInterface extends ContentBlockInterface */ public function getScripts($location = 'head'); + + /** + * @param string $location + * @return array + */ + public function getLinks($location = 'head'); + /** * @param string $location * @return array @@ -76,7 +83,6 @@ interface HtmlBlockInterface extends ContentBlockInterface */ public function addScript($element, $priority = 0, $location = 'head'); - /** * @param string|array $element * @param int $priority @@ -85,6 +91,35 @@ interface HtmlBlockInterface extends ContentBlockInterface */ public function addInlineScript($element, $priority = 0, $location = 'head'); + + /** + * Shortcut for writing addScript(['type' => 'module', 'src' => ...]). + * + * @param string|array $element + * @param int $priority + * @param string $location + * @return bool + */ + public function addModule($element, $priority = 0, $location = 'head'); + + /** + * Shortcut for writing addInlineScript(['type' => 'module', 'content' => ...]). + * + * @param string|array $element + * @param int $priority + * @param string $location + * @return bool + */ + public function addInlineModule($element, $priority = 0, $location = 'head'); + + /** + * @param array $element + * @param int $priority + * @param string $location + * @return bool + */ + public function addLink($element, $priority = 0, $location = 'head'); + /** * @param string $html * @param int $priority