From e20be9293fe9093c510ea7c7acce8c518e123281 Mon Sep 17 00:00:00 2001 From: Jonathon Menz Date: Sun, 15 Jul 2018 12:44:23 -0700 Subject: [PATCH 1/2] NEW Meta tag components Meta tags can now be individually accessed and modified by key, prior to being rendered and flattened in to a single string. --- code/Model/SiteTree.php | 126 ++++++++++++++++++++++++++++------------ 1 file changed, 89 insertions(+), 37 deletions(-) diff --git a/code/Model/SiteTree.php b/code/Model/SiteTree.php index fb729f8f..5b404c31 100755 --- a/code/Model/SiteTree.php +++ b/code/Model/SiteTree.php @@ -541,7 +541,7 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi if (!($page = DataObject::get_by_id(self::class, $arguments['id'])) // Get the current page by ID. && !($page = Versioned::get_latest_version(self::class, $arguments['id'])) // Attempt link to old version. ) { - return null; // There were no suitable matches at all. + return null; // There were no suitable matches at all. } /** @var SiteTree $page */ @@ -1356,51 +1356,103 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi } /** - * Return the title, description, keywords and language metatags. + * Return attributes for various meta tags, plus a title tag, in a keyed array. + * Array structure corresponds to arguments for HTML::create_tag(). Example: * - * @todo Move tag in separate getter for easier customization and more obvious usage + * $tags['description'] = [ + * // html tag type, if omitted defaults to 'meta' + * 'tag' => 'meta', + * // attributes of html tag + * 'attributes' => [ + * 'name' => 'description', + * 'content' => $this->customMetaDescription(), + * ], + * // content of html tag. (True meta tags don't contain content) + * 'content' => null + * ]; + * + * @see HTML::createTag() + * @return array + */ + public function MetaComponents() + { + $tags = []; + + $tags['title'] = [ + 'tag' => 'title', + 'attributes' => [], + 'content' => $this->obj('Title')->forTemplate() + ]; + + $generator = trim(Config::inst()->get(self::class, 'meta_generator')); + if (!empty($generator)) { + $tags['generator'] = [ + 'attributes' => [ + 'name' => 'generator', + 'content' => $generator, + ], + ]; + } + + $charset = ContentNegotiator::config()->uninherited('encoding'); + $tags['contentType'] = [ + 'attributes' => [ + 'http-equiv' => 'Content-Type', + 'content' => 'text/html; charset=' . $charset, + ], + ]; + if ($this->MetaDescription) { + $tags['description'] = [ + 'attributes' => [ + 'name' => 'description', + 'content' => $this->MetaDescription, + ], + ]; + } + + if (Permission::check('CMS_ACCESS_CMSMain') + && $this->ID > 0 + ) { + $tags['pageId'] = [ + 'attributes' => [ + 'name' => 'x-page-id', + 'content' => $this->ID, + ], + ]; + $tags['cmsEditLink'] = [ + 'attributes' => [ + 'name' => 'x-cms-edit-link', + 'content' => $this->CMSEditLink(), + ], + ]; + } + + $this->extend('MetaComponents', $tags); + + return $tags; + } + + /** + * Return the title, description, keywords and language metatags. * * @param bool $includeTitle Show default <title>-tag, set to false for custom templating * @return string The XHTML metatags */ public function MetaTags($includeTitle = true) { - $tags = array(); - if ($includeTitle && strtolower($includeTitle) != 'false') { - $tags[] = HTML::createTag('title', array(), $this->obj('Title')->forTemplate()); + $tags = []; + $tagsArray = $this->MetaComponents(); + if (!$includeTitle) { + unset($tagsArray['title']); } - $generator = trim(Config::inst()->get(self::class, 'meta_generator')); - if (!empty($generator)) { - $tags[] = HTML::createTag('meta', array( - 'name' => 'generator', - 'content' => $generator, - )); - } - - $charset = ContentNegotiator::config()->uninherited('encoding'); - $tags[] = HTML::createTag('meta', array( - 'http-equiv' => 'Content-Type', - 'content' => 'text/html; charset=' . $charset, - )); - if ($this->MetaDescription) { - $tags[] = HTML::createTag('meta', array( - 'name' => 'description', - 'content' => $this->MetaDescription, - )); - } - - if (Permission::check('CMS_ACCESS_CMSMain') - && $this->ID > 0 - ) { - $tags[] = HTML::createTag('meta', array( - 'name' => 'x-page-id', - 'content' => $this->obj('ID')->forTemplate(), - )); - $tags[] = HTML::createTag('meta', array( - 'name' => 'x-cms-edit-link', - 'content' => $this->obj('CMSEditLink')->forTemplate(), - )); + foreach ($tagsArray as $tagProps) { + $tag = array_merge([ + 'tag' => 'meta', + 'attributes' => [], + 'content' => null, + ], $tagProps); + $tags[] = HTML::createTag($tag['tag'], $tag['attributes'], $tag['content']); } $tagString = implode("\n", $tags); From ed0680a26464dbc37ef35a3abd4e63014e361fd3 Mon Sep 17 00:00:00 2001 From: Maxime Rainville <maxime@silverstripe.com> Date: Fri, 1 Feb 2019 16:00:11 +1300 Subject: [PATCH 2/2] MINOR Add unit test for MetaComponents --- code/Model/SiteTree.php | 3 +- tests/php/Model/SiteTreeTest.php | 51 ++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/code/Model/SiteTree.php b/code/Model/SiteTree.php index 5b404c31..046eba3a 100755 --- a/code/Model/SiteTree.php +++ b/code/Model/SiteTree.php @@ -1380,7 +1380,6 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi $tags['title'] = [ 'tag' => 'title', - 'attributes' => [], 'content' => $this->obj('Title')->forTemplate() ]; @@ -1442,7 +1441,7 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi { $tags = []; $tagsArray = $this->MetaComponents(); - if (!$includeTitle) { + if (!$includeTitle || strtolower($includeTitle) == 'false') { unset($tagsArray['title']); } diff --git a/tests/php/Model/SiteTreeTest.php b/tests/php/Model/SiteTreeTest.php index e914129a..03b85493 100644 --- a/tests/php/Model/SiteTreeTest.php +++ b/tests/php/Model/SiteTreeTest.php @@ -1353,6 +1353,57 @@ class SiteTreeTest extends SapphireTest // Test without title $meta = $page->MetaTags(false); $this->assertNotContains('<title>', $meta); + + $meta = $page->MetaTags('false'); + $this->assertNotContains('<title>', $meta); + } + + public function testMetaComponents() + { + $this->logInWithPermission('ADMIN'); + /** @var SiteTree $page */ + $page = $this->objFromFixture('Page', 'metapage'); + + $charset = Config::inst()->get(ContentNegotiator::class, 'encoding'); + + $expected = [ + 'title' => [ + 'tag' => 'title', + 'content' => "HTML & XML", + ], + 'generator' => [ + 'attributes' => [ + 'name' => 'generator', + 'content' => Config::inst()->get(SiteTree::class, 'meta_generator') + ], + ], + 'contentType' => [ + 'attributes' => [ + 'http-equiv' => 'Content-Type', + 'content' => "text/html; charset=$charset", + ], + ], + 'description' => [ + 'attributes' => [ + 'name' => 'description', + 'content' => 'The <br /> and <br> tags' + ] + ], + 'pageId' => [ + 'attributes' => [ + 'name' => 'x-page-id', + 'content' => $page->ID + ], + ], + 'cmsEditLink' => [ + 'attributes' => [ + 'name' => 'x-cms-edit-link', + 'content' => $page->CMSEditLink() + ] + ] + ]; + + $this->assertEquals($expected, $page->MetaComponents()); } /**