Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mode parameter to slugify Liquid filter #2918

Merged
merged 3 commits into from Jan 18, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 5 additions & 5 deletions lib/jekyll/filters.rb
Expand Up @@ -50,12 +50,12 @@ def scssify(input)
# Slugify a filename or title.
#
# input - The filename or title to slugify.
# mode - how string is slugified
#
# Returns the given filename or title as a lowercase String, with every
# sequence of spaces and non-alphanumeric characters replaced with a
# hyphen.
def slugify(input)
Utils.slugify(input)
# Returns the given filename or title as a lowercase URL String.
# See Utils.slugify for more detail.
def slugify(input, mode=nil)
Utils.slugify(input, mode)
end

# Format a date in short format e.g. "27 Jan 2011".
Expand Down
55 changes: 43 additions & 12 deletions lib/jekyll/utils.rb
Expand Up @@ -104,19 +104,50 @@ def has_yaml_header?(file)

# Slugify a filename or title.
#
# name - the filename or title to slugify
#
# Returns the given filename or title in lowercase, with every
# sequence of spaces and non-alphanumeric characters replaced with a
# hyphen.
def slugify(string)
unless string.nil?
# Replace each non-alphanumeric character sequence with a hyphen
slug = string.gsub(/[^a-z0-9]+/i, '-')
# Remove leading/trailing hyphen
slug.gsub!(/^\-|\-$/i, '')
slug.downcase
# string - the filename or title to slugify
# mode - how string is slugified
#
# When mode is "none", return the given string in lowercase.
#
# When mode is "raw", return the given string in lowercase,
# with every sequence of spaces characters replaced with a hyphen.
#
# When mode is "default" or nil, non-alphabetic characters are
# replaced with a hyphen too.
#
# When mode is "pretty", some non-alphabetic characters (._~!$&'()+,;=@)
# are not replaced with hyphen.
#
# Examples:
# slugify("The _config.yml file")
# # => "the-config-yml-file"
#
# slugify("The _config.yml file", "pretty")
# # => "the-_config.yml-file"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two examples seem to clash.

#
# Returns the slugified string.
def slugify(string, mode=nil)
mode ||= 'default'
return nil if string.nil?

# Replace each character sequence with a hyphen
re = case mode
when 'raw'
Regexp.new('\\s+')
when 'default'
Regexp.new('[^a-zA-Z0-9]+')
when 'pretty'
# "._~!$&'()+,;=@" is human readable (not URI-escaped) in URL
# and is allowed in both extN and NTFS.
Regexp.new("[^a-zA-Z0-9._~!$&'()+,;=@]+")
else
return string.downcase
end
slug = string.gsub(re, '-')

# Remove leading/trailing hyphen
slug.gsub!(/^\-|\-$/i, '')
slug.downcase
end

end
Expand Down
20 changes: 18 additions & 2 deletions site/_docs/templates.md
Expand Up @@ -214,11 +214,27 @@ common tasks easier.
<tr>
<td>
<p class="name"><strong>Slugify</strong></p>
<p>Convert a string into a lowercase URL "slug" by replacing every sequence of spaces and non-alphanumeric characters with a hyphen.</p>
<p>Convert a string into a lowercase URL "slug".</p>
<p>Optional argument mode specify what characters are replaced with a hyphen. The default value is 'default'.</p>
<ul>
<li>'none': no characters</li>
<li>'raw': spaces</li>
<li>'default': spaces and non-alphanumeric characters</li>
<li>'pretty': spaces and non-alphanumeric characters except for <em>._~!$&amp;'()+,;=@</em></li>
</ul>
</td>
<td class="align-center">
<p>
<code class="filter">{% raw %}{{ page.title | slugify }}{% endraw %}</code>
<code class="filter">{% raw %}{{ "The _config.yml file" | slugify }}{% endraw %}</code>
</p>
<p>
<code class="output">the-config-yml-file</code>
</p>
<p>
<code class="filter">{% raw %}{{ "The _config.yml file" | slugify: 'pretty' }}{% endraw %}</code>
</p>
<p>
<code class="output">the-_config.yml-file</code>
</p>
</td>
</tr>
Expand Down
8 changes: 6 additions & 2 deletions site/_sass/_style.scss
Expand Up @@ -834,10 +834,14 @@ td {
padding: .5em .75em;
}

td p {
td p, td ul, article td li {
margin: 0;
}

td ul {
padding: 0 0 0 1.2em;
}

th {
text-transform: uppercase;
font-size: 16px;
Expand All @@ -861,7 +865,7 @@ tbody td {
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#1affffff', endColorstr='#00ffffff',GradientType=0 );
}

td p {
td p, td ul {
font-size: 16px;
}

Expand Down
4 changes: 4 additions & 0 deletions test/test_filters.rb
Expand Up @@ -221,6 +221,10 @@ def initialize(opts = {})
should "return a slugified string" do
assert_equal "q-bert-says", @filter.slugify(" Q*bert says @!#?@!")
end

should "return a slugified string with mode" do
assert_equal "q-bert-says-@!-@!", @filter.slugify(" Q*bert says @!#?@!", "pretty")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This wouldn't be a valid path, would it? If so, can you link me to the spec which details that these are allowed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is valid path. When pretty mode is specified, ._~!$&'()+,;=@ is not replaced with a hyphen.

  1. Replace to hyphen: Q*bert says @!#?@!-Q-bert-says-@!-@!
  2. Remove leading/trailing hyphen: -Q-bert-says-@!-@!Q-bert-says-@!-@!
  3. Downcase: Q-bert-says-@!-@!q-bert-says-@!-@!

end
end

context "push filter" do
Expand Down
20 changes: 20 additions & 0 deletions test/test_utils.rb
Expand Up @@ -139,6 +139,26 @@ class TestUtils < Test::Unit::TestCase
Utils.slugify(title)
assert_equal "Quick-start guide", title
end

should "not change behaviour if mode is default" do
assert_equal "the-config-yml-file", Utils.slugify("The _config.yml file?", "default")
end

should "not change behaviour if mode is nil" do
assert_equal "the-config-yml-file", Utils.slugify("The _config.yml file?", nil)
end

should "not replace period and underscore if mode is pretty" do
assert_equal "the-_config.yml-file", Utils.slugify("The _config.yml file?", "pretty")
end

should "only replace whitespace if mode is raw" do
assert_equal "the-_config.yml-file?", Utils.slugify("The _config.yml file?", "raw")
end

should "return the given string if mode is none" do
assert_equal "the _config.yml file?", Utils.slugify("The _config.yml file?", "none")
end
end

end