Skip to content

Commit 6c7ecf4

Browse files
authored
Use external links (#586)
* Change links to refer to external_link, if present for Story, CommunityNews, Resource * Only implement link_target w Linkable, otherwise use object_link_target via decorator (called from taggings index) * Only open in new window (target:'_blank') if is external_link * Add noreferrer to all noopener exteranl links * Add 'target' keyword to arg * Update tagged_item_card * Update brakeman
1 parent 0b8eedb commit 6c7ecf4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+202
-198
lines changed

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ gem "active_storage_validations", "~> 3.0"
4949

5050
group :development, :test do
5151
gem "better_errors"
52-
gem "brakeman", "~> 7.1.1", require: false
52+
gem "brakeman", "~> 7.1.2", require: false
5353
gem "bundler-audit", require: false
5454
gem "capybara", "~> 3.36"
5555
gem "dotenv-rails"

Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ DEPENDENCIES
458458
better_errors
459459
binding_of_caller
460460
bootsnap
461-
brakeman (~> 7.1.1)
461+
brakeman (~> 7.1.2)
462462
bundler-audit
463463
capybara (~> 3.36)
464464
cocoon (~> 1.2.6)

app/controllers/categories_controller.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@ def index
55
per_page = params[:number_of_items_per_page].presence || 25
66
@category_types = CategoryType.order(:name)
77

8-
unpaginated = Category.joins(:category_type)
9-
filtered = unpaginated.category_type_id(params[:category_type_id])
8+
unfiltered = Category.joins(:category_type)
9+
filtered = unfiltered.category_type_id(params[:category_type_id])
1010
.category_name(params[:category_name])
1111
.published_search(params[:published_search])
1212
.order("metadata.name ASC, categories.name ASC")
1313
@categories = filtered.paginate(page: params[:page], per_page: per_page)
1414

15-
@count_display = if @categories.total_entries == unpaginated.count
16-
unpaginated.count
15+
@count_display = if filtered.count == unfiltered.count
16+
unfiltered.count
1717
else
18-
"#{@categories.total_entries}/#{unpaginated.count}"
18+
"#{filtered.count}/#{unfiltered.count}"
1919
end
2020
end
2121

app/controllers/community_news_controller.rb

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,28 @@ class CommunityNewsController < ApplicationController
33

44
def index
55
per_page = params[:number_of_items_per_page].presence || 25
6-
unpaginated = current_user.super_user? ? CommunityNews.all : Community_news.published
7-
filtered = unpaginated.search_by_params(params)
8-
@community_news = filtered.paginate(page: params[:page], per_page: per_page)
6+
unfiltered = current_user.super_user? ? CommunityNews.all : Community_news.published
7+
filtered = unfiltered.search_by_params(params)
8+
@community_news = filtered.paginate(page: params[:page], per_page: per_page).decorate
99

10-
@count_display = if @community_news.total_entries == unpaginated.count
11-
unpaginated.count
10+
@count_display = if filtered.count == unfiltered.count
11+
unfiltered.count
1212
else
13-
"#{@community_news.total_entries}/#{unpaginated.count}"
13+
"#{filtered.count}/#{unfiltered.count}"
1414
end
1515
end
1616

1717
def show
18+
@community_news = @community_news.decorate
1819
end
1920

2021
def new
21-
@community_news = CommunityNews.new
22+
@community_news = CommunityNews.new.decorate
2223
set_form_variables
2324
end
2425

2526
def edit
27+
@community_news = @community_news.decorate
2628
set_form_variables
2729
end
2830

@@ -33,6 +35,7 @@ def create
3335
redirect_to community_news_index_path,
3436
notice: "Community news was successfully created."
3537
else
38+
@community_news = @community_news.decorate
3639
set_form_variables
3740
render :new, status: :unprocessable_content
3841
end

app/controllers/resources_controller.rb

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,22 @@ def index
66
.includes(:main_image, :gallery_images, :attachments)
77
filtered = unpaginated.search_by_params(params)
88
.by_created
9-
@resources = filtered.paginate(page: params[:page], per_page: per_page)
9+
@resources = filtered.paginate(page: params[:page], per_page: per_page).decorate
1010

11-
@count_display = if @resources.total_entries == unpaginated.count
11+
@count_display = if filtered.count == unpaginated.count
1212
unpaginated.count
1313
else
14-
"#{@resources.total_entries}/#{unpaginated.count}"
14+
"#{filtered.count}/#{unpaginated.count}"
1515
end
1616
@sortable_fields = Resource::PUBLISHED_KINDS
1717
end
1818

1919
def stories
20-
@stories = Resource.story.paginate(page: params[:page], per_page: 6)
20+
@stories = Resource.story.paginate(page: params[:page], per_page: 6).decorate
2121
end
2222

2323
def new
24-
@resource = Resource.new
24+
@resource = Resource.new.decorate
2525
set_form_variables
2626
end
2727

@@ -47,6 +47,7 @@ def create
4747
if @resource.save
4848
redirect_to resources_path
4949
else
50+
@resource = @resource.decorate
5051
set_form_variables
5152
flash[:alert] = "Unable to save #{@resource.title.titleize}"
5253
render :new

app/controllers/sectors_controller.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@ class SectorsController < ApplicationController
33

44
def index
55
per_page = params[:number_of_items_per_page].presence || 25
6-
unpaginated = Sector.all
7-
filtered = unpaginated.sector_name(params[:sector_name])
6+
unfiltered = Sector.all
7+
filtered = unfiltered.sector_name(params[:sector_name])
88
.published_search(params[:published_search])
99
.order(:name)
1010
@sectors = filtered.paginate(page: params[:page], per_page: per_page)
1111

12-
@count_display = if @sectors.total_entries == unpaginated.count
13-
unpaginated.count
12+
@count_display = if filtered.count == unfiltered.count
13+
unfiltered.count
1414
else
15-
"#{@sectors.total_entries}/#{unpaginated.count}"
15+
"#{filtered.count}/#{unfiltered.count}"
1616
end
1717
end
1818

app/controllers/stories_controller.rb

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,27 @@ def index
77
filtered = unpaginated.includes(:windows_type, :project, :workshop, :created_by, :updated_by)
88
.search_by_params(params)
99
.order(created_at: :desc)
10-
@stories = filtered.paginate(page: params[:page], per_page: per_page)
10+
@stories = filtered.paginate(page: params[:page], per_page: per_page).decorate
1111

12-
@count_display = if @stories.total_entries == unpaginated.count
12+
@count_display = if filtered.count == unpaginated.count
1313
unpaginated.count
1414
else
15-
"#{@stories.total_entries}/#{unpaginated.count}"
15+
"#{filtered.count}/#{unpaginated.count}"
1616
end
1717
end
1818

1919
def show
20+
@story = @story.decorate
2021
end
2122

2223
def new
23-
@story = Story.new
24+
@story = Story.new.decorate
25+
@story = @story.decorate
2426
set_form_variables
2527
end
2628

2729
def edit
30+
@story = @story.decorate
2831
set_form_variables
2932
end
3033

@@ -34,6 +37,7 @@ def create
3437
if @story.save
3538
redirect_to stories_path, notice: "Story was successfully created."
3639
else
40+
@story = @story.decorate
3741
set_form_variables
3842
render :new, status: :unprocessable_content
3943
end
@@ -43,6 +47,7 @@ def update
4347
if @story.update(story_params.except(:images))
4448
redirect_to stories_path, notice: "Story was successfully updated.", status: :see_other
4549
else
50+
@story = @story.decorate
4651
set_form_variables
4752
render :edit, status: :unprocessable_content
4853
end
Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
class ApplicationDecorator < Draper::Decorator
22
delegate_all
33

4-
def object_link_target
5-
if object.respond_to?(:link_target)
6-
object.link_target
7-
else
8-
object_default_link_target
9-
end
4+
def link_target
5+
h.polymorphic_path(object)
106
end
117

12-
private
13-
14-
def object_default_link_target
15-
h.polymorphic_path(object)
8+
def external_link?
9+
false
1610
end
17-
end
11+
12+
end

app/decorators/community_news_decorator.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
class CommunityNewsDecorator < ApplicationDecorator
2+
include ::Linkable
3+
24
def detail(length: nil)
35
length ? body&.truncate(length) : body
46
end
57

8+
def external_url
9+
object.reference_url
10+
end
11+
612
def inactive?
713
!published?
814
end
Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,28 @@
1+
# app/decorators/concerns/linkable.rb
12
module Linkable
23
extend ActiveSupport::Concern
34

4-
included do
5-
# Override this in each model with something like:
6-
# def internal_url
7-
# Rails.application.routes.url_helpers.story_path(self)
8-
# end
9-
end
10-
115
def link_target
12-
if external_link?
13-
normalized_url(external_url)
14-
else
15-
default_link_target
16-
end
6+
external_link? ? normalized_url(external_url) : super
177
end
188

199
def external_link?
2010
external_url.present? && valid_external_url?(external_url)
2111
end
2212

23-
# Models must implement this method.
2413
def external_url
25-
raise NotImplementedError, "Models including Linkable must define #external_url"
14+
raise NotImplementedError, "#{self.class.name} must define #external_url"
2615
end
2716

2817
private
2918

19+
def default_link_target
20+
Rails.application.routes.url_helpers.polymorphic_path(self)
21+
end
22+
3023
def valid_external_url?(value)
3124
return false if value.blank?
3225

33-
# Only normalize *naked domains*, not scheme-bearing strings
3426
if value =~ /\A[\w.-]+\.[a-z]{2,}/i
3527
value = "https://#{value}" unless value =~ /\Ahttps?:\/\//i
3628
end
@@ -41,10 +33,6 @@ def valid_external_url?(value)
4133
false
4234
end
4335

44-
def default_link_target
45-
Rails.application.routes.url_helpers.polymorphic_path(self)
46-
end
47-
4836
def normalized_url(value)
4937
return "" if value.blank?
5038
value =~ /\Ahttp(s)?:\/\// ? value : "https://#{value}"

0 commit comments

Comments
 (0)