diff --git a/app/controllers/admin/configs_controller.rb b/app/controllers/admin/configs_controller.rb
index 51b816fd2..645c95e71 100644
--- a/app/controllers/admin/configs_controller.rb
+++ b/app/controllers/admin/configs_controller.rb
@@ -14,6 +14,7 @@ module Admin
COMMUNITY_PARAMS =
%i[
community_name
+ community_emoji
collective_noun
collective_noun_disabled
community_description
@@ -127,6 +128,7 @@ module Admin
display_email_domain_allow_list_publicly
].freeze
+ EMOJI_ONLY_FIELDS = %w[community_emoji].freeze
IMAGE_FIELDS =
%w[
main_social_image
@@ -146,6 +148,7 @@ module Admin
before_action :extra_authorization_and_confirmation, only: [:create]
before_action :validate_inputs, only: [:create]
+ before_action :validate_emoji, only: [:create], if: -> { params[:site_config].keys & EMOJI_ONLY_FIELDS }
before_action :validate_image_urls, only: [:create], if: -> { params[:site_config].keys & IMAGE_FIELDS }
after_action :bust_content_change_caches, only: [:create]
@@ -217,6 +220,15 @@ module Admin
redirect_to admin_config_path, alert: "😭 #{errors.to_sentence}" if errors.any?
end
+ def validate_emoji
+ emoji_params = config_params.slice(*EMOJI_ONLY_FIELDS).to_h
+ errors = emoji_params.filter_map do |field, value|
+ non_emoji_characters = value.downcase.gsub(EmojiRegex::RGIEmoji, "")
+ "#{field} contains invalid emoji" if non_emoji_characters.present?
+ end
+ redirect_to admin_config_path, alert: "😭 #{errors.to_sentence}" if errors.any?
+ end
+
def validate_image_urls
image_params = config_params.slice(*IMAGE_FIELDS).to_h
errors = image_params.filter_map do |field, url|
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 7dcc73611..b8e676a86 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -45,7 +45,7 @@ module ApplicationHelper
derived_title = if page_title.include?(community_name)
page_title
elsif user_signed_in?
- "#{page_title} - #{community_qualified_name} 👩💻👨💻"
+ "#{page_title} - #{community_qualified_name} #{community_emoji}"
else
"#{page_title} - #{community_name}"
end
@@ -185,6 +185,10 @@ module ApplicationHelper
@community_name ||= SiteConfig.community_name
end
+ def community_emoji
+ @community_emoji ||= SiteConfig.community_emoji
+ end
+
def community_qualified_name
return "#{community_name} #{SiteConfig.collective_noun}" unless SiteConfig.collective_noun_disabled
diff --git a/app/lib/constants/site_config.rb b/app/lib/constants/site_config.rb
index 1f3122bab..f487ca28c 100644
--- a/app/lib/constants/site_config.rb
+++ b/app/lib/constants/site_config.rb
@@ -57,6 +57,10 @@ module Constants
description: "Used in meta description tags etc.",
placeholder: "A fabulous community of kind and welcoming people."
},
+ community_emoji: {
+ description: "Used in the title tags across the site alongside the community name",
+ placeholder: ""
+ },
community_member_label: {
description: "Used to determine what a member will be called e.g developer, hobbyist etc.",
placeholder: "user"
diff --git a/app/models/site_config.rb b/app/models/site_config.rb
index 27efea783..7bb2157b9 100644
--- a/app/models/site_config.rb
+++ b/app/models/site_config.rb
@@ -50,6 +50,7 @@ class SiteConfig < RailsSettings::Base
# Community Content
field :community_name, type: :string, default: ApplicationConfig["COMMUNITY_NAME"] || "New Forem"
+ field :community_emoji, type: :string, default: "🌱"
field :collective_noun, type: :string, default: "Community"
field :collective_noun_disabled, type: :boolean, default: false
field :community_description, type: :string
diff --git a/app/views/admin/configs/show.html.erb b/app/views/admin/configs/show.html.erb
index 269f8ab65..9835f3f07 100644
--- a/app/views/admin/configs/show.html.erb
+++ b/app/views/admin/configs/show.html.erb
@@ -443,6 +443,15 @@
<%= f.check_box :collective_noun_disabled, checked: SiteConfig.collective_noun_disabled, data: { action: "config#disableTargetField", disable_target: "collectiveNoun" }, class: "crayons-checkbox" %>
+
+ <%= admin_config_label :community_emoji %>
+ <%= admin_config_description Constants::SiteConfig::DETAILS[:community_emoji][:description] %>
+ <%= f.text_field :community_emoji,
+ class: "crayons-textfield",
+ value: SiteConfig.community_emoji,
+ placeholder: Constants::SiteConfig::DETAILS[:community_emoji][:placeholder] %>
+
+
<%= admin_config_label :tagline %>
<%= admin_config_description Constants::SiteConfig::DETAILS[:tagline][:description] %>
diff --git a/app/views/articles/index.html.erb b/app/views/articles/index.html.erb
index 7748170cf..68ed4bf64 100644
--- a/app/views/articles/index.html.erb
+++ b/app/views/articles/index.html.erb
@@ -1,6 +1,6 @@
<%= content_for :page_meta do %>
<% title_with_timeframe(
- page_title: "#{community_qualified_name} 👩💻👨💻",
+ page_title: "#{community_qualified_name} #{community_emoji}",
timeframe: params[:timeframe],
content_for: true,
) %>
diff --git a/app/views/chat_channels/index.html.erb b/app/views/chat_channels/index.html.erb
index a0b56404d..6ca55f1ac 100644
--- a/app/views/chat_channels/index.html.erb
+++ b/app/views/chat_channels/index.html.erb
@@ -1,4 +1,4 @@
-<% title("#{community_name} Connect 👩💻💬👨💻") %>
+<% title("#{community_name} Connect") %>
<%= content_for :page_meta do %>
diff --git a/spec/liquid_tags/tweet_tag_spec.rb b/spec/liquid_tags/tweet_tag_spec.rb
index 7a87910c5..19feb396a 100644
--- a/spec/liquid_tags/tweet_tag_spec.rb
+++ b/spec/liquid_tags/tweet_tag_spec.rb
@@ -3,7 +3,7 @@ require "rails_helper"
RSpec.describe TweetTag, type: :liquid_tag do
let(:twitter_id) { "1018911886862057472" }
let(:handle) { "thepracticaldev" }
- let(:name) { "DEV Community 👩💻👨💻" }
+ let(:name) { "DEV Community" }
let(:body) { "When GitHub goes down" }
setup { Liquid::Template.register_tag("tweet", described_class) }
diff --git a/spec/requests/admin/configs_spec.rb b/spec/requests/admin/configs_spec.rb
index 71e9b98ef..5171f6a2c 100644
--- a/spec/requests/admin/configs_spec.rb
+++ b/spec/requests/admin/configs_spec.rb
@@ -144,6 +144,23 @@ RSpec.describe "/admin/config", type: :request do
expect(SiteConfig.community_description).to eq(description)
end
+ it "updates the community_emoji if valid" do
+ allow(SiteConfig).to receive(:community_emoji).and_call_original
+ emoji = "🥐"
+ post "/admin/config", params: { site_config: { community_emoji: emoji },
+ confirmation: confirmation_message }
+ expect(SiteConfig.community_emoji).to eq(emoji)
+ end
+
+ it "does not update the community_emoji if invalid" do
+ allow(SiteConfig).to receive(:community_emoji).and_call_original
+ not_an_emoji = "i love croissants"
+ expect do
+ post "/admin/config", params: { site_config: { community_emoji: not_an_emoji },
+ confirmation: confirmation_message }
+ end.not_to change(SiteConfig, :community_emoji)
+ end
+
it "updates the community_name" do
name_magoo = "Hey hey #{rand(100)}"
post "/admin/config", params: { site_config: { community_name: name_magoo },
diff --git a/spec/requests/stories_show_spec.rb b/spec/requests/stories_show_spec.rb
index 69c1361c5..8dbcb82f9 100644
--- a/spec/requests/stories_show_spec.rb
+++ b/spec/requests/stories_show_spec.rb
@@ -21,11 +21,13 @@ RSpec.describe "StoriesShow", type: :request do
## Title tag
it "renders signed-in title tag for signed-in user" do
+ allow(SiteConfig).to receive(:community_emoji).and_return("🌱")
+
sign_in user
get article.path
- expected_title = "
#{CGI.escapeHTML(article.title)} - #{community_qualified_name} 👩💻👨💻"
- expect(response.body).to include(expected_title)
+ title = "#{CGI.escapeHTML(article.title)} - #{community_qualified_name} #{community_emoji}"
+ expect(response.body).to include(title)
end
it "renders signed-out title tag for signed-out user" do
@@ -44,12 +46,14 @@ RSpec.describe "StoriesShow", type: :request do
end
it "does not render title tag with search_optimized_title_preamble if set and not signed in" do
+ allow(SiteConfig).to receive(:community_emoji).and_return("🌱")
+
sign_in user
article.update_column(:search_optimized_title_preamble, "Hey this is a test")
get article.path
- expected_title = "#{CGI.escapeHTML(article.title)} - #{community_qualified_name} 👩💻👨💻"
- expect(response.body).to include(expected_title)
+ title = "#{CGI.escapeHTML(article.title)} - #{community_qualified_name} #{community_emoji}"
+ expect(response.body).to include(title)
end
it "does not render preamble with search_optimized_title_preamble not signed in but not set" do