diff --git a/.gitignore b/.gitignore
index c66b3c339..f2b6e9d55 100755
--- a/.gitignore
+++ b/.gitignore
@@ -49,3 +49,7 @@ coverage
.byebug_history
.envrc
.yarnrc
+
+config/settings.local.yml
+config/settings/*.local.yml
+config/environments/*.local.yml
diff --git a/Gemfile b/Gemfile
index 45dc996f0..b0565048a 100644
--- a/Gemfile
+++ b/Gemfile
@@ -80,6 +80,9 @@ gem 'ed25519', '~> 1.2.4'
gem 'bcrypt_pbkdf', '~> 1.0.0'
# Error tracking
gem 'bugsnag', '~> 6.26'
+# Configure environment settings
+gem 'config', '~> 5.5.2'
+
group :development, :test do
# Access an IRB console on exception pages or by using <%= console %> anywhere in the code.
@@ -123,4 +126,4 @@ group :test do
gem 'rspec-retry', '~> 0.6.0'
# Stub http requests
gem 'webmock', '~> 3.14.0'
-end
\ No newline at end of file
+end
diff --git a/Gemfile.lock b/Gemfile.lock
index 28b42aee6..63bf4b283 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -116,6 +116,9 @@ GEM
cocoon (1.2.15)
colorize (0.8.1)
concurrent-ruby (1.3.3)
+ config (5.5.2)
+ deep_merge (~> 1.2, >= 1.2.1)
+ ostruct
connection_pool (2.4.1)
countries (5.3.1)
unaccent (~> 0.3)
@@ -124,6 +127,7 @@ GEM
crass (1.0.6)
database_cleaner (1.8.5)
date (3.3.4)
+ deep_merge (1.2.2)
devise (4.9.0)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
@@ -252,6 +256,7 @@ GEM
version_gem (~> 1.1)
okcomputer (1.18.4)
orm_adapter (0.5.0)
+ ostruct (0.6.1)
parallel (1.25.1)
parser (3.3.3.0)
ast (~> 2.4.1)
@@ -480,6 +485,7 @@ DEPENDENCIES
carrierwave (~> 2.2.5)
clamby
cocoon (~> 1.2.0)
+ config (~> 5.5.2)
country_select!
database_cleaner (~> 1.8.0)
devise (>= 4.7.1)
diff --git a/README.md b/README.md
index 5ac07d05f..fea641e3f 100755
--- a/README.md
+++ b/README.md
@@ -75,6 +75,17 @@ Any PRs merged to main will automatically be deployed to QA.
To initiate a production deploy, create a new release. Then, merge the automatically created PR in the config repo: https://github.com/psu-libraries/etda-config
+### Config
+The [config](https://rubygems.org/gems/config) gem provides a means for adding ad-hoc config as needed.
+The file `config/settings.local.yml` is not tracked in git.
+Currently this is used to add announcements quickly. By adding values such as:
+```rb
+# Strings
+show_annoucements: true
+announcement:
+ message: "Place your important message here"
+```
+
## LionPath Integration
### Imports
diff --git a/app/views/shared/_announcements.html.erb b/app/views/shared/_announcements.html.erb
new file mode 100644
index 000000000..ca45b7dd0
--- /dev/null
+++ b/app/views/shared/_announcements.html.erb
@@ -0,0 +1,7 @@
+
+
+
+
<%= sanitize Settings.announcement&.message %>
+
+
+
diff --git a/app/views/shared/_header.html.erb b/app/views/shared/_header.html.erb
index acb5e5df8..86a9b3097 100644
--- a/app/views/shared/_header.html.erb
+++ b/app/views/shared/_header.html.erb
@@ -1,4 +1,5 @@
+ <%= render partial: 'shared/announcements' if Settings.show_announcements %>
@@ -15,4 +16,5 @@
<%= render partial: '/matomo_analytics' if ENV.fetch('HOSTNAME', 'dev').match(/^etda-wf-/).present? %>
<%= render partial: 'shared/nav_bar' %>
+
diff --git a/config/initializers/config.rb b/config/initializers/config.rb
new file mode 100644
index 000000000..a5a6120a9
--- /dev/null
+++ b/config/initializers/config.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+Config.setup do |config|
+ # Name of the constant exposing loaded settings
+ config.const_name = 'Settings'
+
+ # Ability to remove elements of the array set in earlier loaded settings file. For example value: '--'.
+ #
+ # config.knockout_prefix = nil
+
+ # Overwrite an existing value when merging a `nil` value.
+ # When set to `false`, the existing value is retained after merge.
+ #
+ # config.merge_nil_values = true
+
+ # Overwrite arrays found in previously loaded settings file. When set to `false`, arrays will be merged.
+ #
+ # config.overwrite_arrays = true
+
+ # Load environment variables from the `ENV` object and override any settings defined in files.
+ #
+ config.use_env = true
+
+ # Define ENV variable prefix deciding which variables to load into config.
+ #
+ # Reading variables from ENV is case-sensitive. If you define lowercase value below, ensure your ENV variables are
+ # prefixed in the same way.
+ #
+ # When not set it defaults to `config.const_name`.
+ #
+ config.env_prefix = 'SETTINGS'
+
+ # What string to use as level separator for settings loaded from ENV variables. Default value of '.' works well
+ # with Heroku, but you might want to change it for example for '__' to easy override settings from command line, where
+ # using dots in variable names might not be allowed (eg. Bash).
+ #
+ config.env_separator = '__'
+
+ # Ability to process variables names:
+ # * nil - no change
+ # * :downcase - convert to lower case
+ #
+ # config.env_converter = :downcase
+
+ # Parse numeric values as integers instead of strings.
+ #
+ # config.env_parse_values = true
+
+ # Validate presence and type of specific config values. Check https://github.com/dry-rb/dry-validation for details.
+ #
+ # config.schema do
+ # required(:name).filled
+ # required(:age).maybe(:int?)
+ # required(:email).filled(format?: EMAIL_REGEX)
+ # end
+end
diff --git a/spec/integration/announcement_spec.rb b/spec/integration/announcement_spec.rb
new file mode 100644
index 000000000..0e5ee24cf
--- /dev/null
+++ b/spec/integration/announcement_spec.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe 'Announcement', :js do
+ context 'when show_announcements is false' do
+ before do
+ Settings.add_source!(
+ {
+ show_announcements: false,
+ announcement: nil
+ }
+ )
+ Settings.reload!
+ end
+
+ it 'does not display an announcement on top' do
+ visit root_path
+ expect(page).to have_no_css '.announcement'
+ end
+ end
+
+ context 'when show_announcement is nil' do
+ before do
+ Settings.add_source!(
+ {
+ show_announcements: nil,
+ announcement: nil
+ }
+ )
+ Settings.reload!
+ end
+
+ it 'does not display an announcement on top' do
+ visit root_path
+ expect(page).to have_no_css '.announcement'
+ end
+ end
+
+ context 'when show_announcement is true' do
+ before do
+ Settings.add_source!(
+ {
+ show_announcements: true,
+ announcement: {
+ message: 'ETDA is for cool kids'
+ }
+ }
+ )
+ Settings.reload!
+ end
+
+ it 'displays the given announcement' do
+ visit root_path
+ expect(page).to have_css '.announcement'
+ expect(page).to have_content 'ETDA is for cool kids'
+ end
+ end
+end