From 39007b4dabc0c979bd730dedd7626bb73947eb6a Mon Sep 17 00:00:00 2001 From: Ridhwana Date: Tue, 18 Feb 2020 19:02:09 +0200 Subject: [PATCH] Campaign settings (#6141) [deploy] * feat: port over changes (+ suggestions) from https://github.com/thepracticaldev/dev.to/pull/5892/files * chore: add query over multiple lines * refactor: move the sql logic into the controller instead of in the template * chore: appease code climate --- .../internal/configs_controller.rb | 2 + app/controllers/stories_controller.rb | 16 ++++++ app/models/html_variant.rb | 6 ++- app/models/site_config.rb | 7 +++ .../articles/_sidebar_additional.html.erb | 1 + app/views/articles/_sidebar_campaign.html.erb | 16 ++++++ app/views/html_variants/_form.html.erb | 2 +- app/views/html_variants/index.html.erb | 1 + app/views/internal/configs/show.html.erb | 47 ++++++++++++++++++ app/views/layouts/application.html.erb | 5 +- spec/requests/stories_index_spec.rb | 49 +++++++++++++++++++ 11 files changed, 149 insertions(+), 3 deletions(-) create mode 100644 app/views/articles/_sidebar_campaign.html.erb diff --git a/app/controllers/internal/configs_controller.rb b/app/controllers/internal/configs_controller.rb index 26e96c7dd..d0450fa7c 100644 --- a/app/controllers/internal/configs_controller.rb +++ b/app/controllers/internal/configs_controller.rb @@ -21,6 +21,8 @@ class Internal::ConfigsController < Internal::ApplicationController def config_params allowed_params = %i[ default_site_email social_networks_handle + campaign_hero_html_variant_name campaign_background_color + campaign_text_color campaign_sidebar_enabled campaign_featured_tags main_social_image favicon_url logo_svg rate_limit_follow_count_daily ga_view_id ga_fetch_rate diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb index f883bee25..1cd6048d8 100644 --- a/app/controllers/stories_controller.rb +++ b/app/controllers/stories_controller.rb @@ -38,6 +38,20 @@ class StoriesController < ApplicationController private + def assign_hero_html + return if SiteConfig.campaign_hero_html_variant_name.blank? + + @hero_html = HtmlVariant.relevant.select(:html). + find_by(group: "campaign", name: SiteConfig.campaign_hero_html_variant_name)&.html + end + + def get_latest_campaign_articles + @latest_campaign_articles = Article.tagged_with(SiteConfig.campaign_featured_tags, any: true). + where("published_at > ?", 2.weeks.ago).where(approved: true). + order("hotness_score DESC"). + pluck(:path, :title, :comments_count, :created_at) + end + def redirect_to_changed_username_profile potential_username = params[:username].tr("@", "").downcase user_or_org = User.find_by("old_username = ? OR old_old_username = ?", potential_username, potential_username) || @@ -125,8 +139,10 @@ class StoriesController < ApplicationController @default_home_feed = true @featured_story, @stories = feed.default_home_feed(user_signed_in: user_signed_in?) end + assign_hero_html assign_podcasts assign_classified_listings + get_latest_campaign_articles if SiteConfig.campaign_sidebar_enabled? @article_index = true @featured_story = (@featured_story || Article.new)&.decorate @stories = ArticleDecorator.decorate_collection(@stories) diff --git a/app/models/html_variant.rb b/app/models/html_variant.rb index 923071ea5..f61b1733a 100644 --- a/app/models/html_variant.rb +++ b/app/models/html_variant.rb @@ -1,9 +1,11 @@ class HtmlVariant < ApplicationRecord include CloudinaryHelper + GROUP_NAMES = %w[article_show_sidebar_cta article_show_below_article_cta badge_landing_page campaign].freeze + validates :html, presence: true validates :name, uniqueness: true - validates :group, inclusion: { in: %w[article_show_sidebar_cta article_show_below_article_cta badge_landing_page] } + validates :group, inclusion: { in: GROUP_NAMES } validates :success_rate, presence: true validate :no_edits @@ -13,6 +15,8 @@ class HtmlVariant < ApplicationRecord before_save :prefix_all_images + scope :relevant, -> { where(approved: true, published: true) } + def calculate_success_rate! self.success_rate = html_variant_successes.size.to_f / (html_variant_trials.size * 10.0) # x10 because we only capture every 10th save! diff --git a/app/models/site_config.rb b/app/models/site_config.rb index 2d3f515da..268427850 100644 --- a/app/models/site_config.rb +++ b/app/models/site_config.rb @@ -13,6 +13,13 @@ class SiteConfig < RailsSettings::Base field :default_site_email, type: :string, default: "yo@dev.to" field :social_networks_handle, type: :string, default: "thepracticaldev" + # campaign + field :campaign_hero_html_variant_name, type: :string, default: "" + field :campaign_background_color, type: :string, default: "FFFFFF" + field :campaign_text_color, type: :string, default: "000000" + field :campaign_featured_tags, type: :array, default: %w[] + field :campaign_sidebar_enabled, type: :boolean, default: 0 + # images field :main_social_image, type: :string, default: "https://thepracticaldev.s3.amazonaws.com/i/6hqmcjaxbgbon8ydw93z.png" field :favicon_url, type: :string, default: "favicon.ico" diff --git a/app/views/articles/_sidebar_additional.html.erb b/app/views/articles/_sidebar_additional.html.erb index 30eb8d106..5008c333f 100644 --- a/app/views/articles/_sidebar_additional.html.erb +++ b/app/views/articles/_sidebar_additional.html.erb @@ -27,6 +27,7 @@ <% end %> + <%= render "articles/sidebar_campaign" if SiteConfig.campaign_sidebar_enabled? %> <% if params[:timeframe].blank? && @classified_listings.any? %> <%= f.submit %> <% end %> diff --git a/app/views/html_variants/index.html.erb b/app/views/html_variants/index.html.erb index 39fc85876..825050941 100644 --- a/app/views/html_variants/index.html.erb +++ b/app/views/html_variants/index.html.erb @@ -10,6 +10,7 @@ ">Show Page Sidebar ">Show Page Below Article ">Badge Landing Page + ">Campaign <% if params[:state] == "mine" %>

My Entries

diff --git a/app/views/internal/configs/show.html.erb b/app/views/internal/configs/show.html.erb index 2f5b719ac..e153284dd 100644 --- a/app/views/internal/configs/show.html.erb +++ b/app/views/internal/configs/show.html.erb @@ -45,6 +45,53 @@ +
+
Campaign
+
+
+ <%= f.label :campaign_hero_html_variant_name %> + <%= f.text_field :campaign_hero_html_variant_name, + class: "form-control", + value: SiteConfig.campaign_hero_html_variant_name, + placeholder: "" %> +
Hero HtmlVariant name
+
+ +
+ <%= f.label :campaign_background_color %> + <%= f.text_field :campaign_background_color, + class: "form-control", + value: SiteConfig.campaign_background_color, + placeholder: "FFFFFF" %> +
Campaign background color
+
+ +
+ <%= f.label :campaign_text_color %> + <%= f.text_field :campaign_text_color, + class: "form-control", + value: SiteConfig.campaign_text_color, + placeholder: "FFFFFF" %> +
Campaign text color
+
+ +
+ <%= f.label :campaign_sidebar_enabled %> + <%= f.check_box :campaign_sidebar_enabled, checked: SiteConfig.campaign_sidebar_enabled %> +
Campaign sidebar enabled or not
+
+ +
+ <%= f.label :campaign_featured_tags %> + <%= f.text_field :campaign_featured_tags, + class: "form-control", + value: SiteConfig.campaign_featured_tags.join(","), + placeholder: "List of campaign tags: comma separated, letters only e.g. shecoded,theycoded" %> +
Posts with which tags will be featured in the campaign sidebar (comma separated, letters only)
+
+
+
+
Images
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index e4062912b..972a11bb3 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -7,7 +7,10 @@
<% end %>
+ <% if @hero_html %> + <%= @hero_html.html_safe %> + <% end %> <%= yield %>
-<%= render "shell/bottom" %> \ No newline at end of file +<%= render "shell/bottom" %> diff --git a/spec/requests/stories_index_spec.rb b/spec/requests/stories_index_spec.rb index 8414b74ce..cb8b63480 100644 --- a/spec/requests/stories_index_spec.rb +++ b/spec/requests/stories_index_spec.rb @@ -68,6 +68,55 @@ RSpec.describe "StoriesIndex", type: :request do get "/" expect(response.body).to include(CGI.escapeHTML(listing.title)) end + + context "with campaign hero" do + let!(:hero_html) { create(:html_variant, group: "campaign", name: "hero", html: Faker::Book.title, published: true, approved: true) } + + it "displays hero html when it exists and is set in config" do + SiteConfig.campaign_hero_html_variant_name = "hero" + get "/" + expect(response.body).to include(CGI.escapeHTML(hero_html.html)) + end + + it "doesn't display when campaign_hero_html_variant_name is not set" do + SiteConfig.campaign_hero_html_variant_name = "" + get "/" + expect(response.body).not_to include(CGI.escapeHTML(hero_html.html)) + end + + it "doesn't display when hero html is not approved" do + SiteConfig.campaign_hero_html_variant_name = "hero" + hero_html.update_column(:approved, false) + get "/" + expect(response.body).not_to include(CGI.escapeHTML(hero_html.html)) + end + end + + context "with campaign_sidebar" do + before do + SiteConfig.campaign_featured_tags = "shecoded,theycoded" + create(:article, approved: true, body_markdown: "---\ntitle: Super-sheep#{rand(1000)}\npublished: true\ntags: heyheyhey,shecoded\n---\n\nHello") + create(:article, approved: false, body_markdown: "---\ntitle: Unapproved-post#{rand(1000)}\npublished: true\ntags: heyheyhey,shecoded\n---\n\nHello") + end + + it "doesn't display posts with the campaign tags when sidebar is disabled" do + SiteConfig.campaign_sidebar_enabled = false + get "/" + expect(response.body).not_to include(CGI.escapeHTML("Super-sheep")) + end + + it "displays posts with the campaign tags when sidebar is enabled" do + SiteConfig.campaign_sidebar_enabled = true + get "/" + expect(response.body).not_to include(CGI.escapeHTML("Unapproved-post")) + end + + it "displays only approved posts with the campaign tags" do + SiteConfig.campaign_sidebar_enabled = false + get "/" + expect(response.body).not_to include(CGI.escapeHTML("Super-puper")) + end + end end describe "GET query page" do