diff --git a/CHANGELOG.md b/CHANGELOG.md index cb0c0e727..c0d7913a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased - New GitHub Pages configurations will deploy a production build +- Add an seo configuration (bridgetown-seo-tag gem) +- Add a feed configuration (bridgetown-feed gem) ## [1.1.0] — 2022-07-18 diff --git a/bridgetown-core/lib/bridgetown-core/configurations/feed.rb b/bridgetown-core/lib/bridgetown-core/configurations/feed.rb new file mode 100644 index 000000000..c188c40e4 --- /dev/null +++ b/bridgetown-core/lib/bridgetown-core/configurations/feed.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +say_status :feed, "Adding bridgetown-feed gem" + +bundle_command = <<~BUNDLE + bundle info bridgetown-feed || + bundle add bridgetown-feed -g bridgetown_plugins +BUNDLE + +run bundle_command, { verbose: false, capture: true } + +say_status :feed, "Adding feed tags" + +head_file = Dir.glob("src/**/{head.liquid,_head.erb,_head.serb}").first + +unless head_file + say_status :feed, "Feed tags could not be automatically inserted" + say_status :feed, "To enable, output `feed` in the application element" \ + "using the relevant template language tags" + say "" + say "For help with tag configuration see #{"https://github.com/bridgetownrb/bridgetown-feed#readme".yellow.bold}" + + return +end + +File.open(head_file, "a+") do |file| + feed_tag = Bridgetown::Utils.build_output_tag_for_template_extname( + File.extname(head_file), + "feed_meta" + ) + + file.write("#{feed_tag}\n") unless file.grep(%r{#{feed_tag}}).any? + + say "" + say_status :feed, "Feed tags added to #{head_file}" + say_status :feed, "For help with tag configuration see #{"https://github.com/bridgetownrb/bridgetown-feed#readme".yellow.bold}" +end diff --git a/bridgetown-core/lib/bridgetown-core/configurations/seo.rb b/bridgetown-core/lib/bridgetown-core/configurations/seo.rb new file mode 100644 index 000000000..c7ac0239e --- /dev/null +++ b/bridgetown-core/lib/bridgetown-core/configurations/seo.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +say_status :seo, "Adding bridgetown-seo-tag gem" + +bundle_command = <<~BUNDLE + bundle info bridgetown-seo-tag || + bundle add bridgetown-seo-tag -g bridgetown_plugins +BUNDLE + +run bundle_command, { verbose: false, capture: true } + +say_status :seo, "Adding SEO tags" + +head_file = Dir.glob("src/**/{head.liquid,_head.erb,_head.serb}").first + +unless head_file + say_status :seo, "SEO tags could not be automatically inserted" + say_status :seo, "To enable SEO, output `seo` in the application element" \ + "using the relevant template language tags" + say "" + say "For help with tag configuration see #{"https://github.com/bridgetownrb/bridgetown-seo-tag#readme".yellow.bold}" + + return +end + +File.open(head_file, "a+") do |file| + seo_tag = Bridgetown::Utils.build_output_tag_for_template_extname(File.extname(head_file), "seo") + + file.write("#{seo_tag}\n") unless file.grep(%r{#{seo_tag}}).any? + + say "" + say_status :seo, "SEO tags added to #{head_file}" + say_status :seo, "For help with tag configuration see #{"https://github.com/bridgetownrb/bridgetown-seo-tag#readme".yellow.bold}" +end diff --git a/bridgetown-core/lib/bridgetown-core/utils.rb b/bridgetown-core/lib/bridgetown-core/utils.rb index 0e8005934..3c0f20f17 100644 --- a/bridgetown-core/lib/bridgetown-core/utils.rb +++ b/bridgetown-core/lib/bridgetown-core/utils.rb @@ -18,6 +18,21 @@ module Utils # rubocop:todo Metrics/ModuleLength SLUGIFY_PRETTY_REGEXP = Regexp.new("[^\\p{M}\\p{L}\\p{Nd}._~!$&'()+,;=@]+").freeze SLUGIFY_ASCII_REGEXP = Regexp.new("[^[A-Za-z0-9]]+").freeze + TEMPLATE_EXTNAMES_TAGS = { + ".liquid" => [ + "{%", + "%}", + ], + ".erb" => [ + "<%=", + "%>", + ], + ".serb" => [ + "{%=", + "%}", + ], + }.freeze + # Takes a slug and turns it into a simple title. def titleize_slug(slug) slug.gsub(%r![_ ]!, "-").split("-").map!(&:capitalize).join(" ") @@ -116,7 +131,7 @@ def parse_date(input, msg = "Input could not be parsed.") raise Errors::InvalidDateError, "Invalid date '#{input}': #{msg}" end - # Determines whether a given file has + # Determines whether a given file has YAML front matter # # @return [Boolean] if the YAML front matter is present. # rubocop: disable Naming/PredicateName @@ -128,7 +143,7 @@ def has_rbfm_header?(file) File.open(file, "rb", &:gets)&.match?(Bridgetown::FrontMatterImporter::RUBY_HEADER) || false end - # Determine whether the given content string contains Liquid Tags or Vaiables + # Determine whether the given content string contains Liquid Tags or Variables # # @return [Boolean] if the string contains sequences of `{%` or `{{` def has_liquid_construct?(content) @@ -501,6 +516,17 @@ def chomp_locale_suffix!(path, locale) end end + def build_output_tag_for_template_extname(extname, content) + unless TEMPLATE_EXTNAMES_TAGS.key?(extname) + raise "Template engines using file extension #{extname}" \ + "are not currently supported by default" + end + + start_tag, end_tag = TEMPLATE_EXTNAMES_TAGS[extname] + + [start_tag, content, end_tag].join(" ") + end + private def merge_values(target, overwrite) diff --git a/bridgetown-core/test/test_utils.rb b/bridgetown-core/test/test_utils.rb index 52aeb843a..70a89465b 100644 --- a/bridgetown-core/test/test_utils.rb +++ b/bridgetown-core/test/test_utils.rb @@ -435,4 +435,24 @@ class TestUtils < BridgetownUnitTest assert_equal "master", Utils.default_github_branch_name("https://github.com/thisorgdoesntexist/thisrepoistotallybogus") end end + + context "The \`Utils.build_output_tag_for_template_extname\` method" do + setup do + Utils::TEMPLATE_EXTNAMES_TAGS = { + ".liquid" => ["{%", "%}"], + ".erb" => ["<%=", "%>"], + }.freeze + end + + should "return content within tags for the supplied file extname" do + assert_equal "{% content %}", Utils.build_output_tag_for_template_extname(".liquid", "content") + assert_equal "<%= content %>", Utils.build_output_tag_for_template_extname(".erb", "content") + end + + should "raise an error if the supplied extname is not supported" do + assert_raises do + Utils.build_output_tag_for_template_extname(".not_a_template_engine", "content") + end + end + end end diff --git a/bridgetown-website/src/_docs/bundled-configurations.md b/bridgetown-website/src/_docs/bundled-configurations.md index 61ee54f1d..6841a6475 100644 --- a/bridgetown-website/src/_docs/bundled-configurations.md +++ b/bridgetown-website/src/_docs/bundled-configurations.md @@ -24,6 +24,8 @@ The configurations we include are: - [GitHub Pages Configuration](#github-pages-configuration) (`gh-pages`) - [Automated Test Suite using Minitest](#automated-test-suite-using-minitest) (`minitesting`) - [Cypress](#cypress) (`cypress`) +- [SEO](#seo) (`seo`) +- [Feed (RSS-like)](#feed) (`feed`) The full list of configurations can also be seen by running `bridgetown configure` without arguments. @@ -208,3 +210,23 @@ bin/bridgetown configure minitesting ```sh bin/bridgetown configure cypress ``` + +### SEO + +🔍 Adds metadata tags for search engines and social networks to better index and display your site's content. Check out the [gem readme](https://github.com/bridgetownrb/bridgetown-seo-tag#summary) for more info and configuration options. + +🛠 **Configure using:** + +```sh +bin/bridgetown configure seo +``` + +### Feed + +🍽️ Generate an Atom (RSS-like) feed of your Bridgetown posts and other collection documents. Check out the [gem readme](https://github.com/bridgetownrb/bridgetown-feed#usage) for more info and configuration options. + +🛠 **Configure using:** + +```sh +bin/bridgetown configure feed +```