From ff7f4edd80c89545915183beed6abcb3f8a1572e Mon Sep 17 00:00:00 2001 From: Manuel Rojas Date: Tue, 3 Oct 2023 13:12:39 -0600 Subject: [PATCH] style(seo improvements): read more section styling (#26335) * #26262 readmore styling * #26262 Adding readmore styling * #26262 Adding readmore styling * #26262 Adding UI fixes * #26262 Adding UI fixes --- .../html/dot-seo-meta-tags.service.ts | 46 ++++- .../dot-results-seo-tool.component.html | 8 +- .../dot-results-seo-tool.component.scss | 11 +- .../dot-results-seo-tool.component.spec.ts | 190 +++++++++++++++++- .../dot-results-seo-tool.component.ts | 13 +- .../WEB-INF/messages/Language.properties | 32 +++ 6 files changed, 283 insertions(+), 17 deletions(-) diff --git a/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/content/services/html/dot-seo-meta-tags.service.ts b/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/content/services/html/dot-seo-meta-tags.service.ts index 5079373d681e..c0a27ef564d9 100644 --- a/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/content/services/html/dot-seo-meta-tags.service.ts +++ b/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/content/services/html/dot-seo-meta-tags.service.ts @@ -19,11 +19,14 @@ import { SeoMediaKeys, ImageMetaData, OpenGraphOptions, - SEO_TAGS + SEO_TAGS, + SEO_MEDIA_TYPES } from '../dot-edit-content-html/models/meta-tags-model'; @Injectable() export class DotSeoMetaTagsService { + readMoreValues: Record; + constructor( private dotMessageService: DotMessageService, private dotUploadService: DotUploadService @@ -591,6 +594,47 @@ export class DotSeoMetaTagsService { return message.replace(regexPattern, '$&'); } + public getReadMore(): Record { + return { + [SEO_MEDIA_TYPES.FACEBOOK]: [ + this.dotMessageService.get('seo.rules.read-more.facebook.learn'), + this.dotMessageService.get('seo.rules.read-more.facebook.sharing'), + this.dotMessageService.get('seo.rules.read-more.facebook.title'), + this.dotMessageService.get('seo.rules.read-more.facebook.title.unique'), + this.dotMessageService.get('seo.rules.read-more.facebook.title.sizes'), + this.dotMessageService.get('seo.rules.read-more.facebook.og-image'), + this.dotMessageService.get('seo.rules.read-more.facebook.social') + ], + [SEO_MEDIA_TYPES.TWITTER]: [ + this.dotMessageService.get('seo.rules.read-more.twitter.learn'), + this.dotMessageService.get('seo.rules.read-more.twitter.suggest'), + this.dotMessageService.get('seo.rules.read-more.twitter.twitter-card'), + this.dotMessageService.get('seo.rules.read-more.twitter.twitter-title'), + this.dotMessageService.get('seo.rules.read-more.twitter.twitter-title.content'), + this.dotMessageService.get('seo.rules.read-more.twitter.length'), + this.dotMessageService.get('seo.rules.read-more.twitter.twitter-image'), + this.dotMessageService.get('seo.rules.read-more.twitter.twitter-image.aspect'), + this.dotMessageService.get('seo.rules.read-more.twitter.twitter-image.content'), + this.dotMessageService.get('seo.rules.read-more.twitter.twitter-image.social') + ], + [SEO_MEDIA_TYPES.LINKEDIN]: [ + this.dotMessageService.get('seo.rules.read-more.linkedin.learn'), + this.dotMessageService.get('seo.rules.read-more.linkedin.meta'), + this.dotMessageService.get('seo.rules.read-more.linkedin.summary') + ], + [SEO_MEDIA_TYPES.GOOGLE]: [ + this.dotMessageService.get('seo.rules.read-more.google.favicons'), + this.dotMessageService.get('seo.rules.read-more.google.title'), + this.dotMessageService.get('seo.rules.read-more.google.title.unique'), + this.dotMessageService.get('seo.rules.read-more.google.description'), + this.dotMessageService.get('seo.rules.read-more.google.length'), + this.dotMessageService.get('seo.rules.read-more.google.meta-tags'), + this.dotMessageService.get('seo.rules.read-more.google.meta-description'), + this.dotMessageService.get('seo.rules.read-more.google.image-sizes') + ] + }; + } + /** * This uploads the image temporaly to get the file size, only if it is external * @param imageUrl string diff --git a/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/seo/components/dot-results-seo-tool/dot-results-seo-tool.component.html b/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/seo/components/dot-results-seo-tool/dot-results-seo-tool.component.html index 0f50bcccad42..f14b51ae5f50 100644 --- a/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/seo/components/dot-results-seo-tool/dot-results-seo-tool.component.html +++ b/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/seo/components/dot-results-seo-tool/dot-results-seo-tool.component.html @@ -75,10 +75,12 @@
{{ mainPreview.title }}
diff --git a/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/seo/components/dot-results-seo-tool/dot-results-seo-tool.component.scss b/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/seo/components/dot-results-seo-tool/dot-results-seo-tool.component.scss index 89ae6525be8c..b9ce78150525 100644 --- a/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/seo/components/dot-results-seo-tool/dot-results-seo-tool.component.scss +++ b/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/seo/components/dot-results-seo-tool/dot-results-seo-tool.component.scss @@ -87,10 +87,11 @@ display: flex; gap: $spacing-3; color: $black; + align-items: flex-start; } .results-seo-tool__result-card-list li:not(:last-child) { - margin-bottom: $spacing-3; + margin-bottom: $spacing-4; } .results-seo-tool__result-icon { @@ -155,9 +156,17 @@ .results-seo-tool__result-card-list .pi-external-link { color: $color-palette-gray-700; + font-size: $font-size-xs; } .results-seo-tool__main-card .p-card .p-card-body { padding: $spacing-3; } + + .results-seo-tool__read-more-label { + span { + display: inline-flex; + padding: 0 $spacing-0; + } + } } diff --git a/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/seo/components/dot-results-seo-tool/dot-results-seo-tool.component.spec.ts b/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/seo/components/dot-results-seo-tool/dot-results-seo-tool.component.spec.ts index 8a6d31e4b2e8..1917a5555d8d 100644 --- a/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/seo/components/dot-results-seo-tool/dot-results-seo-tool.component.spec.ts +++ b/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/seo/components/dot-results-seo-tool/dot-results-seo-tool.component.spec.ts @@ -54,7 +54,67 @@ describe('DotResultsSeoToolComponent', () => { 'og:image metatag found, but is empty!', 'seo.rules.og-image.over': 'og:image metatag found, but image is over 8 MB.', 'seo.rules.og-image.found': - 'og:image metatag found, with an appropriate sized image!' + 'og:image metatag found, with an appropriate sized image!', + + 'seo.rules.read-more.facebook.learn': + 'Learn more about The Open Graph Protocol. ', + 'seo.rules.read-more.facebook.sharing': + 'Explore the Sharing Debugger - Meta for Developers ', + 'seo.rules.read-more.facebook.title': + 'Ensure that your og:title content is between 55 and 150 characters.', + 'seo.rules.read-more.facebook.title.unique': + 'Keep in mind that your og:title content should be unique across your site.', + 'seo.rules.read-more.facebook.title.sizes': + 'Optimize your og:image sizes to be under 1200 x 630 pixels.', + 'seo.rules.read-more.facebook.og-image': + 'Make sure your og:image file sizes are under 8 MB.', + 'seo.rules.read-more.facebook.social': + 'Read more about social media tile image sizes ', + + 'seo.rules.read-more.twitter.learn': + 'Read more about About Twitter Cards on the Twitter Developer Platform', + 'seo.rules.read-more.twitter.suggest': + 'Suggest using the twitter:card value of summary_large_image for most content, which uses a 16:9 image aspect ratio; this is similar to other social media cards.', + 'seo.rules.read-more.twitter.twitter-card': + 'A twitter:card value of summary corresponds instead to a 1:1 image.', + 'seo.rules.read-more.twitter.twitter-title': + 'twitter:title content should be between 30 and 70 characters.', + 'seo.rules.read-more.twitter.twitter-title.content': + 'twitter:title content should be unique across your site.', + 'seo.rules.read-more.twitter.length': + 'The length of the description allowed will depend on the reader\'s device size; on the smallest size only about 110 characters are allowed. Longer descriptions will show up with some sort of "read more" or "expand" option.', + 'seo.rules.read-more.twitter.twitter-image': + 'twitter:image content should be in JPG, PNG, WEBP, or GIF format.', + 'seo.rules.read-more.twitter.twitter-image.aspect': + 'twitter:image content should use a 16:9 aspect ratio, with a max of 1200 x 675 pixels.', + 'seo.rules.read-more.twitter.twitter-image.content': + 'twitter:image content should be smaller than 5MB.', + 'seo.rules.read-more.twitter.twitter-image.social': + 'Read more about social media tile image sizes ', + + 'seo.rules.read-more.linkedin.learn': + 'LinkedIn’s Post Inspector Tool', + 'seo.rules.read-more.linkedin.meta': + 'Meta Tags: Getting Them Right for LinkedIn. ', + 'seo.rules.read-more.linkedin.summary': + 'Read more about social media tile image sizes ', + + 'seo.rules.read-more.google.favicons': + 'Favicons should be .ico files.', + 'seo.rules.read-more.google.title': + 'HTML Title content should be between 30 and 60 characters.', + 'seo.rules.read-more.google.title.unique': + 'HTML Title content should be unique per page across your site.', + 'seo.rules.read-more.google.description': + 'Meta Description tags should be under 160 characters.', + 'seo.rules.read-more.google.length': + 'The length of the Description allowed will depend on the reader\'s device size; on the smallest size only about 110 characters are allowed. Longer descriptions will show up with some sort of "read more" or "expand" option.', + 'seo.rules.read-more.google.meta-tags': + 'Meta Tags for SEO: A Simple Guide for Beginners ', + 'seo.rules.read-more.google.meta-description': + 'What Are Meta Descriptions And How to Write Them ', + 'seo.rules.read-more.google.image-sizes': + 'Read more about social media tile image sizes' }) } ] @@ -163,4 +223,132 @@ describe('DotResultsSeoToolComponent', () => { expect(resultKeyTitle).toContainText(expectedTitle); expect(resultKeyDescription).toContainText(expectedDescription); }); + + it('should render Readmore for Twitter', () => { + spectator.setInput({ + seoMedia: SEO_MEDIA_TYPES.TWITTER + }); + spectator.detectChanges(); + + const readmore = spectator.queryAll(byTestId('readmore')); + expect(readmore).toExist(); + + expect(readmore[0].innerHTML).toEqual( + 'Read more about About Twitter Cards on the Twitter Developer Platform' + ); + expect(readmore[1].innerHTML).toEqual( + 'Suggest using the twitter:card value of summary_large_image for most content, which uses a 16:9 image aspect ratio; this is similar to other social media cards.' + ); + expect(readmore[2].innerHTML).toEqual( + 'A twitter:card value of summary corresponds instead to a 1:1 image.' + ); + expect(readmore[3].innerHTML).toEqual( + 'twitter:title content should be between 30 and 70 characters.' + ); + expect(readmore[4].innerHTML).toEqual( + 'twitter:title content should be unique across your site.' + ); + expect(readmore[5].innerHTML).toEqual( + 'The length of the description allowed will depend on the reader\'s device size; on the smallest size only about 110 characters are allowed. Longer descriptions will show up with some sort of "read more" or "expand" option.' + ); + expect(readmore[6].innerHTML).toEqual( + 'twitter:image content should be in JPG, PNG, WEBP, or GIF format.' + ); + expect(readmore[7].innerHTML).toEqual( + 'twitter:image content should use a 16:9 aspect ratio, with a max of 1200 x 675 pixels.' + ); + expect(readmore[8].innerHTML).toEqual( + 'twitter:image content should be smaller than 5MB.' + ); + expect(readmore[9].innerHTML).toEqual( + 'Read more about social media tile image sizes ' + ); + }); + + it('should render Readmore for Facebook', () => { + spectator.setInput({ + seoMedia: SEO_MEDIA_TYPES.FACEBOOK + }); + spectator.detectChanges(); + + const readmore = spectator.queryAll(byTestId('readmore')); + expect(readmore).toExist(); + + expect(readmore[0].innerHTML).toEqual( + 'Learn more about The Open Graph Protocol. ' + ); + expect(readmore[1].innerHTML).toEqual( + 'Explore the Sharing Debugger - Meta for Developers ' + ); + expect(readmore[2].innerHTML).toEqual( + 'Ensure that your og:title content is between 55 and 150 characters.' + ); + expect(readmore[3].innerHTML).toEqual( + 'Keep in mind that your og:title content should be unique across your site.' + ); + expect(readmore[4].innerHTML).toEqual( + 'Optimize your og:image sizes to be under 1200 x 630 pixels.' + ); + expect(readmore[5].innerHTML).toEqual( + 'Make sure your og:image file sizes are under 8 MB.' + ); + expect(readmore[6].innerHTML).toEqual( + 'Read more about social media tile image sizes ' + ); + }); + + it('should render Readmore for LinkedIn', () => { + spectator.setInput({ + seoMedia: SEO_MEDIA_TYPES.LINKEDIN + }); + spectator.detectChanges(); + + const readmore = spectator.queryAll(byTestId('readmore')); + expect(readmore).toExist(); + + expect(readmore[0].innerHTML).toEqual( + 'LinkedIn’s Post Inspector Tool' + ); + expect(readmore[1].innerHTML).toEqual( + 'Meta Tags: Getting Them Right for LinkedIn. ' + ); + expect(readmore[2].innerHTML).toEqual( + 'Read more about social media tile image sizes ' + ); + }); + + it('should render Readmore for Google', () => { + spectator.setInput({ + seoMedia: SEO_MEDIA_TYPES.GOOGLE + }); + spectator.detectChanges(); + + const readmore = spectator.queryAll(byTestId('readmore')); + expect(readmore).toExist(); + + expect(readmore[0].innerHTML).toEqual( + 'Favicons should be .ico files.' + ); + expect(readmore[1].innerHTML).toEqual( + 'HTML Title content should be between 30 and 60 characters.' + ); + expect(readmore[2].innerHTML).toEqual( + 'HTML Title content should be unique per page across your site.' + ); + expect(readmore[3].innerHTML).toEqual( + 'Meta Description tags should be under 160 characters.' + ); + expect(readmore[4].innerHTML).toEqual( + 'The length of the Description allowed will depend on the reader\'s device size; on the smallest size only about 110 characters are allowed. Longer descriptions will show up with some sort of "read more" or "expand" option.' + ); + expect(readmore[5].innerHTML).toEqual( + 'Meta Tags for SEO: A Simple Guide for Beginners ' + ); + expect(readmore[6].innerHTML).toEqual( + 'What Are Meta Descriptions And How to Write Them ' + ); + expect(readmore[7].innerHTML).toEqual( + 'Read more about social media tile image sizes' + ); + }); }); diff --git a/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/seo/components/dot-results-seo-tool/dot-results-seo-tool.component.ts b/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/seo/components/dot-results-seo-tool/dot-results-seo-tool.component.ts index 30cd9fc44baf..cbd67a6c2c29 100644 --- a/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/seo/components/dot-results-seo-tool/dot-results-seo-tool.component.ts +++ b/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/seo/components/dot-results-seo-tool/dot-results-seo-tool.component.ts @@ -56,22 +56,12 @@ export class DotResultsSeoToolComponent implements OnInit, OnChanges { @Input() seoOGTags: SeoMetaTags; @Input() seoOGTagsResults: Observable; currentResults$: Observable; + readMoreValues: Record; constructor(private dotSeoMetaTagsService: DotSeoMetaTagsService) {} - allPreview: MetaTagsPreview[]; mainPreview: MetaTagsPreview; seoMediaTypes = SEO_MEDIA_TYPES; - readMore = [ - { - label: 'The Open Graph protocol', - url: 'https://ogp.me/' - }, - { - label: 'Sharing Debugger - Meta for Developers', - url: 'https://developers.facebook.com/tools/debug/' - } - ]; ngOnInit() { this.allPreview = [ @@ -99,6 +89,7 @@ export class DotResultsSeoToolComponent implements OnInit, OnChanges { const [preview] = this.allPreview; this.mainPreview = preview; + this.readMoreValues = this.dotSeoMetaTagsService.getReadMore(); } ngOnChanges() { diff --git a/dotCMS/src/main/webapp/WEB-INF/messages/Language.properties b/dotCMS/src/main/webapp/WEB-INF/messages/Language.properties index d133c6ba5d24..e15866a5d931 100644 --- a/dotCMS/src/main/webapp/WEB-INF/messages/Language.properties +++ b/dotCMS/src/main/webapp/WEB-INF/messages/Language.properties @@ -5487,3 +5487,35 @@ seo.rules.twitter-image.more.one.found=more than 1 twitter:image meta tag found! seo.rules.twitter-image.more.one.found.empty=twitter:image meta tag found, but is empty! seo.rules.twitter-image.found=twitter:image meta tag found, with an appropriate sized image! seo.rules.twitter-image.over=twitter:image meta tag found, but image is over 5 MB. + +seo.rules.read-more.facebook.learn = Learn more about The Open Graph Protocol. +seo.rules.read-more.facebook.sharing = Explore the Sharing Debugger - Meta for Developers +seo.rules.read-more.facebook.title = Ensure that your og:title content is between 55 and 150 characters. +seo.rules.read-more.facebook.title.unique = Keep in mind that your og:title content should be unique across your site. +seo.rules.read-more.facebook.title.sizes = Optimize your og:image sizes to be under 1200 x 630 pixels. +seo.rules.read-more.facebook.og-image = Make sure your og:image file sizes are under 8 MB. +seo.rules.read-more.facebook.social = Read more about social media tile image sizes + +seo.rules.read-more.twitter.learn = Read more about About Twitter Cards on the Twitter Developer Platform, +seo.rules.read-more.twitter.suggest = Suggest using the twitter:card value of summary_large_image for most content, which uses a 16:9 image aspect ratio; this is similar to other social media cards. +seo.rules.read-more.twitter.twitter-card = A twitter:card value of summary corresponds instead to a 1:1 image. +seo.rules.read-more.twitter.twitter-title = twitter:title content should be between 30 and 70 characters. +seo.rules.read-more.twitter.twitter-title.content = twitter:title content should be unique across your site. +seo.rules.read-more.twitter.length = The length of the description allowed will depend on the reader's device size; on the smallest size only about 110 characters are allowed. Longer descriptions will show up with some sort of "read more" or "expand" option. +seo.rules.read-more.twitter.twitter-image = twitter:image content should be in JPG, PNG, WEBP, or GIF format. +seo.rules.read-more.twitter.twitter-image.aspect = twitter:image content should use a 16:9 aspect ratio, with a max of 1200 x 675 pixels. +seo.rules.read-more.twitter.twitter-image.content = twitter:image content should be smaller than 5MB. +seo.rules.read-more.twitter.twitter-image.social = Read more about social media tile image sizes + +seo.rules.read-more.linkedin.learn = LinkedIn’s Post Inspector Tool +seo.rules.read-more.linkedin.meta = Meta Tags: Getting Them Right for LinkedIn. +seo.rules.read-more.linkedin.summary = Read more about social media tile image sizes + +seo.rules.read-more.google.favicons = Favicons should be .ico files. +seo.rules.read-more.google.title = HTML Title content should be between 30 and 60 characters. +seo.rules.read-more.google.title.unique = HTML Title content should be unique per page across your site. +seo.rules.read-more.google.description = Meta Description tags should be under 160 characters. +seo.rules.read-more.google.length = The length of the Description allowed will depend on the reader's device size; on the smallest size only about 110 characters are allowed. Longer descriptions will show up with some sort of "read more" or "expand" option. +seo.rules.read-more.google.meta-tags = Meta Tags for SEO: A Simple Guide for Beginners +seo.rules.read-more.google.meta-description = What Are Meta Descriptions And How to Write Them +seo.rules.read-more.google.image-sizes = Read more about social media tile image sizes