From 589feb0186a76c374ecb34a6f7ae4bb78332507d Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Mon, 6 Nov 2023 18:20:37 +0100 Subject: [PATCH] Truncate the description value to 100 words (#492) Merge pull request 492 --- docs/advanced-usage.md | 21 +++++++++++++++++++++ lib/jekyll-seo-tag/drop.rb | 14 +++++++++++++- spec/jekyll_seo_tag/drop_spec.rb | 18 ++++++++++++++++++ spec/jekyll_seo_tag_integration_spec.rb | 17 +++++++++++++++++ 4 files changed, 69 insertions(+), 1 deletion(-) diff --git a/docs/advanced-usage.md b/docs/advanced-usage.md index f3344961..f6991bcf 100644 --- a/docs/advanced-usage.md +++ b/docs/advanced-usage.md @@ -80,6 +80,27 @@ You can set it the same way as the other author properties. For example, you can url: https://example.com/ ``` +### Customizing description length + +By default, the description is limited to the first 100 words of the full content. + +You can adjust this limit at the page level, by using the `seo_description_max_words` page property: + +```yml + seo_description_max_words: 200 +``` + +You can also set a default site-wide value for all pages using [Front Matter defaults](https://jekyllrb.com/docs/configuration/front-matter-defaults/) in your `_config.yml` file: + +```yml +defaults: + - scope: + path: "" + values: + seo_description_max_words: 200 +``` + + ### Customizing JSON-LD output The following options can be set for any particular page. While the default options are meant to serve most users in the most common circumstances, there may be situations where more precise control is necessary. diff --git a/lib/jekyll-seo-tag/drop.rb b/lib/jekyll-seo-tag/drop.rb index 157babd4..9d4a9f6a 100644 --- a/lib/jekyll-seo-tag/drop.rb +++ b/lib/jekyll-seo-tag/drop.rb @@ -89,7 +89,8 @@ def name def description @description ||= begin - format_string(page["description"] || page["excerpt"]) || site_description + value = format_string(page["description"] || page["excerpt"]) || site_description + snippet(value, description_max_words) end end @@ -175,6 +176,10 @@ def canonical_url end end + def description_max_words + @description_max_words ||= page["seo_description_max_words"] || 100 + end + private def filters @@ -217,6 +222,13 @@ def format_string(string) string unless string.empty? end + def snippet(string, max_words) + return string if string.nil? + + result = string.split(%r!\s+!, max_words + 1)[0...max_words].join(" ") + result.length < string.length ? result.concat("…") : result + end + def seo_name @seo_name ||= format_string(page_seo["name"]) if page_seo["name"] end diff --git a/spec/jekyll_seo_tag/drop_spec.rb b/spec/jekyll_seo_tag/drop_spec.rb index 574213f2..53f48f9f 100644 --- a/spec/jekyll_seo_tag/drop_spec.rb +++ b/spec/jekyll_seo_tag/drop_spec.rb @@ -233,6 +233,24 @@ expect(subject.description).to be_nil end end + + context "truncation" do + context "without seo_description_max_words" do + let(:page_meta) { { "description" => "word " * 150 } } + + it "truncates the description to the first 200 words" do + expect(subject.description).to eql(("word " * 100).chop.concat("…")) + end + end + + context "with an explicit seo_description_max_words property" do + let(:page_meta) { { "description" => "For a long time, I went to bed early", "seo_description_max_words" => 6 } } + + it "truncates the description to the configured words count" do + expect(subject.description).to eql("For a long time, I went…") + end + end + end end context "author" do diff --git a/spec/jekyll_seo_tag_integration_spec.rb b/spec/jekyll_seo_tag_integration_spec.rb index f7b1cb8e..58a9af19 100755 --- a/spec/jekyll_seo_tag_integration_spec.rb +++ b/spec/jekyll_seo_tag_integration_spec.rb @@ -350,6 +350,23 @@ it "removes null values from JSON-LD" do expect(output).to_not match(%r!:null!) end + + context "description" do + context "with page.seo_description_max_words" do + let(:meta) do + { + "title" => "post", + "description" => "For a long time, I went to bed early", + "image" => "/img.png", + "seo_description_max_words" => 6, + } + end + + it "truncates the description" do + expect(json_data["description"]).to eql("For a long time, I went…") + end + end + end end end