From d92e9d1af479a8a3639a456c3c5bee8dcc25c87d Mon Sep 17 00:00:00 2001
From: Ridhwana
Date: Fri, 12 May 2023 14:30:30 +0200
Subject: [PATCH] CTA Embed (#19440)
* feat: first pass at CTA Tag
* fix: strip_tags before using the link
* default hover
* feat: add the type of cta
* feat: add own ltag by copying the utility class
* feat: rename property to style
* feat: add style and width
* feat: add xit test
* feat: add spec for unordered options
* chore: some css
* feat: update the cta spec to remove style and width options
* feat: move billboard related code out of widgets
* fix: mobile display ad below the comments section
* feat: cta_tag strip tags input
* feat: update the editor docs
* feat: add help text to teh liquid guide and the editor guide
* feat: fix the css styles of the CTA
* cgore: alphabetical order
* chore: move everything on one line
---------
Co-authored-by: Mac Siri
---
app/assets/stylesheets/base/typography.scss | 10 ++++
app/assets/stylesheets/billboards.scss | 50 +++++++++++++++++++
app/assets/stylesheets/ltags/CtaTag.scss | 49 ++++++++++++++++++
app/assets/stylesheets/ltags/LiquidTags.scss | 1 +
app/assets/stylesheets/minimal.scss | 1 +
app/assets/stylesheets/widgets.scss | 21 --------
app/liquid_tags/cta_tag.rb | 36 +++++++++++++
app/views/liquids/_cta.html.erb | 1 +
.../pages/_editor_liquid_help.en.html.erb | 12 +++--
.../pages/_editor_liquid_help.fr.html.erb | 4 ++
.../_supported_nonurl_embeds_list.en.html.erb | 4 ++
.../_supported_nonurl_embeds_list.fr.html.erb | 4 ++
app/views/shared/_display_ad.html.erb | 4 +-
spec/liquid_tags/cta_tag_spec.rb | 47 +++++++++++++++++
14 files changed, 217 insertions(+), 27 deletions(-)
create mode 100644 app/assets/stylesheets/billboards.scss
create mode 100644 app/assets/stylesheets/ltags/CtaTag.scss
create mode 100644 app/liquid_tags/cta_tag.rb
create mode 100644 app/views/liquids/_cta.html.erb
create mode 100644 spec/liquid_tags/cta_tag_spec.rb
diff --git a/app/assets/stylesheets/base/typography.scss b/app/assets/stylesheets/base/typography.scss
index 213b9a102..eaf10ba41 100644
--- a/app/assets/stylesheets/base/typography.scss
+++ b/app/assets/stylesheets/base/typography.scss
@@ -112,6 +112,16 @@ body {
// when/if we "redesign" liquid tags.
[class*='ltag'] a {
text-decoration: none;
+ &:hover {
+ color: var(--color-hover);
+ }
+ }
+
+ a[class*='ltag'] {
+ text-decoration: none;
+ &:hover {
+ color: var(--color-hover);
+ }
}
h1,
diff --git a/app/assets/stylesheets/billboards.scss b/app/assets/stylesheets/billboards.scss
new file mode 100644
index 000000000..1cc28afd5
--- /dev/null
+++ b/app/assets/stylesheets/billboards.scss
@@ -0,0 +1,50 @@
+@import 'config/import';
+@import 'variables';
+@import '_mixins';
+
+.crayons-layout__comments-display-ad {
+ .crayons-sponsorship {
+ .c-indicator.crayons-sponsorship__indicator {
+ line-height: 15px;
+ }
+
+ padding-left: var(--content-padding-x);
+ padding-bottom: var(--su-6);
+
+ @media (min-width: $breakpoint-s) {
+ .text-styles {
+ padding-right: var(--su-8);
+ }
+ }
+ }
+}
+
+.sponsorship-dropdown {
+ hr {
+ border: 0.5px solid var(--divider);
+ margin: 8px;
+ }
+}
+
+.billboard .ltag_cta {
+ padding-top: var(--su-2);
+ padding-bottom: var(--su-2);
+
+ @media (max-width: $breakpoint-s) {
+ display: block;
+ }
+}
+
+// refers to the sidebar billboards where we use cards
+.crayons-card.billboard .ltag_cta {
+ display: block;
+}
+
+// these are inline CTA's
+//refers to the below the comments billboard on the article page
+//refers to the feed/stories where we use story
+.crayons-layout__comments-display-ad .crayons-card.billboard .ltag_cta,
+.crayons-story.billboard .ltag_cta {
+ padding-right: var(--su-7);
+ padding-left: var(--su-7);
+}
diff --git a/app/assets/stylesheets/ltags/CtaTag.scss b/app/assets/stylesheets/ltags/CtaTag.scss
new file mode 100644
index 000000000..23ef7154a
--- /dev/null
+++ b/app/assets/stylesheets/ltags/CtaTag.scss
@@ -0,0 +1,49 @@
+.ltag_cta {
+ --border-width: 1px;
+ padding: var(--su-2) var(--su-4);
+ border: var(--border-width) solid;
+ border-color: var(--border);
+ text-decoration: none;
+ border-radius: var(--radius);
+ font: inherit;
+ background-color: var(--bg);
+ color: var(--color);
+ outline: 0;
+ text-align: center;
+ display: inline-flex;
+ position: relative;
+ overflow-wrap: normal;
+
+ &:hover,
+ .js-focus-visible &.focus-visible:focus {
+ background-color: var(--bg-hover);
+ border-color: var(--border-hover);
+ color: var(--color-hover);
+ z-index: var(--z-elevate);
+ text-decoration: underline;
+ }
+
+ .js-focus-visible &.focus-visible:focus {
+ box-shadow: var(--focus-ring);
+ }
+}
+
+.ltag_cta {
+ --bg: var(--cta-bg);
+ --bg-hover: var(--cta-bg-hover);
+ --color: var(--cta-color);
+ --color-hover: var(--cta-color-hover);
+ --border: var(--cta-border);
+ --border-hover: var(--cta-border-hover);
+
+ &--branded {
+ --bg: var(--cta-branded-bg);
+ --bg-hover: var(--cta-branded-bg-hover);
+ --color: var(--cta-branded-color);
+ --color-hover: var(--cta-branded-color-hover);
+ --border: var(--cta-branded-border);
+ --border-hover: var(--cta-branded-border-hover);
+
+ font-weight: var(--fw-medium);
+ }
+}
diff --git a/app/assets/stylesheets/ltags/LiquidTags.scss b/app/assets/stylesheets/ltags/LiquidTags.scss
index 50fe6850d..b214352b7 100644
--- a/app/assets/stylesheets/ltags/LiquidTags.scss
+++ b/app/assets/stylesheets/ltags/LiquidTags.scss
@@ -1,4 +1,5 @@
@import 'CommentTag';
+@import 'CtaTag';
@import 'GistTag';
@import 'GithubReadmeTag';
@import 'GithubTag';
diff --git a/app/assets/stylesheets/minimal.scss b/app/assets/stylesheets/minimal.scss
index 6388f0558..65fa9a3d4 100644
--- a/app/assets/stylesheets/minimal.scss
+++ b/app/assets/stylesheets/minimal.scss
@@ -3,6 +3,7 @@
@import 'scaffolds';
@import 'articles';
@import 'article-show';
+@import 'billboards';
@import 'shared';
@import 'dashboard';
@import 'settings';
diff --git a/app/assets/stylesheets/widgets.scss b/app/assets/stylesheets/widgets.scss
index ae7ce4e27..415f22108 100644
--- a/app/assets/stylesheets/widgets.scss
+++ b/app/assets/stylesheets/widgets.scss
@@ -351,24 +351,3 @@
}
}
}
-
-.crayons-layout__comments-display-ad {
- .crayons-sponsorship {
- .c-indicator.crayons-sponsorship__indicator {
- line-height: 15px;
- }
-
- padding-left: var(--content-padding-x);
- padding-bottom: var(--su-6);
- .text-styles {
- padding-right: var(--su-8);
- }
- }
-}
-
-.sponsorship-dropdown {
- hr {
- border: 0.5px solid var(--divider);
- margin: 8px;
- }
-}
diff --git a/app/liquid_tags/cta_tag.rb b/app/liquid_tags/cta_tag.rb
new file mode 100644
index 000000000..64ff90d53
--- /dev/null
+++ b/app/liquid_tags/cta_tag.rb
@@ -0,0 +1,36 @@
+class CtaTag < Liquid::Block
+ include ActionView::Helpers::SanitizeHelper
+
+ PARTIAL = "liquids/cta".freeze
+ # at some point we may want to pass in options to dictate which type of CTA the user wants to use,
+ # i.e. secondary, primary, branded. This sets the scene for it without actually providing that option now.
+ TYPE_OPTIONS = %w[branded].freeze
+ DESCRIPTION_LENGTH = 128
+
+ def initialize(_tag_name, options, _parse_context)
+ super
+ @link = strip_tags(options.strip)
+ end
+
+ def render(_context)
+ content = Nokogiri::HTML.parse(super)
+
+ ApplicationController.render(
+ partial: PARTIAL,
+ locals: {
+ link: @link,
+ description: sanitized_description(content),
+ type: TYPE_OPTIONS.first
+ },
+ )
+ end
+
+ private
+
+ def sanitized_description(content)
+ stripped_description = strip_tags(content.xpath("//html/body").inner_html).delete("\n").strip
+ stripped_description.truncate(DESCRIPTION_LENGTH)
+ end
+end
+
+Liquid::Template.register_tag("cta", CtaTag)
diff --git a/app/views/liquids/_cta.html.erb b/app/views/liquids/_cta.html.erb
new file mode 100644
index 000000000..7536fae3d
--- /dev/null
+++ b/app/views/liquids/_cta.html.erb
@@ -0,0 +1 @@
+<%= description %>
diff --git a/app/views/pages/_editor_liquid_help.en.html.erb b/app/views/pages/_editor_liquid_help.en.html.erb
index 37cff71a8..ecd0cab7a 100644
--- a/app/views/pages/_editor_liquid_help.en.html.erb
+++ b/app/views/pages/_editor_liquid_help.en.html.erb
@@ -45,11 +45,15 @@
Supported Non-URL Embeds
+ Call To Action (CTA)
+ {% cta link %} description {% endcta %}
+ Provide a link that a user will be redirected to. The description will contain the label/description for the call to action.
+
Details
You can embed a details HTML element by using details, spoiler, or collapsible. The summary will be what the dropdown title displays. The content will be the text hidden behind the dropdown. This is great for when you want to hide text (i.e. answers to questions) behind a user action/intent (i.e. a click).
- {% details summary %} content {% enddetails %}
- {% spoiler summary %} content {% endspoiler %}
- {% collapsible summary %} content {% endcollapsible %}
+ {% details summary %} content {% enddetails %}
+ {% spoiler summary %} content {% endspoiler %}
+ {% collapsible summary %} content {% endcollapsible %}
KaTex
Place your mathematical expression within a KaTeX liquid block, as follows:
@@ -65,7 +69,7 @@
<%= community_name %> User Subscriptions
This embed can only be created within posts by Admins.
You can add call-to-action text that will show above the subscribe button:
- {% user_subscription If you'd like to receive future updates, subscribe below! %}
+ {% user_subscription If you'd like to receive future updates, subscribe below! %}
If a reader is signed out, the button will prompt them to sign in first
to subscribe. If the reader is signed in, the button will prompt them
diff --git a/app/views/pages/_editor_liquid_help.fr.html.erb b/app/views/pages/_editor_liquid_help.fr.html.erb
index 37cff71a8..aedc1221b 100644
--- a/app/views/pages/_editor_liquid_help.fr.html.erb
+++ b/app/views/pages/_editor_liquid_help.fr.html.erb
@@ -45,6 +45,10 @@
Supported Non-URL Embeds
+ Call To Action (CTA)
+ {% cta link %} description {% endcta %}
+ Provide a link that a user will be redirected to. The description will contain the label/description for the call to action.
+
Details
You can embed a details HTML element by using details, spoiler, or collapsible. The summary will be what the dropdown title displays. The content will be the text hidden behind the dropdown. This is great for when you want to hide text (i.e. answers to questions) behind a user action/intent (i.e. a click).
{% details summary %} content {% enddetails %}
diff --git a/app/views/pages/_supported_nonurl_embeds_list.en.html.erb b/app/views/pages/_supported_nonurl_embeds_list.en.html.erb
index 910dc4486..720dc66b7 100644
--- a/app/views/pages/_supported_nonurl_embeds_list.en.html.erb
+++ b/app/views/pages/_supported_nonurl_embeds_list.en.html.erb
@@ -1,5 +1,9 @@
<% @user_approved_liquid_tags = Users::ApprovedLiquidTags.call(@user) %>
+Call To Action (CTA)
+{% cta link %} description {% endcta %}
+Provide a link that a user will be redirected to. The description will contain the label/description for the call to action.
+
Details
You can embed a details HTML element by using details, spoiler, or collapsible. The summary will be what the dropdown title displays. The content will be the text hidden behind the dropdown. This is great for when you want to hide text (i.e. answers to questions) behind a user action/intent (i.e. a click).
diff --git a/app/views/pages/_supported_nonurl_embeds_list.fr.html.erb b/app/views/pages/_supported_nonurl_embeds_list.fr.html.erb
index 910dc4486..720dc66b7 100644
--- a/app/views/pages/_supported_nonurl_embeds_list.fr.html.erb
+++ b/app/views/pages/_supported_nonurl_embeds_list.fr.html.erb
@@ -1,5 +1,9 @@
<% @user_approved_liquid_tags = Users::ApprovedLiquidTags.call(@user) %>
+Call To Action (CTA)
+{% cta link %} description {% endcta %}
+Provide a link that a user will be redirected to. The description will contain the label/description for the call to action.
+
Details
You can embed a details HTML element by using details, spoiler, or collapsible. The summary will be what the dropdown title displays. The content will be the text hidden behind the dropdown. This is great for when you want to hide text (i.e. answers to questions) behind a user action/intent (i.e. a click).
diff --git a/app/views/shared/_display_ad.html.erb b/app/views/shared/_display_ad.html.erb
index ef01b0887..dd9278cfb 100644
--- a/app/views/shared/_display_ad.html.erb
+++ b/app/views/shared/_display_ad.html.erb
@@ -1,5 +1,5 @@
<% if display_ad.placement_area.start_with?("feed_") %>
-
<% else %>
- ").render
+ expect(rendered).to include("DEV Community")
+ expect(rendered).not_to include("class='crayons'")
+ expect(rendered).not_to include("")
+ end
+ end
+end