mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-15 04:10:40 -07:00
feat: slugify filter from Jekyll, #443
This commit is contained in:
@@ -82,6 +82,7 @@ filters:
|
||||
shift: shift.html
|
||||
size: size.html
|
||||
slice: slice.html
|
||||
slugify: slugify.html
|
||||
sort: sort.html
|
||||
sort_natural: sort_natural.html
|
||||
split: split.html
|
||||
|
||||
@@ -11,7 +11,7 @@ Categories | Filters
|
||||
--- | ---
|
||||
Math | plus, minus, modulo, times, floor, ceil, round, divided_by, abs, at_least, at_most
|
||||
String | append, prepend, capitalize, upcase, downcase, strip, lstrip, rstrip, strip_newlines, split, replace, replace_first, replace_last,remove, remove_first, remove_last, truncate, truncatewords, normalize_whitespace, number_of_words, array_to_sentence_string
|
||||
HTML/URI | escape, escape_once, url_encode, url_decode, strip_html, newline_to_br, xml_escape, cgi_escape, uri_escape
|
||||
HTML/URI | escape, escape_once, url_encode, url_decode, strip_html, newline_to_br, xml_escape, cgi_escape, uri_escape, slugify
|
||||
Array | slice, map, sort, sort_natural, uniq, where, where_exp, group_by, group_by_exp, find, find_exp, first, last, join, reverse, concat, compact, size, push, pop, shift, unshift
|
||||
Date | date, date_to_xmlschema, date_to_rfc822, date_to_string, date_to_long_string
|
||||
Misc | default, json, jsonify, inspect, raw, to_integer
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
---
|
||||
title: slugify
|
||||
---
|
||||
|
||||
{% since %}v10.13.0{% endsince %}
|
||||
|
||||
Convert a string into a lowercase URL "slug". The slugify filter accepts 2 options:
|
||||
|
||||
1. `mode: string`. The default is `"default"`. They are as follows (with what they filter):
|
||||
- `"none"`: no characters
|
||||
- `"raw"`: spaces
|
||||
- `"default"`: spaces and non-alphanumeric characters
|
||||
- `"pretty"`: spaces and non-alphanumeric characters except for `._~!$&'()+,;=@`
|
||||
- `"ascii"`: spaces, non-alphanumeric, and non-ASCII characters
|
||||
- `"latin"`: like default, except Latin characters are first transliterated (e.g. àèïòü to aeiou).
|
||||
2. `case: boolean`. The default is `false`. The original case of slug will be retained if set to `true`.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "The _config.yml file" | slugify }}
|
||||
```
|
||||
Output
|
||||
```
|
||||
the-config-yml-file
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "The _config.yml file" | slugify: "pretty" }}
|
||||
```
|
||||
Output
|
||||
```
|
||||
the-_config.yml-file
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "The _cönfig.yml file" | slugify: "ascii" }}
|
||||
```
|
||||
Output
|
||||
```
|
||||
the-c-nfig-yml-file
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "The cönfig.yml file" | slugify: "latin" }}
|
||||
```
|
||||
Output
|
||||
```
|
||||
the-config-yml-file
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "The cönfig.yml file" | slugify: "latin", true }}
|
||||
```
|
||||
Output
|
||||
```
|
||||
The-config-yml-file
|
||||
```
|
||||
@@ -11,7 +11,7 @@ LiquidJS 共支持 40+ 个过滤器,可以分为如下几类:
|
||||
--- | ---
|
||||
数学 | plus, minus, modulo, times, floor, ceil, round, divided_by, abs, at_least, at_most
|
||||
字符串 | append, prepend, capitalize, upcase, downcase, strip, lstrip, rstrip, strip_newlines, split, replace, replace_first, replace_last, remove, remove_first, remove_last, truncate, truncatewords, normalize_whitespace, number_of_words, array_to_sentence_string
|
||||
HTML/URI | escape, escape_once, url_encode, url_decode, strip_html, newline_to_br, xml_escape, cgi_escape, uri_escape
|
||||
HTML/URI | escape, escape_once, url_encode, url_decode, strip_html, newline_to_br, xml_escape, cgi_escape, uri_escape, slugify
|
||||
数组 | slice, map, sort, sort_natural, uniq, where, where_exp, group_by, group_by_exp, find, find_exp, first, last, join, reverse, concat, compact, size, push, pop, shift, unshift
|
||||
日期 | date, date_to_xmlschema, date_to_rfc822, date_to_string, date_to_long_string
|
||||
其他 | default, json, jsonify, inspect, raw, to_integer
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
---
|
||||
title: slugify
|
||||
---
|
||||
|
||||
将字符串转换为小写的 URL “slug”。`slugify` 过滤器接受两个选项:
|
||||
|
||||
1. `mode: string`。默认为`"default"`,它可选的值如下:
|
||||
- `"none"`:没有字符
|
||||
- `"raw"`:空格
|
||||
- `"default"`:空格和非字母数字字符
|
||||
- `"pretty"`:空格和非字母数字字符,但排除 `._~!$&'()+,;=@`
|
||||
- `"ascii"`:空格、非字母数字和非 ASCII 字符
|
||||
- `"latin"`:与默认相同,但拉丁字符首先进行音译(例如,àèïòü 转换为 aeiou)。
|
||||
2. `case: boolean`。默认为 `false`。如果为 `true`,则保留 `slug` 原本的大小写。
|
||||
|
||||
输入
|
||||
```liquid
|
||||
{{ "The _config.yml file" | slugify }}
|
||||
```
|
||||
输出
|
||||
```
|
||||
the-config-yml-file
|
||||
```
|
||||
|
||||
输入
|
||||
```liquid
|
||||
{{ "The _config.yml file" | slugify: "pretty" }}
|
||||
```
|
||||
输出
|
||||
```
|
||||
the-_config.yml-file
|
||||
```
|
||||
|
||||
输入
|
||||
```liquid
|
||||
{{ "The _cönfig.yml file" | slugify: "ascii" }}
|
||||
```
|
||||
输出
|
||||
```
|
||||
the-c-nfig-yml-file
|
||||
```
|
||||
|
||||
输入
|
||||
```liquid
|
||||
{{ "The cönfig.yml file" | slugify: "latin" }}
|
||||
```
|
||||
输出
|
||||
```
|
||||
the-config-yml-file
|
||||
```
|
||||
|
||||
输入
|
||||
```liquid
|
||||
{{ "The cönfig.yml file" | slugify: "latin", true }}
|
||||
```
|
||||
输出
|
||||
```
|
||||
The-config-yml-file
|
||||
```
|
||||
+2
-2
@@ -36,8 +36,8 @@ vendor-prefixes = webkit moz ms official
|
||||
font-sans = "Helvetica Neue", Helvetica, Arial, sans-serif
|
||||
font-serif = Garamond, Georgia, "Times New Roman", serif
|
||||
font-mono = "Source Code Pro", Monaco, Menlo, Consolas, monospace
|
||||
font-size = 15px
|
||||
line-height = 1.6em
|
||||
font-size = 16px
|
||||
line-height = 1.8em
|
||||
|
||||
// Layout
|
||||
max-width = 1800px
|
||||
|
||||
@@ -8,3 +8,44 @@ export const cgi_escape = (x: string) => encodeURIComponent(stringify(x))
|
||||
export const uri_escape = (x: string) => encodeURI(stringify(x))
|
||||
.replace(/%5B/g, '[')
|
||||
.replace(/%5D/g, ']')
|
||||
|
||||
const rSlugifyDefault = /[^\p{M}\p{L}\p{Nd}]+/ug
|
||||
const rSlugifyReplacers = {
|
||||
'raw': /\s+/g,
|
||||
'default': rSlugifyDefault,
|
||||
'pretty': /[^\p{M}\p{L}\p{Nd}._~!$&'()+,;=@]+/ug,
|
||||
'ascii': /[^A-Za-z0-9]+/g,
|
||||
'latin': rSlugifyDefault,
|
||||
'none': null
|
||||
}
|
||||
|
||||
export function slugify (str: string, mode: keyof typeof rSlugifyReplacers = 'default', cased = false): string {
|
||||
str = stringify(str)
|
||||
|
||||
const replacer = rSlugifyReplacers[mode]
|
||||
if (replacer) {
|
||||
if (mode === 'latin') str = removeAccents(str)
|
||||
str = str.replace(replacer, '-').replace(/^-|-$/g, '')
|
||||
}
|
||||
|
||||
return cased ? str : str.toLowerCase()
|
||||
}
|
||||
|
||||
function removeAccents (str: string): string {
|
||||
return str.replace(/[àáâãäå]/g, 'a')
|
||||
.replace(/[æ]/g, 'ae')
|
||||
.replace(/[ç]/g, 'c')
|
||||
.replace(/[èéêë]/g, 'e')
|
||||
.replace(/[ìíîï]/g, 'i')
|
||||
.replace(/[ð]/g, 'd')
|
||||
.replace(/[ñ]/g, 'n')
|
||||
.replace(/[òóôõöø]/g, 'o')
|
||||
.replace(/[ùúûü]/g, 'u')
|
||||
.replace(/[ýÿ]/g, 'y')
|
||||
.replace(/[ß]/g, 'ss')
|
||||
.replace(/[œ]/g, 'oe')
|
||||
.replace(/[þ]/g, 'th')
|
||||
.replace(/[ẞ]/g, 'SS')
|
||||
.replace(/[Œ]/g, 'OE')
|
||||
.replace(/[Þ]/g, 'TH')
|
||||
}
|
||||
|
||||
@@ -42,4 +42,53 @@ describe('filters/url', () => {
|
||||
expect(html).toEqual(reserved)
|
||||
})
|
||||
})
|
||||
|
||||
describe('slugify', () => {
|
||||
describe('slugify', () => {
|
||||
it('should slugify with default mode', () => {
|
||||
const html = liquid.parseAndRenderSync('{{ "The _config.yml file" | slugify }}')
|
||||
expect(html).toEqual('the-config-yml-file')
|
||||
})
|
||||
|
||||
it('should slugify with pretty mode', () => {
|
||||
const html = liquid.parseAndRenderSync('{{ "The _config.yml file" | slugify: "pretty" }}')
|
||||
expect(html).toEqual('the-_config.yml-file')
|
||||
})
|
||||
|
||||
it('should slugify with ascii mode', () => {
|
||||
const html = liquid.parseAndRenderSync('{{ "The _cönfig.yml file" | slugify: "ascii" }}')
|
||||
expect(html).toEqual('the-c-nfig-yml-file')
|
||||
})
|
||||
|
||||
it('should slugify with latin mode', () => {
|
||||
const html = liquid.parseAndRenderSync('{{ "The cönfig.yml file" | slugify: "latin" }}')
|
||||
expect(html).toEqual('the-config-yml-file')
|
||||
})
|
||||
|
||||
it('should slugify with none mode', () => {
|
||||
const html = liquid.parseAndRenderSync('{{ "The _config.yml file" | slugify: "none" }}')
|
||||
expect(html).toEqual('the _config.yml file')
|
||||
})
|
||||
|
||||
it('should slugify with invalid mode', () => {
|
||||
const html = liquid.parseAndRenderSync('{{ "The _config.yml file" | slugify: "invalid_mode" }}')
|
||||
expect(html).toEqual('the _config.yml file')
|
||||
})
|
||||
|
||||
it('should slugify with empty string', () => {
|
||||
const html = liquid.parseAndRenderSync('{{ "" | slugify }}')
|
||||
expect(html).toEqual('')
|
||||
})
|
||||
|
||||
it('should slugify with cased=false', () => {
|
||||
const html = liquid.parseAndRenderSync('{{ "Test String" | slugify: "pretty", false }}')
|
||||
expect(html).toEqual('test-string')
|
||||
})
|
||||
|
||||
it('should slugify with cased=true', () => {
|
||||
const html = liquid.parseAndRenderSync('{{ "Test String" | slugify: "pretty", true }}')
|
||||
expect(html).toEqual('Test-String')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user