├── log └── .keep ├── app ├── mailers │ └── .keep ├── models │ ├── .keep │ ├── concerns │ │ └── .keep │ ├── fixture.rb │ └── component.rb ├── assets │ ├── images │ │ └── .keep │ └── stylesheets │ │ ├── preview.css.scss │ │ ├── _component.scss │ │ └── application.scss ├── controllers │ ├── concerns │ │ └── .keep │ ├── about_controller.rb │ ├── welcome_controller.rb │ ├── components_controller.rb │ ├── application_controller.rb │ └── fixtures_controller.rb ├── helpers │ ├── welcome_helper.rb │ ├── component_helper.rb │ └── application_helper.rb └── views │ ├── components │ ├── _preview.html.erb │ ├── index.html.erb │ ├── _call.html.erb │ ├── _list.html.erb │ ├── preview.html │ └── show.html.erb │ ├── fixtures │ ├── preview.html.erb │ ├── show.html.erb │ └── index.html.erb │ ├── layouts │ ├── preview.html.erb │ └── application.html.erb │ ├── welcome │ └── index.html.erb │ └── about │ └── index.html.erb ├── lib ├── assets │ └── .keep └── tasks │ └── .keep ├── public ├── favicon.ico ├── robots.txt ├── 500.html ├── 422.html └── 404.html ├── test ├── helpers │ ├── .keep │ ├── welcome_helper_test.rb │ └── component_helper_test.rb ├── mailers │ └── .keep ├── models │ └── .keep ├── controllers │ ├── .keep │ ├── about_controller_test.rb │ ├── welcome_controller_test.rb │ ├── components_controller_test.rb │ └── fixtures_controller_test.rb ├── fixtures │ └── .keep ├── integration │ └── .keep └── test_helper.rb ├── .ruby-version ├── vendor └── assets │ ├── stylesheets │ ├── .keep │ └── prism.css │ └── javascripts │ └── prism.js ├── startup.sh ├── bin ├── rake ├── bundle ├── rails ├── spring └── setup ├── config.ru ├── config ├── initializers │ ├── cookies_serializer.rb │ ├── session_store.rb │ ├── mime_types.rb │ ├── filter_parameter_logging.rb │ ├── assets.rb │ ├── wrap_parameters.rb │ ├── backtrace_silencers.rb │ └── inflections.rb ├── environment.rb ├── boot.rb ├── locales │ └── en.yml ├── routes.rb ├── secrets.yml ├── application.rb └── environments │ ├── development.rb │ ├── test.rb │ └── production.rb ├── Rakefile ├── db └── seeds.rb ├── .travis.yml ├── app.json ├── .gitignore ├── Gemfile ├── README.md └── Gemfile.lock /log/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/mailers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/models/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/assets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/tasks/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/helpers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/mailers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/models/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.3.0 2 | -------------------------------------------------------------------------------- /app/assets/images/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/controllers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/integration/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/models/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/controllers/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /startup.sh: -------------------------------------------------------------------------------- 1 | bundle exec rails s -b 0.0.0.0 -p 3113 2 | -------------------------------------------------------------------------------- /app/helpers/welcome_helper.rb: -------------------------------------------------------------------------------- 1 | module WelcomeHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/component_helper.rb: -------------------------------------------------------------------------------- 1 | module ComponentHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative '../config/boot' 3 | require 'rake' 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /app/controllers/about_controller.rb: -------------------------------------------------------------------------------- 1 | class AboutController < ApplicationController 2 | def index 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /test/helpers/welcome_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class WelcomeHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /test/helpers/component_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ComponentHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /app/controllers/welcome_controller.rb: -------------------------------------------------------------------------------- 1 | class WelcomeController < ApplicationController 2 | def index 3 | @components = Component.all 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path('../../config/application', __FILE__) 3 | require_relative '../config/boot' 4 | require 'rails/commands' 5 | -------------------------------------------------------------------------------- /app/views/components/_preview.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <%= render partial: "govuk_component/#{component.id}", locals: fixture.data %> 3 |
4 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Rails.application 5 | -------------------------------------------------------------------------------- /config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.action_dispatch.cookies_serializer = :json 4 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /app/views/components/index.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :header do %> 2 | Available Components 3 | <% end %> 4 | 5 | <%= render partial: "components/list", locals: {components: @components } %> 6 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | # Set up gems listed in the Gemfile. 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | 4 | require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) 5 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.session_store :cookie_store, key: '_govuk_component_guide_session' 4 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /test/controllers/about_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class AboutControllerTest < ActionController::TestCase 4 | test "should get index" do 5 | get :index 6 | assert_response :success 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/controllers/welcome_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class WelcomeControllerTest < ActionController::TestCase 4 | test "should get index" do 5 | get :index 6 | assert_response :success 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV['RAILS_ENV'] ||= 'test' 2 | require File.expand_path('../../config/environment', __FILE__) 3 | require 'rails/test_help' 4 | 5 | class ActiveSupport::TestCase 6 | # Add more helper methods to be used by all tests here... 7 | end 8 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require File.expand_path('../config/application', __FILE__) 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /app/views/components/_call.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <%= render partial: 'govuk_component/<%= component.id %>'<% if fixture.data? %>, locals: <%= fixture.pretty_data %><% end %> %> 3 |
4 | -------------------------------------------------------------------------------- /app/views/fixtures/preview.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :title do %> 2 | <%= @component.name %>: <%= @fixture.name %> preview 3 | <% end %> 4 | 5 |
6 | <%= render partial: "govuk_component/#{@component.id}", locals: @fixture.data %> 7 |
8 | -------------------------------------------------------------------------------- /app/models/fixture.rb: -------------------------------------------------------------------------------- 1 | Fixture = Struct.new(:id, :data) do 2 | def name 3 | id.humanize 4 | end 5 | 6 | def pretty_data 7 | JSON.pretty_generate(data).gsub('\\n', "\n ").gsub(/"(\w*)":/, '\1:').strip 8 | end 9 | 10 | def data? 11 | data.any? 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). 3 | # 4 | # Examples: 5 | # 6 | # cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) 7 | # Mayor.create(name: 'Emanuel', city: cities.first) 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | 3 | env: 4 | - PLEK_SERVICE_STATIC_URI=assets.digital.cabinet-office.gov.uk 5 | 6 | script: 7 | # Tests depend on an instance of `static` running, this needs to be stubbed 8 | # out at some point, in the mean time hit production :( 9 | # - bundle exec rake test 10 | - bundle exec govuk-lint-ruby app test config lib 11 | - bundle exec govuk-lint-sass app 12 | -------------------------------------------------------------------------------- /app/views/components/_list.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
    3 | <% components.each do |component| %> 4 |
  1. 5 |

    <%= component.name %>

    6 | <% if component.description %> 7 |

    <%= component.description %>

    8 | <% end %> 9 |
  2. 10 | <% end %> 11 |
12 |
13 | -------------------------------------------------------------------------------- /app/views/layouts/preview.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <%= yield :title %> - GOV.UK Component Guide 5 | <%= stylesheet_link_tag 'preview', media: 'all' %> 6 | <%= csrf_meta_tags %> 7 | 8 | 9 | 10 | 11 |
12 | <%= yield %> 13 |
14 | 15 | 16 | -------------------------------------------------------------------------------- /app/views/welcome/index.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :header do %> 2 | GOV.UK Publishing Component Guide 3 | <% end %> 4 | 5 | <% content_for :header_description do %> 6 |

Components are a way to share UI patterns between applications, without duplicating code, within the GOV.UK Publishing platform. Find out more

7 | <% end %> 8 | 9 | <%= render partial: "components/list", locals: {components: @components } %> 10 | -------------------------------------------------------------------------------- /config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = '1.0' 5 | 6 | # Precompile additional assets. 7 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. 8 | Rails.application.config.assets.precompile += %w(preview.css prism.js prism.css) 9 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] if respond_to?(:wrap_parameters) 9 | end 10 | -------------------------------------------------------------------------------- /app/views/components/preview.html: -------------------------------------------------------------------------------- 1 | <% content_for :title do %> 2 | <%= @component.name %> preview 3 | <% end %> 4 | 5 | <% @component.fixtures.each do |fixture| %> 6 |
7 |

<%= fixture.name %>

8 | <%= render partial: "govuk_component/#{@component.id}", locals: fixture.data %> 9 |
10 | <% end %> 11 | -------------------------------------------------------------------------------- /bin/spring: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'spring' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('spring', 'spring') 17 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /app/controllers/components_controller.rb: -------------------------------------------------------------------------------- 1 | require 'component' 2 | 3 | class ComponentsController < ApplicationController 4 | def show 5 | @component = Component.get(params[:id]) 6 | head :not_found if @component.nil? 7 | end 8 | 9 | def index 10 | @components = Component.all 11 | end 12 | 13 | def preview 14 | @component = Component.get(params[:component_id]) 15 | if @component.nil? 16 | head :not_found 17 | else 18 | render layout: 'preview' 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "govuk-component-guide", 3 | "scripts": { 4 | }, 5 | "env": { 6 | "GOVUK_APP_DOMAIN": "www.gov.uk", 7 | "PLEK_SERVICE_STATIC_URI": "https://assets.digital.cabinet-office.gov.uk/", 8 | "RACK_ENV": "production", 9 | "RAILS_ENV": "production", 10 | "SECRET_KEY_BASE": { 11 | "generator": "secret" 12 | } 13 | }, 14 | "addons": [ 15 | "heroku-postgresql" 16 | ], 17 | "buildpacks": [ 18 | { 19 | "url": "urn:buildpack:heroku/ruby" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | # Prevent CSRF attacks by raising an exception. 3 | # For APIs, you may want to use :null_session instead. 4 | protect_from_forgery with: :exception 5 | include Slimmer::GovukComponents 6 | include Slimmer::Headers 7 | 8 | before_action :set_custom_slimmer_headers 9 | 10 | private 11 | 12 | def set_custom_slimmer_headers 13 | set_slimmer_headers(report_a_problem: 'false', remove_search: true) 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile '~/.gitignore_global' 6 | 7 | # Ignore bundler config. 8 | /.bundle 9 | 10 | # Ignore the default SQLite database. 11 | /db/*.sqlite3 12 | /db/*.sqlite3-journal 13 | 14 | # Ignore all logfiles and tempfiles. 15 | /log/*.log 16 | /tmp 17 | -------------------------------------------------------------------------------- /test/controllers/components_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ComponentsControllerTest < ActionController::TestCase 4 | test "should get index" do 5 | get :index 6 | assert_response :success 7 | end 8 | 9 | test "should get show" do 10 | get :show, params: { id: 'title' } 11 | assert_response :success 12 | end 13 | 14 | test "should fail to get show" do 15 | # This component does not exist and should return a 404 error 16 | get :show, params: { id: 'test' } 17 | assert_response :missing 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /app/assets/stylesheets/preview.css.scss: -------------------------------------------------------------------------------- 1 | // `govuk_frontend_toolkit` 2 | @import "measurements"; 3 | @import "typography"; 4 | @import "colours"; 5 | 6 | html { 7 | background: $white; 8 | } 9 | 10 | .hide-header-and-footer { 11 | // scss-lint:disable IdSelector 12 | #global-header, 13 | #global-header-bar, 14 | #global-breadcrumb, 15 | #footer { 16 | display: none; 17 | } 18 | } 19 | 20 | .component-guide-preview { 21 | padding: 30px 0; 22 | 23 | .preview-title { 24 | margin-bottom: 1em; 25 | @include bold-16; 26 | 27 | a { 28 | color: $black; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/views/fixtures/show.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :header do %> 2 | <%= @component.name %>: <%= @fixture.name %> 3 | <% end %> 4 | 5 |
6 |

<%= @component.description %>

7 | 8 | <% if @component.body %> 9 | <%= @component.html_body %> 10 | <% end %> 11 | 12 |

How to call this component

13 | <%= render partial: "components/call", locals: { component: @component, fixture: @fixture } %> 14 | 15 |

How this component looks

16 | <%= render partial: "components/preview", locals: { component: @component, fixture: @fixture } %> 17 | 18 |
19 | -------------------------------------------------------------------------------- /test/controllers/fixtures_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class FixturesControllerTest < ActionController::TestCase 4 | test "should get index" do 5 | get :index, params: { component_id: 'title' } 6 | assert_response :success 7 | end 8 | 9 | test "should get show" do 10 | get :show, params: { component_id: 'title', id: 'default' } 11 | assert_response :success 12 | end 13 | 14 | test "should fail to get show" do 15 | # This fixture does not exist and should return a 404 error 16 | get :show, params: { component_id: 'title', id: 'test' } 17 | assert_response :missing 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /app/views/fixtures/index.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :header do %> 2 | <%= @component.name %>: Examples 3 | <% end %> 4 | 5 |
6 |

<%= @component.description %>

7 | 8 | <% if @component.body %> 9 | <%= @component.html_body %> 10 | <% end %> 11 | 12 | <% if @component.fixtures %> 13 |

All examples

14 |
    15 | <% @component.fixtures.each do |fixture| %> 16 |
  1. 17 | <%= fixture.name %> 18 |
  2. 19 | <% end %> 20 |
21 | <% end %> 22 | 23 |
24 | -------------------------------------------------------------------------------- /app/controllers/fixtures_controller.rb: -------------------------------------------------------------------------------- 1 | require 'component' 2 | 3 | class FixturesController < ApplicationController 4 | def show 5 | @fixture = component.fixtures.find { |f| 6 | f.id == params[:id] 7 | } 8 | head :not_found if @fixture.nil? 9 | end 10 | 11 | def index 12 | @fixtures = component.fixtures 13 | end 14 | 15 | def preview 16 | @fixture = component.fixtures.find { |f| 17 | f.id == params[:fixture_id] 18 | } 19 | if @fixture.nil? 20 | head :not_found 21 | else 22 | render layout: 'preview' 23 | end 24 | end 25 | 26 | private 27 | 28 | def component 29 | @component = Component.get(params[:component_id]) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'RESTful' 16 | # end 17 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # To learn more, please read the Rails Internationalization guide 20 | # available at http://guides.rubyonrails.org/i18n.html. 21 | 22 | en: 23 | hello: "Hello world" 24 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | root to: redirect('https://govuk-static.herokuapp.com/component-guide') 3 | 4 | get 'component', to: redirect("/components") 5 | get 'component/:id', to: redirect("/components/%{id}") 6 | 7 | get 'components/:component/fixtures/:example/preview', to: redirect('https://govuk-static.herokuapp.com/component-guide/%{component}/%{example}/preview') 8 | get 'components/:component/fixtures/:example', to: redirect('https://govuk-static.herokuapp.com/component-guide/%{component}/%{example}') 9 | get 'components/:component', to: redirect('https://govuk-static.herokuapp.com/component-guide/%{component}') 10 | 11 | # Catch all 12 | get '*path', to: redirect('https://govuk-static.herokuapp.com/component-guide') 13 | end 14 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'pathname' 3 | 4 | # path to your application root. 5 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) 6 | 7 | Dir.chdir APP_ROOT do 8 | # This script is a starting point to setup your application. 9 | # Add necessary setup steps to this file: 10 | 11 | puts "== Installing dependencies ==" 12 | system "gem install bundler --conservative" 13 | system "bundle check || bundle install" 14 | 15 | # puts "\n== Copying sample files ==" 16 | # unless File.exist?("config/database.yml") 17 | # system "cp config/database.yml.sample config/database.yml" 18 | # end 19 | 20 | puts "\n== Preparing database ==" 21 | system "bin/rake db:setup" 22 | 23 | puts "\n== Removing old logs and tempfiles ==" 24 | system "rm -f log/*" 25 | system "rm -rf tmp/cache" 26 | 27 | puts "\n== Restarting application server ==" 28 | system "touch tmp/restart.txt" 29 | end 30 | -------------------------------------------------------------------------------- /app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <%= yield :header %> - GOV.UK Component Guide 5 | <%= stylesheet_link_tag 'application', media: 'all' %> 6 | <%= stylesheet_link_tag 'prism', media: 'all' %> 7 | <%= javascript_include_tag 'prism' %> 8 | <%= csrf_meta_tags %> 9 | 10 | 11 | 12 |
13 |
14 | 17 |
18 |
19 | 20 |
21 | 22 |

<%= yield :header %>

23 | <% if content_for?(:header_description) %> 24 |
<%= yield :header_description %>
25 | <% end %> 26 | 27 | <%= yield %> 28 | 29 |
30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | ruby File.read('.ruby-version').strip 4 | 5 | # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' 6 | gem 'rails', '5.0.4' 7 | # Use SCSS for stylesheets 8 | gem 'sass-rails', '~> 5.0.6' 9 | # Use Uglifier as compressor for JavaScript assets 10 | gem 'uglifier', '>= 1.3.0' 11 | # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder 12 | gem 'jbuilder', '~> 2.0' 13 | 14 | # bundle exec rake doc:rails generates the API under doc/api. 15 | gem 'sdoc', '~> 0.4.0', group: :doc 16 | 17 | gem 'kramdown', '1.5' 18 | 19 | gem 'slimmer', '~> 11.0.0' 20 | 21 | gem 'govuk_frontend_toolkit', '4.10.0' 22 | gem 'rest-client' 23 | 24 | group :production do 25 | gem 'rails_stdout_logging' 26 | end 27 | 28 | group :development do 29 | gem 'spring' 30 | gem 'pry' 31 | gem 'better_errors' 32 | gem 'binding_of_caller' 33 | end 34 | 35 | group :development, :test do 36 | gem 'govuk-lint', '2.1.0' 37 | end 38 | -------------------------------------------------------------------------------- /config/secrets.yml: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rake secret` to generate a secure secret key. 9 | 10 | # Make sure the secrets in this file are kept private 11 | # if you're sharing your code publicly. 12 | 13 | development: 14 | secret_key_base: c9db14f9f8ee4f4ed2df4408e402710f03370a3bb5df426e0910be29df6564f8a24509c8a6a3ea891d7543f4340a162e519f5cf8594234e6e6c9dd2d512bce68 15 | 16 | test: 17 | secret_key_base: 862f1afa4b098929eff86d2d69fd5310d9770289e926e04722779950bac70e24f167ff8f68b86fb5927d0f4c164394e427a52fcdb9a8c8944f5be33301cf79ae 18 | 19 | # Do not keep production secrets in the repository, 20 | # instead read values from the environment. 21 | production: 22 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> 23 | -------------------------------------------------------------------------------- /app/models/component.rb: -------------------------------------------------------------------------------- 1 | Component = Struct.new(:id, :name, :description, :body, :fixtures) do 2 | def self.get(id) 3 | all.find { |component| component.id == id } 4 | end 5 | 6 | def self.all 7 | Rails.cache.fetch('component_doc', expires_in: 15.minute, force: !Rails.env.production?) { 8 | fetch_component_doc.map { |component| 9 | build(component) 10 | } 11 | } 12 | end 13 | 14 | def self.build(component) 15 | fixtures = component[:fixtures].map { |id, data| 16 | Fixture.new(id.to_s, data) 17 | } 18 | self.new(component[:id], component[:name], component[:description], component[:body], fixtures) 19 | end 20 | 21 | def self.component_doc_url 22 | Plek.current.find('static') + '/templates/govuk_component/docs' 23 | end 24 | 25 | def self.fetch_component_doc 26 | begin 27 | JSON.parse( 28 | RestClient.get(component_doc_url).body, 29 | symbolize_names: true 30 | ) 31 | rescue RestClient::BadGateway => e 32 | raise "#{e} from #{Plek.current.find('static')} - is static running?" 33 | end 34 | end 35 | 36 | def fixture 37 | fixtures.first 38 | end 39 | 40 | def html_body 41 | Kramdown::Document.new(body).to_html.html_safe 42 | end 43 | 44 | def other_fixtures 45 | fixtures.slice(1..-1) 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | # Pick the frameworks you want: 4 | require "active_model/railtie" 5 | # require "active_record/railtie" 6 | require "action_controller/railtie" 7 | require "action_mailer/railtie" 8 | require "action_view/railtie" 9 | require "sprockets/railtie" 10 | require "rails/test_unit/railtie" 11 | 12 | # Require the gems listed in Gemfile, including any gems 13 | # you've limited to :test, :development, or :production. 14 | Bundler.require(*Rails.groups) 15 | 16 | module GovukComponentGuide 17 | class Application < Rails::Application 18 | # Settings in config/environments/* take precedence over those specified here. 19 | # Application configuration should go into files in config/initializers 20 | # -- all .rb files in that directory are automatically loaded. 21 | 22 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 23 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 24 | # config.time_zone = 'Central Time (US & Canada)' 25 | 26 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 27 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 28 | # config.i18n.default_locale = :de 29 | config.cache_store = :memory_store 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /app/views/about/index.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :header do %> 2 | About 3 | <% end %> 4 | 5 |
6 | 7 |

What's a component?

8 | 9 |

A simple way to share UI patterns between applications without having to duplicate code

10 | 11 |

Components hook in to your application template path and will allow you to insert a partial, which will handle it's own markup and styling.

12 | 13 |

You can can consider them an abstraction/blackbox around a piece of UI, where you don't want to care about how it works, just that it does.

14 | 15 |

How do I use one?

16 | 17 |

You need to be using Slimmer in your Rails app, and add include Slimmer::GovukComponents to your ApplicationController.

18 | 19 |
20 | 21 | class ApplicationController < ActionController::Base 22 | include Slimmer::GovukComponents 23 | end 24 | 25 |
26 | 27 |

From a template call a partial scoped to govuk_component/ followed by the component name (available components).

28 | 29 |
30 | <%= render partial: 'govuk_component/example_component' %> 31 |
32 |
33 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Do not eager load code on boot. 10 | config.eager_load = false 11 | 12 | # Show full error reports and disable caching. 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send. 17 | config.action_mailer.raise_delivery_errors = false 18 | 19 | # Print deprecation notices to the Rails logger. 20 | config.active_support.deprecation = :log 21 | 22 | # Debug mode disables concatenation and preprocessing of assets. 23 | # This option may cause significant delays in view rendering with a large 24 | # number of complex assets. 25 | config.assets.debug = true 26 | 27 | # Adds additional error checking when serving assets at runtime. 28 | # Checks for improperly declared sprockets dependencies. 29 | # Raises helpful error messages. 30 | config.assets.raise_runtime_errors = true 31 | 32 | # Raises error for missing translations 33 | # config.action_view.raise_on_missing_translations = true 34 | end 35 | -------------------------------------------------------------------------------- /app/assets/stylesheets/_component.scss: -------------------------------------------------------------------------------- 1 | .component-show { 2 | 3 | .component-doc { 4 | @include core-16; 5 | 6 | p { 7 | margin: $gutter-half 0; 8 | } 9 | 10 | ol, 11 | ul { 12 | margin: 0 0 0 $gutter; 13 | } 14 | 15 | h3 { 16 | margin: $gutter 0 $gutter-half; 17 | @include bold-19; 18 | } 19 | } 20 | 21 | .component-guide-preview { 22 | padding: ($gutter * 1.5) $gutter $gutter; 23 | border: 1px solid $border-colour; 24 | position: relative; 25 | 26 | &:before { 27 | @include core-14; 28 | content: "EXAMPLE"; 29 | position: absolute; 30 | top: 0; 31 | left: 0; 32 | padding: 0.21053em 0.78947em; 33 | background: $border-colour; 34 | color: $white; 35 | } 36 | 37 | div[class^="govuk-"] { 38 | &:hover { 39 | outline: 1px solid $border-color; 40 | box-shadow: 0 0 10px $border-color; 41 | } 42 | } 43 | } 44 | 45 | .fixtures { 46 | margin-top: $gutter * 2; 47 | 48 | .fixtures-title { 49 | @include bold-27; 50 | margin: $gutter 0; 51 | 52 | small { 53 | @include bold-16; 54 | } 55 | } 56 | 57 | .component-fixture { 58 | margin: 0 0 $gutter * 2; 59 | 60 | .fixture-title { 61 | @include bold-24; 62 | margin: $gutter-half 0; 63 | 64 | small { 65 | @include bold-16; 66 | } 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /app/views/components/show.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :header do %> 2 | <%= @component.name %> 3 | <% end %> 4 | 5 | <% content_for :header_description do %> 6 |

<%= @component.description %>

7 | <% end %> 8 | 9 |
10 |
11 | <% if @component.body %> 12 | <%= @component.html_body %> 13 | <% end %> 14 | 15 |

How to call this component

16 | <%= render partial: "components/call", locals: { component: @component, fixture: @component.fixture } %> 17 | 18 |

How this component looks

19 |
20 | 21 | <%= render partial: "components/preview", locals: { component: @component, fixture: @component.fixture } %> 22 | 23 | <% if @component.other_fixtures.any? %> 24 |
25 |

Other examples (preview all)

26 | 27 | <% @component.other_fixtures.each do |fixture| %> 28 |
29 |

30 | <%= fixture.name %> 31 | (preview) 32 |

33 | 34 | <%= render partial: "components/call", locals: { component: @component, fixture: fixture } %> 35 | 36 | <%= render partial: "components/preview", locals: { component: @component, fixture: fixture } %> 37 |
38 | <% end %> 39 |
40 | <% end %> 41 | 42 |
43 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.scss: -------------------------------------------------------------------------------- 1 | // `govuk_frontend_toolkit` 2 | @import "measurements"; 3 | @import "grid_layout"; 4 | @import "typography"; 5 | @import "colours"; 6 | 7 | $prism-background: #f5f2f0; 8 | $border-color: #ccc; 9 | 10 | // App modules 11 | @import "component"; 12 | 13 | .code-block { 14 | margin: 30px 0; 15 | padding: $gutter; 16 | @extend %outdent-to-full-width; 17 | overflow: scroll; 18 | max-height: 300px; 19 | 20 | // Match Prism styles to avoid a flash as it renders 21 | background: $prism-background; 22 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 23 | 24 | &[contenteditable]:hover { 25 | cursor: text; 26 | } 27 | 28 | code { 29 | display: block; 30 | } 31 | } 32 | 33 | // scss-lint:disable IdSelector 34 | #footer { 35 | display: none; 36 | } 37 | 38 | #wrapper { 39 | padding-bottom: $gutter * 4; 40 | } 41 | // scss-lint:enable IdSelector 42 | 43 | .govuk-component-guide-title { 44 | @include bold-36; 45 | margin: $gutter 0; 46 | } 47 | 48 | .govuk-component-guide-title-description { 49 | margin-bottom: $gutter; 50 | 51 | p { 52 | @include core-19; 53 | max-width: 740px; 54 | } 55 | } 56 | 57 | .govuk-component-guide-header { 58 | @include core-19; 59 | 60 | margin-bottom: $gutter; 61 | padding-top: $gutter / 2; 62 | padding-bottom: $gutter / 2; 63 | 64 | border-bottom: 1px solid $border-color; 65 | 66 | .app-name { 67 | margin: 0; 68 | } 69 | } 70 | 71 | .component-list { 72 | li { 73 | @include core-19; 74 | margin-bottom: $gutter-half; 75 | } 76 | } 77 | 78 | .about-components { 79 | h2 { 80 | @include bold-24; 81 | margin: 30px 0 20px; 82 | } 83 | 84 | p { 85 | margin-bottom: 20px; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

We're sorry, but something went wrong.

62 |
63 |

If you are the application owner check the logs for more information.

64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The change you wanted was rejected.

62 |

Maybe you tried to change something you didn't have access to.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The page you were looking for doesn't exist.

62 |

You may have mistyped the address or the page may have moved.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Do not eager load code on boot. This avoids loading your whole application 11 | # just for the purpose of running a single test. If you are using a tool that 12 | # preloads Rails for running tests, you may have to set it to true. 13 | config.eager_load = false 14 | 15 | # Configure static asset server for tests with Cache-Control for performance. 16 | config.public_file_server.enabled = true 17 | config.public_file_server.headers = { 'Cache-Control' => 'public, max-age=3600' } 18 | 19 | # Show full error reports and disable caching. 20 | config.consider_all_requests_local = true 21 | config.action_controller.perform_caching = false 22 | 23 | # Raise exceptions instead of rendering exception templates. 24 | config.action_dispatch.show_exceptions = false 25 | 26 | # Disable request forgery protection in test environment. 27 | config.action_controller.allow_forgery_protection = false 28 | 29 | # Tell Action Mailer not to deliver emails to the real world. 30 | # The :test delivery method accumulates sent emails in the 31 | # ActionMailer::Base.deliveries array. 32 | config.action_mailer.delivery_method = :test 33 | 34 | # Print deprecation notices to the stderr. 35 | config.active_support.deprecation = :stderr 36 | 37 | # Raises error for missing translations 38 | # config.action_view.raise_on_missing_translations = true 39 | 40 | config.active_support.test_order = :random 41 | end 42 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/prism.css: -------------------------------------------------------------------------------- 1 | /* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+scss+ruby */ 2 | /** 3 | * prism.js default theme for JavaScript, CSS and HTML 4 | * Based on dabblet (http://dabblet.com) 5 | * @author Lea Verou 6 | */ 7 | 8 | code[class*="language-"], 9 | pre[class*="language-"] { 10 | color: black; 11 | text-shadow: 0 1px white; 12 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 13 | direction: ltr; 14 | text-align: left; 15 | white-space: pre; 16 | word-spacing: normal; 17 | word-break: normal; 18 | line-height: 1.5; 19 | 20 | -moz-tab-size: 4; 21 | -o-tab-size: 4; 22 | tab-size: 4; 23 | 24 | -webkit-hyphens: none; 25 | -moz-hyphens: none; 26 | -ms-hyphens: none; 27 | hyphens: none; 28 | } 29 | 30 | pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, 31 | code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { 32 | text-shadow: none; 33 | background: #b3d4fc; 34 | } 35 | 36 | pre[class*="language-"]::selection, pre[class*="language-"] ::selection, 37 | code[class*="language-"]::selection, code[class*="language-"] ::selection { 38 | text-shadow: none; 39 | background: #b3d4fc; 40 | } 41 | 42 | @media print { 43 | code[class*="language-"], 44 | pre[class*="language-"] { 45 | text-shadow: none; 46 | } 47 | } 48 | 49 | /* Code blocks */ 50 | pre[class*="language-"] { 51 | padding: 1em; 52 | margin: .5em 0; 53 | overflow: auto; 54 | } 55 | 56 | :not(pre) > code[class*="language-"], 57 | pre[class*="language-"] { 58 | background: #f5f2f0; 59 | } 60 | 61 | /* Inline code */ 62 | :not(pre) > code[class*="language-"] { 63 | padding: .1em; 64 | border-radius: .3em; 65 | } 66 | 67 | .token.comment, 68 | .token.prolog, 69 | .token.doctype, 70 | .token.cdata { 71 | color: slategray; 72 | } 73 | 74 | .token.punctuation { 75 | color: #999; 76 | } 77 | 78 | .namespace { 79 | opacity: .7; 80 | } 81 | 82 | .token.property, 83 | .token.tag, 84 | .token.boolean, 85 | .token.number, 86 | .token.constant, 87 | .token.symbol, 88 | .token.deleted { 89 | color: #905; 90 | } 91 | 92 | .token.selector, 93 | .token.attr-name, 94 | .token.string, 95 | .token.char, 96 | .token.builtin, 97 | .token.inserted { 98 | color: #690; 99 | } 100 | 101 | .token.operator, 102 | .token.entity, 103 | .token.url, 104 | .language-css .token.string, 105 | .style .token.string, 106 | .token.variable { 107 | color: #a67f59; 108 | background: hsla(0, 0%, 100%, .5); 109 | } 110 | 111 | .token.atrule, 112 | .token.attr-value, 113 | .token.keyword { 114 | color: #07a; 115 | } 116 | 117 | .token.function { 118 | color: #DD4A68; 119 | } 120 | 121 | .token.regex, 122 | .token.important { 123 | color: #e90; 124 | } 125 | 126 | .token.important { 127 | font-weight: bold; 128 | } 129 | 130 | .token.entity { 131 | cursor: help; 132 | } 133 | 134 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GOV.UK Component Guide 2 | 3 | **Component guides now live within applications and are generated using the [govuk_publishing_components gem](https://github.com/alphagov/govuk_publishing_components). This application is being retired.** 4 | 5 | **A list of all component guides is available here: https://docs.publishing.service.gov.uk/manual/components.html. Static components are listed here: https://govuk-static.herokuapp.com/component-guide/** 6 | 7 | [![Build Status](https://travis-ci.org/alphagov/govuk-component-guide.svg)](https://travis-ci.org/alphagov/govuk-component-guide) 8 | 9 | A living style guide and documentation for GOV.UK Components — A new approach to sharing UI patterns between applications without having to duplicate code. 10 | 11 | ## Caveats 12 | 13 | It's still in it's early stages, many features are missing or incomplete, and documentation may not be 100% accurate. 14 | 15 | It depends on [Slimmer](https://github.com/alphagov/slimmer) and makes API calls to [Static](https://github.com/alphagov/static). 16 | 17 | ## Installation 18 | 19 | It's a pretty standard Rails app, clone it, `bundle` it. 20 | 21 | ## Running 22 | 23 | ``` 24 | $ PLEK_SERVICE_STATIC_URI=assets.digital.cabinet-office.gov.uk ./startup.sh 25 | ``` 26 | 27 | If running on a VM, then Rails needs to be bound to `0.0.0.0` rather than localhost so that it can be accessed outside of the VM. This is if using `startup.sh` but if running `bundle exec rails s` yourself you'll need to bind the port manually. 28 | 29 | The application will start on port `3113`, so to access it visit [0.0.0.0:3113](http://0.0.0.0:3113/) or [dev.gov.uk:3113](http://dev.gov.uk:3113) on a VM. 30 | 31 | The `PLEK_SERVICE_STATIC_URI` environment variable points to a public instance of [alphagov/static](https://github.com/alphagov/static) - This is where the component documentation used to generate the dynamic parts of this guide is fetched from. Pointing at 32 | different static hosts may show different components. 33 | 34 | ## Running against local static 35 | 36 | If you'd like to run the component guide against a different version of static, for example, where you've added, or made changes to, components, you'll need to run a copy of static locally. 37 | 38 | To get a local copy of [alphagov/static](https://github.com/alphagov/static), follow the installation and local running instructions there, then run the component guide with this command: 39 | 40 | ``` 41 | $ PLEK_SERVICE_STATIC_URI=http://0.0.0.0:3013 ./startup.sh 42 | ``` 43 | 44 | ## Deployment 45 | 46 | The app is deployed to a [Heroku instance](https://dashboard.heroku.com/apps/govuk-component-guide/) and is continuously deployed, updating whenever `master` changes and CI passes. 47 | 48 | To access the Heroku admin, add yourself through the shared `heroku@digital.cabinet-office.gov.uk` account, or ask a [contributor](https://github.com/alphagov/govuk-component-guide/graphs/contributors) to add you. 49 | 50 | ### Environment vars 51 | 52 | These are required when running a production environment 53 | 54 | - `PLEK_SERVICE_STATIC_URI` - as above. 55 | - `GOVUK_APP_DOMAIN`- set to `www.gov.uk` 56 | -------------------------------------------------------------------------------- /config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # Code is not reloaded between requests. 5 | config.cache_classes = true 6 | 7 | # Eager load code on boot. This eager loads most of Rails and 8 | # your application in memory, allowing both threaded web servers 9 | # and those relying on copy on write to perform better. 10 | # Rake tasks automatically ignore this option for performance. 11 | config.eager_load = true 12 | 13 | # Full error reports are disabled and caching is turned on. 14 | config.consider_all_requests_local = false 15 | config.action_controller.perform_caching = true 16 | 17 | # Enable Rack::Cache to put a simple HTTP cache in front of your application 18 | # Add `rack-cache` to your Gemfile before enabling this. 19 | # For large-scale production use, consider using a caching reverse proxy like nginx, varnish or squid. 20 | # config.action_dispatch.rack_cache = true 21 | 22 | # Disable Rails's static asset server (Apache or nginx will already do this). 23 | config.public_file_server.enabled = true 24 | 25 | # Compress JavaScripts and CSS. 26 | config.assets.js_compressor = :uglifier 27 | # config.assets.css_compressor = :sass 28 | 29 | # Do not fallback to assets pipeline if a precompiled asset is missed. 30 | config.assets.compile = false 31 | 32 | # Generate digests for assets URLs. 33 | config.assets.digest = true 34 | 35 | # `config.assets.precompile` has moved to config/initializers/assets.rb 36 | 37 | # Specifies the header that your server uses for sending files. 38 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache 39 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx 40 | 41 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 42 | # config.force_ssl = true 43 | 44 | # Set to :debug to see everything in the log. 45 | config.log_level = :debug 46 | 47 | # Prepend all log lines with the following tags. 48 | # config.log_tags = [ :subdomain, :uuid ] 49 | 50 | # Use a different logger for distributed setups. 51 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) 52 | 53 | # Use a different cache store in production. 54 | # config.cache_store = :mem_cache_store 55 | 56 | # Enable serving of images, stylesheets, and JavaScripts from an asset server. 57 | # config.action_controller.asset_host = "http://assets.example.com" 58 | 59 | # Precompile additional assets. 60 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. 61 | # config.assets.precompile += %w( search.js ) 62 | 63 | # Ignore bad email addresses and do not raise email delivery errors. 64 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 65 | # config.action_mailer.raise_delivery_errors = false 66 | 67 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 68 | # the I18n.default_locale when a translation cannot be found). 69 | config.i18n.fallbacks = true 70 | 71 | # Send deprecation notices to registered listeners. 72 | config.active_support.deprecation = :notify 73 | 74 | # Disable automatic flushing of the log to improve performance. 75 | # config.autoflush_log = false 76 | 77 | # Use default logging formatter so that PID and timestamp are not suppressed. 78 | config.log_formatter = ::Logger::Formatter.new 79 | end 80 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | actioncable (5.0.4) 5 | actionpack (= 5.0.4) 6 | nio4r (>= 1.2, < 3.0) 7 | websocket-driver (~> 0.6.1) 8 | actionmailer (5.0.4) 9 | actionpack (= 5.0.4) 10 | actionview (= 5.0.4) 11 | activejob (= 5.0.4) 12 | mail (~> 2.5, >= 2.5.4) 13 | rails-dom-testing (~> 2.0) 14 | actionpack (5.0.4) 15 | actionview (= 5.0.4) 16 | activesupport (= 5.0.4) 17 | rack (~> 2.0) 18 | rack-test (~> 0.6.3) 19 | rails-dom-testing (~> 2.0) 20 | rails-html-sanitizer (~> 1.0, >= 1.0.2) 21 | actionview (5.0.4) 22 | activesupport (= 5.0.4) 23 | builder (~> 3.1) 24 | erubis (~> 2.7.0) 25 | rails-dom-testing (~> 2.0) 26 | rails-html-sanitizer (~> 1.0, >= 1.0.3) 27 | activejob (5.0.4) 28 | activesupport (= 5.0.4) 29 | globalid (>= 0.3.6) 30 | activemodel (5.0.4) 31 | activesupport (= 5.0.4) 32 | activerecord (5.0.4) 33 | activemodel (= 5.0.4) 34 | activesupport (= 5.0.4) 35 | arel (~> 7.0) 36 | activesupport (5.0.4) 37 | concurrent-ruby (~> 1.0, >= 1.0.2) 38 | i18n (~> 0.7) 39 | minitest (~> 5.1) 40 | tzinfo (~> 1.1) 41 | arel (7.1.4) 42 | ast (2.3.0) 43 | better_errors (2.1.1) 44 | coderay (>= 1.0.0) 45 | erubis (>= 2.6.6) 46 | rack (>= 0.9.0) 47 | binding_of_caller (0.7.2) 48 | debug_inspector (>= 0.0.1) 49 | builder (3.2.3) 50 | coderay (1.1.1) 51 | concurrent-ruby (1.0.5) 52 | debug_inspector (0.0.3) 53 | domain_name (0.5.20170404) 54 | unf (>= 0.0.5, < 1.0.0) 55 | erubis (2.7.0) 56 | execjs (2.7.0) 57 | globalid (0.4.0) 58 | activesupport (>= 4.2.0) 59 | govuk-lint (2.1.0) 60 | rubocop (~> 0.43.0) 61 | scss_lint 62 | govuk_frontend_toolkit (4.10.0) 63 | rails (>= 3.1.0) 64 | sass (>= 3.2.0) 65 | http-cookie (1.0.3) 66 | domain_name (~> 0.5) 67 | i18n (0.8.6) 68 | jbuilder (2.7.0) 69 | activesupport (>= 4.2.0) 70 | multi_json (>= 1.2) 71 | json (1.8.6) 72 | kramdown (1.5.0) 73 | loofah (2.0.3) 74 | nokogiri (>= 1.5.9) 75 | mail (2.6.6) 76 | mime-types (>= 1.16, < 4) 77 | method_source (0.8.2) 78 | mime-types (3.1) 79 | mime-types-data (~> 3.2015) 80 | mime-types-data (3.2016.0521) 81 | mini_portile2 (2.2.0) 82 | minitest (5.10.3) 83 | multi_json (1.12.1) 84 | netrc (0.11.0) 85 | nio4r (2.1.0) 86 | nokogiri (1.8.0) 87 | mini_portile2 (~> 2.2.0) 88 | null_logger (0.0.1) 89 | parser (2.4.0.0) 90 | ast (~> 2.2) 91 | plek (2.0.0) 92 | powerpack (0.1.1) 93 | pry (0.10.4) 94 | coderay (~> 1.1.0) 95 | method_source (~> 0.8.1) 96 | slop (~> 3.4) 97 | rack (2.0.3) 98 | rack-test (0.6.3) 99 | rack (>= 1.0) 100 | rails (5.0.4) 101 | actioncable (= 5.0.4) 102 | actionmailer (= 5.0.4) 103 | actionpack (= 5.0.4) 104 | actionview (= 5.0.4) 105 | activejob (= 5.0.4) 106 | activemodel (= 5.0.4) 107 | activerecord (= 5.0.4) 108 | activesupport (= 5.0.4) 109 | bundler (>= 1.3.0, < 2.0) 110 | railties (= 5.0.4) 111 | sprockets-rails (>= 2.0.0) 112 | rails-dom-testing (2.0.3) 113 | activesupport (>= 4.2.0) 114 | nokogiri (>= 1.6) 115 | rails-html-sanitizer (1.0.3) 116 | loofah (~> 2.0) 117 | rails_stdout_logging (0.0.5) 118 | railties (5.0.4) 119 | actionpack (= 5.0.4) 120 | activesupport (= 5.0.4) 121 | method_source 122 | rake (>= 0.8.7) 123 | thor (>= 0.18.1, < 2.0) 124 | rainbow (2.2.2) 125 | rake 126 | rake (12.0.0) 127 | rdoc (4.3.0) 128 | rest-client (2.0.2) 129 | http-cookie (>= 1.0.2, < 2.0) 130 | mime-types (>= 1.16, < 4.0) 131 | netrc (~> 0.8) 132 | rubocop (0.43.0) 133 | parser (>= 2.3.1.1, < 3.0) 134 | powerpack (~> 0.1) 135 | rainbow (>= 1.99.1, < 3.0) 136 | ruby-progressbar (~> 1.7) 137 | unicode-display_width (~> 1.0, >= 1.0.1) 138 | ruby-progressbar (1.8.1) 139 | sass (3.4.25) 140 | sass-rails (5.0.6) 141 | railties (>= 4.0.0, < 6) 142 | sass (~> 3.1) 143 | sprockets (>= 2.8, < 4.0) 144 | sprockets-rails (>= 2.0, < 4.0) 145 | tilt (>= 1.1, < 3) 146 | scss_lint (0.54.0) 147 | rake (>= 0.9, < 13) 148 | sass (~> 3.4.20) 149 | sdoc (0.4.2) 150 | json (~> 1.7, >= 1.7.7) 151 | rdoc (~> 4.0) 152 | slimmer (11.0.0) 153 | activesupport 154 | json 155 | nokogiri (~> 1.7) 156 | null_logger 157 | plek (>= 1.1.0) 158 | rack 159 | rest-client 160 | slop (3.6.0) 161 | spring (2.0.2) 162 | activesupport (>= 4.2) 163 | sprockets (3.7.1) 164 | concurrent-ruby (~> 1.0) 165 | rack (> 1, < 3) 166 | sprockets-rails (3.2.0) 167 | actionpack (>= 4.0) 168 | activesupport (>= 4.0) 169 | sprockets (>= 3.0.0) 170 | thor (0.19.4) 171 | thread_safe (0.3.6) 172 | tilt (2.0.8) 173 | tzinfo (1.2.3) 174 | thread_safe (~> 0.1) 175 | uglifier (3.2.0) 176 | execjs (>= 0.3.0, < 3) 177 | unf (0.1.4) 178 | unf_ext 179 | unf_ext (0.0.7.4) 180 | unicode-display_width (1.3.0) 181 | websocket-driver (0.6.5) 182 | websocket-extensions (>= 0.1.0) 183 | websocket-extensions (0.1.2) 184 | 185 | PLATFORMS 186 | ruby 187 | 188 | DEPENDENCIES 189 | better_errors 190 | binding_of_caller 191 | govuk-lint (= 2.1.0) 192 | govuk_frontend_toolkit (= 4.10.0) 193 | jbuilder (~> 2.0) 194 | kramdown (= 1.5) 195 | pry 196 | rails (= 5.0.4) 197 | rails_stdout_logging 198 | rest-client 199 | sass-rails (~> 5.0.6) 200 | sdoc (~> 0.4.0) 201 | slimmer (~> 11.0.0) 202 | spring 203 | uglifier (>= 1.3.0) 204 | 205 | RUBY VERSION 206 | ruby 2.3.0p0 207 | 208 | BUNDLED WITH 209 | 1.14.5 210 | -------------------------------------------------------------------------------- /vendor/assets/javascripts/prism.js: -------------------------------------------------------------------------------- 1 | /* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+scss+ruby */ 2 | self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{};var Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content),e.alias):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(d instanceof a)){c.lastIndex=0;var m=c.exec(d);if(m){u&&(f=m[1].length);var y=m.index-1+f,m=m[0].slice(f),v=m.length,k=y+v,b=d.slice(0,y+1),w=d.slice(k+1),N=[p,1];b&&N.push(b);var O=new a(l,g?t.tokenize(m,g):m,h);N.push(O),w&&N.push(w),Array.prototype.splice.apply(r,N)}}}}}return r},hooks:{all:{},add:function(e,n){var a=t.hooks.all;a[e]=a[e]||[],a[e].push(n)},run:function(e,n){var a=t.hooks.all[e];if(a&&a.length)for(var r,i=0;r=a[i++];)r(n)}}},n=t.Token=function(e,t,n){this.type=e,this.content=t,this.alias=n};if(n.stringify=function(e,a,r){if("string"==typeof e)return e;if("[object Array]"==Object.prototype.toString.call(e))return e.map(function(t){return n.stringify(t,a,e)}).join("");var i={type:e.type,content:n.stringify(e.content,a,r),tag:"span",classes:["token",e.type],attributes:{},language:a,parent:r};if("comment"==i.type&&(i.attributes.spellcheck="true"),e.alias){var l="Array"===t.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(i.classes,l)}t.hooks.run("wrap",i);var o="";for(var s in i.attributes)o+=s+'="'+(i.attributes[s]||"")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'" '+o+">"+i.content+""},!self.document)return self.addEventListener?(self.addEventListener("message",function(e){var n=JSON.parse(e.data),a=n.language,r=n.code;self.postMessage(JSON.stringify(t.util.encode(t.tokenize(r,t.languages[a])))),self.close()},!1),self.Prism):self.Prism;var a=document.getElementsByTagName("script");return a=a[a.length-1],a&&(t.filename=a.src,document.addEventListener&&!a.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism);; 3 | Prism.languages.markup={comment://g,prolog:/<\?.+?\?>/,doctype://,cdata://i,tag:{pattern:/<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+))?\s*)*\/?>/gi,inside:{tag:{pattern:/^<\/?[\w:-]+/i,inside:{punctuation:/^<\/?/,namespace:/^[\w-]+?:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/gi,inside:{punctuation:/=|>|"/g}},punctuation:/\/?>/g,"attr-name":{pattern:/[\w:-]+/g,inside:{namespace:/^[\w-]+?:/}}}},entity:/\&#?[\da-z]{1,8};/gi},Prism.hooks.add("wrap",function(t){"entity"===t.type&&(t.attributes.title=t.content.replace(/&/,"&"))});; 4 | Prism.languages.css={comment:/\/\*[\w\W]*?\*\//g,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*{))/gi,inside:{punctuation:/[;:]/g}},url:/url\((["']?).*?\1\)/gi,selector:/[^\{\}\s][^\{\};]*(?=\s*\{)/g,property:/(\b|\B)[\w-]+(?=\s*:)/gi,string:/("|')(\\?.)*?\1/g,important:/\B!important\b/gi,punctuation:/[\{\};:]/g,"function":/[-a-z0-9]+(?=\()/gi},Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{style:{pattern:/[\w\W]*?<\/style>/gi,inside:{tag:{pattern:/|<\/style>/gi,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.css}}});; 5 | Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//g,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*?(\r?\n|$)/g,lookbehind:!0}],string:/("|')(\\?.)*?\1/g,"class-name":{pattern:/((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/gi,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/g,"boolean":/\b(true|false)\b/g,"function":{pattern:/[a-z0-9_]+\(/gi,inside:{punctuation:/\(/}},number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g,operator:/[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|\~|\^|\%/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};; 6 | Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/g,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?|NaN|-?Infinity)\b/g}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g,lookbehind:!0}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/[\w\W]*?<\/script>/gi,inside:{tag:{pattern:/|<\/script>/gi,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript}}});; 7 | Prism.languages.scss=Prism.languages.extend("css",{comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|\/\/.*?(\r?\n|$))/g,lookbehind:!0},atrule:/@[\w-]+(?=\s+(\(|\{|;))/gi,url:/([-a-z]+-)*url(?=\()/gi,selector:/([^@;\{\}\(\)]?([^@;\{\}\(\)]|&|\#\{\$[-_\w]+\})+)(?=\s*\{(\}|\s|[^\}]+(:|\{)[^\}]+))/gm}),Prism.languages.insertBefore("scss","atrule",{keyword:/@(if|else if|else|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)|(?=@for\s+\$[-_\w]+\s)+from/i}),Prism.languages.insertBefore("scss","property",{variable:/((\$[-_\w]+)|(#\{\$[-_\w]+\}))/i}),Prism.languages.insertBefore("scss","ignore",{placeholder:/%[-_\w]+/i,statement:/\B!(default|optional)\b/gi,"boolean":/\b(true|false)\b/g,"null":/\b(null)\b/g,operator:/\s+([-+]{1,2}|={1,2}|!=|\|?\||\?|\*|\/|\%)\s+/g});; 8 | Prism.languages.ruby=Prism.languages.extend("clike",{comment:/#[^\r\n]*(\r?\n|$)/g,keyword:/\b(alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/g,builtin:/\b(Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|File|Fixnum|Fload|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,constant:/\b[A-Z][a-zA-Z_0-9]*[?!]?\b/g}),Prism.languages.insertBefore("ruby","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g,lookbehind:!0},variable:/[@$]+\b[a-zA-Z_][a-zA-Z_0-9]*[?!]?\b/g,symbol:/:\b[a-zA-Z_][a-zA-Z_0-9]*[?!]?\b/g});; 9 | --------------------------------------------------------------------------------