Fix for nginx mediatypes, search holder: Update infos for hugo articles
parent
7cc40f4724
commit
5ed7c387b9
|
@ -0,0 +1 @@
|
|||
["conf/nginx"]
|
|
@ -2,14 +2,14 @@ application/atom+xml:
|
|||
suffixes:
|
||||
- xml
|
||||
application/json:
|
||||
suffixes:
|
||||
suffixes:
|
||||
- json
|
||||
application/opensearchdescription+xml:
|
||||
suffixes:
|
||||
suffixes:
|
||||
- xml
|
||||
conf/nginx:
|
||||
suffixes:
|
||||
- conf
|
||||
#"conf/nginx":
|
||||
#suffixes:
|
||||
#- conf
|
||||
#text/gemini:
|
||||
#suffixes:
|
||||
#- gmi
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
[nginx]
|
||||
baseName = "redirections.conf"
|
||||
isPlainText = true
|
||||
mediatype = "conf/nginx"
|
||||
notAlternative = true
|
||||
path = "nginx-config"
|
||||
|
|
@ -35,15 +35,15 @@ json:
|
|||
IsPlainText: true
|
||||
mediaType: application/json
|
||||
noUgly: false
|
||||
rel: alternate
|
||||
nginx:
|
||||
basename: index
|
||||
IsHTML: false
|
||||
isPlainText: true
|
||||
mediaType: conf/nginx
|
||||
notAlternative: true
|
||||
noUgly: true
|
||||
path: nginx-config
|
||||
#rel: alternate
|
||||
#nginx:
|
||||
#basename: index
|
||||
#IsHTML: false
|
||||
#isPlainText: true
|
||||
#mediaType: conf/nginx
|
||||
#notAlternative: true
|
||||
#noUgly: true
|
||||
#path: nginx-config
|
||||
opensearch:
|
||||
basename: opensearch
|
||||
isHTML: false
|
||||
|
|
|
@ -46,9 +46,11 @@ The related MimeType to the Opensearch description format is: `application/opens
|
|||
|
||||
Since Hugo 0.20, you need to add:
|
||||
|
||||
`[mediaTypes]` <br>
|
||||
`[mediaTypes."application/opensearchdescription+xml"]` <br>
|
||||
`suffix = "xml"`
|
||||
```toml
|
||||
[mediaTypes]
|
||||
[mediaTypes."application/opensearchdescription+xml"]
|
||||
suffix = "xml"
|
||||
```
|
||||
|
||||
Here, we added a new type of format for the mime type: `application/opensearchdescription+xml`, with the extension name: `xml`.
|
||||
|
||||
|
@ -56,9 +58,11 @@ Here, we added a new type of format for the mime type: `application/opensearchde
|
|||
|
||||
Since Hugo 0.44, you need to add:
|
||||
|
||||
`[mediaTypes]` <br>
|
||||
`[mediaTypes."application/opensearchdescription+xml"]` <br>
|
||||
`suffixes = ["xml"]`
|
||||
```toml
|
||||
[mediaTypes]
|
||||
[mediaTypes."application/opensearchdescription+xml"]
|
||||
suffixes = ["xml"]
|
||||
```
|
||||
|
||||
{{< note tip >}}If your old configuration was before the v0.44, you have to transform the variable `suffix` to `suffixes = ['xml']` ! {{< /note >}}
|
||||
|
||||
|
@ -66,18 +70,22 @@ Since Hugo 0.44, you need to add:
|
|||
|
||||
The output format declaration to add:
|
||||
|
||||
`[outputs]` <br>
|
||||
`[outputFormats.OpenSearch]` <br>
|
||||
`baseName = "opensearch"` <br>
|
||||
`isHTML = false` <br>
|
||||
`isPlainText = false` <br>
|
||||
`mediaType = "application/opensearchdescription+xml"` <br>
|
||||
`noUgly = true` <br>
|
||||
```toml
|
||||
[outputs]
|
||||
[outputFormats.OpenSearch]
|
||||
baseName = "opensearch"
|
||||
isHTML = false
|
||||
isPlainText = false
|
||||
mediaType = "application/opensearchdescription+xml"
|
||||
noUgly = true
|
||||
```
|
||||
|
||||
Next, you need to add `"OpenSearch"` at your `home` variable:
|
||||
|
||||
`[outputs]` <br>
|
||||
`home = ["HTML", "OpenSearch"]` <br>
|
||||
```toml
|
||||
[outputs]
|
||||
home = ["HTML", "OpenSearch"]
|
||||
```
|
||||
|
||||
### Template
|
||||
|
||||
|
@ -91,7 +99,27 @@ language are generated.
|
|||
{{<note info>}}ATTENTION: the presented template manages a multilingual
|
||||
website. {{</note>}}
|
||||
|
||||
{{< file "web-hugo-opensearch-template" xml "layouts/_default/index.opensearch.xml" >}}
|
||||
```xml
|
||||
{{ printf `<?xml version="1.0" encoding="utf-8" ?>` | safeHTML }}
|
||||
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/" xmlns:ie="http://schemas.microsoft.com/Search/2008/" xmlns:moz="http://www.mozilla.org/2006/browser/search/">
|
||||
<Attribution>© {{ $.Date.Format "2006" | safeHTML }} {{ site.Author.name }}; http://creativecommons.org/publicdomain/zero/1.0/legalcode.{{ site.Language.Lang }}</Attribution>
|
||||
<Contact>{{ site.Author.email | safeHTML }}</Contact>
|
||||
<Description>{{ i18n "opensearchDescription" }}</Description>
|
||||
<Developer>{{ site.Author.name | safeHTML }}</Developer>
|
||||
<InputEncoding>utf-8</InputEncoding>
|
||||
<Image width="64" height="64" type="image/png">{{ site.BaseURL }}img/Logo-64px.png</Image>
|
||||
<Image width="16" height="16" type="image/vnd.microsoft.icon">{{ site.BaseURL }}img/favicon.ico</Image>
|
||||
<Language>{{ site.LanguageCode }}</Language>
|
||||
<LongName>{{ site.Title }} :: {{ site.Language.Lang }}</LongName>
|
||||
<OutputEncoding>UTF-8</OutputEncoding>
|
||||
<ShortName>Websearch</ShortName>
|
||||
<SyndicationRight>open</SyndicationRight>
|
||||
<ie:PreviewUrl type="text/html" method="GET" template="{{ site.BaseURL }}{{ site.Language.Lang }}/tags/{searchTerms}/"/>
|
||||
<moz:SearchForm>{{ site.BaseURL }}{{ site.Language.Lang }}/tags/{searchTerms}/</moz:SearchForm>
|
||||
<Url template="{{ site.BaseURL }}{{ site.Language.Lang }}/tags/{searchTerms}/" type="text/html" />
|
||||
<Url rel="self" template="{{ site.BaseURL }}opensearch.xml" type="application/opensearchdescription+xml" />
|
||||
</OpenSearchDescription>
|
||||
```
|
||||
|
||||
## autodiscovery
|
||||
|
||||
|
@ -105,24 +133,31 @@ Opensearch format description in your web site.
|
|||
If you have modified your Hugo configuration to generate an {{< inside2 a="atom" l="web:hugo:hugo-feed" t="Atom" >}} feed,
|
||||
you will need to modify it to add the following:
|
||||
|
||||
`<link href="{{ $.Site.BaseURL }}/opensearch.xml" rel="search" type="application/opensearchdescription+xml" title="Websearch" />`
|
||||
```html
|
||||
<link href="{{ site.BaseURL }}/opensearch.xml" rel="search" type="application/opensearchdescription+xml" title="Websearch" />
|
||||
```
|
||||
|
||||
### HTML
|
||||
|
||||
Add a `link` element:
|
||||
|
||||
`<link rel="search" href="/opensearch.xml" title="Websearch" type="application/opensearchdescription+xml">`
|
||||
```html
|
||||
<link rel="search" href="/opensearch.xml" title="Websearch" type="application/opensearchdescription+xml">
|
||||
```
|
||||
|
||||
### RSS
|
||||
|
||||
If you generate your {{< inside2 a="rss" l="web:hugo:hugo-feed" t="RSS" >}} feed,
|
||||
make sure to edit it, to add:
|
||||
|
||||
|
||||
* the `xmlns:atom="http://www.w3.org/2005/Atom"` attribute, into your `rss` element: <br>
|
||||
`<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">`
|
||||
* in order to declarate `atom:link` item, as: <br>
|
||||
`<atom:link href="{{ $.Site.BaseURL }}/opensearch.xml" rel="search" type="application/opensearchdescription+xml" title="Websearch" />`
|
||||
* the `xmlns:atom="http://www.w3.org/2005/Atom"` attribute, into your `rss` element:
|
||||
```html
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
```
|
||||
* in order to declarate `atom:link` item, as:
|
||||
```html
|
||||
<atom:link href="{{ site.BaseURL }}/opensearch.xml" rel="search" type="application/opensearchdescription+xml" title="Websearch" />
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
|
|
|
@ -24,8 +24,10 @@ Let's go back to the code !
|
|||
Firstly, I write a `$feed` variable; her value is the absolute path for
|
||||
the file **feed.json**.
|
||||
|
||||
`{{- $baseURL := (printf "%s%s/" $.Site.BaseURL $.Site.Language.Lang) | absLangURL -}}` <br>
|
||||
`{{- $feed := (printf "%s%s" $baseURL "/feed.json") | safeURL -}}`
|
||||
```hugo
|
||||
{{- $baseURL := site.BaseURL | absLangURL -}}
|
||||
{{- $feed := urls.JoinPath $baseURL "/feed.json" | absLangURL -}}
|
||||
```
|
||||
|
||||
### JQuery
|
||||
|
||||
|
@ -34,29 +36,100 @@ will directly call the content returned by the `getJSON` function.
|
|||
|
||||
The code:
|
||||
|
||||
{{< code "web-hugo-search-jquery-autocomplete-json-code-jqueryui" javascript >}}
|
||||
```js
|
||||
{{- with resources.Get $feed -}}
|
||||
<!-- Javascript -->
|
||||
<script>
|
||||
$(function() {
|
||||
var projects = [
|
||||
{{- range .items -}}
|
||||
{
|
||||
value: "{{ safeHTML .title }}",
|
||||
label: "{{ safeHTML .summary }}",
|
||||
url:"{{ safeURL .url }}"
|
||||
},
|
||||
{{- end -}}
|
||||
];
|
||||
$("#search").autocomplete({
|
||||
minLength: 0,
|
||||
source: projects,
|
||||
focus: function( event, ui ) {
|
||||
$("#search").val( ui.item.label );
|
||||
return false;
|
||||
},
|
||||
select: function( event, ui ) {
|
||||
$("#search").val( ui.item.label );
|
||||
$("#replyer").val( ui.item.value );
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.data('ui-autocomplete')._renderItem = function(ul, item) {
|
||||
return $('<li>')
|
||||
.append('<a href="' + item.url + '" alt="'+ item.label + '">' + item.value + '</a>' )
|
||||
.appendTo(ul);
|
||||
};
|
||||
});
|
||||
</script>
|
||||
{{- end -}}
|
||||
```
|
||||
|
||||
### HTML
|
||||
|
||||
Make HTML is always so simple:
|
||||
|
||||
{{< code "web-hugo-search-code-html-input" html >}}
|
||||
```html
|
||||
<input class="form-control" id="search" placeholder="{{ T "searchHolderTitle" }}">
|
||||
<input aria-hidden="true" id="replyer" class="hidden">
|
||||
```
|
||||
|
||||
### TL;DR
|
||||
|
||||
{{< file "web-hugo-seach-jquery-autocomplete-json-code-tldr" "search-json.html" html >}}
|
||||
```html
|
||||
<div id="search">
|
||||
<input class="form-control" id="search" placeholder="{{ T "searchHolderTitle" }}">
|
||||
<input aria-hidden="true" id="replyer" class="hidden">
|
||||
{{- $baseURL := site.BaseURL | absLangURL -}}
|
||||
{{- $feed := urls.JoinPath $baseURL "/feed.json" | absLangURL -}}
|
||||
{{- with resources.Get $feed -}}
|
||||
<!-- Javascript -->
|
||||
<script>
|
||||
$(function() {
|
||||
var projects = [
|
||||
{{- range .items -}}
|
||||
{
|
||||
value: "{{ safeHTML .title }}",
|
||||
label: "{{ safeHTML .summary }}",
|
||||
url:"{{ safeURL .url }}"
|
||||
},
|
||||
{{- end -}}
|
||||
];
|
||||
$("#search").autocomplete({
|
||||
minLength: 0,
|
||||
source: projects,
|
||||
focus: function( event, ui ) {
|
||||
$("#search").val( ui.item.label );
|
||||
return false;
|
||||
},
|
||||
select: function( event, ui ) {
|
||||
$("#search").val( ui.item.label );
|
||||
$("#replyer").val( ui.item.value );
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.data('ui-autocomplete')._renderItem = function(ul, item) {
|
||||
return $('<li>')
|
||||
.append('<a href="' + item.url + '" alt="'+ item.label + '">' + item.value + '</a>' )
|
||||
.appendTo(ul);
|
||||
};
|
||||
});
|
||||
</script>
|
||||
{{- end -}}
|
||||
</div>
|
||||
```
|
||||
|
||||
**Explains** :
|
||||
|
||||
The most astute will notice a detail that has its importance:
|
||||
* **look** the line 3: a condition check if Hugo is on its environment development. <br>
|
||||
In this case, the code is not builded. <br>
|
||||
(See section {{< anchor Error error >}} for more informations)
|
||||
|
||||
---
|
||||
|
||||
Try on the [homepage](/en/), to see the result…
|
||||
---
|
||||
|
||||
Voila!
|
||||
|
||||
### Error
|
||||
|
||||
|
@ -65,8 +138,6 @@ it made severals errors, and stop, as: <br>
|
|||
`ERROR 2020/08/27 08:16:41 Failed to get JSON resource “http://localhost:1313/fr/feed.json”: Get “http://localhost:1313/fr/feed.json”: dial tcp [::1]:1313: connect: connection refused`
|
||||
|
||||
{{< abbr A Answer >}}: The server is not able to call a data not builded.
|
||||
Its the reason why on the final script, there is one condition to check
|
||||
the environment.
|
||||
|
||||
----
|
||||
|
||||
|
@ -75,3 +146,5 @@ the environment.
|
|||
* {{< gohugo n="search" s="tools" >}}
|
||||
* Hugo `getJSON` function: {{< gohugo n="data-templates" s="templates" a="load-local-files" >}}
|
||||
* JQuery UI `autocomplete()` method: https://jqueryui.com/autocomplete
|
||||
|
||||
---
|
||||
|
|
|
@ -13,20 +13,12 @@ Adding a function `search` into static website made with Hugo can be done in dif
|
|||
|
||||
We will code this simply with JQuery+UI, in few minutes.
|
||||
|
||||
We will use the Hugo `.Site.Pages` variable, and the JQueryUI `autocomplete()` method.
|
||||
We will use the Hugo `site.Pages` variable, and the JQueryUI `autocomplete()` method.
|
||||
|
||||
I assume you known how to add correctly the both JQuery and JQueryUI librairies on your site.
|
||||
|
||||
## Codes
|
||||
|
||||
### Hugo
|
||||
|
||||
To obtain all pages:
|
||||
{{< code "web-hugo-search-code-hugo" hugo >}}
|
||||
|
||||
We create a `$pages` variable that contains all pages informations of the
|
||||
site. Now, we include it into the code JQuery:
|
||||
|
||||
### JQueryUI
|
||||
|
||||
As explain into the description section, we use the events of the method `autocomplete()`.
|
||||
|
@ -35,14 +27,50 @@ with the Hugo `range` function.
|
|||
|
||||
The JQuery code:
|
||||
|
||||
{{< code "web-hugo-search-code-jqueryui" javascript >}}
|
||||
|
||||
```js
|
||||
<script>
|
||||
$(function() {
|
||||
var projects = [
|
||||
{{- range site.Pages -}}
|
||||
{{- $url := .RelPermalink -}}
|
||||
{{- $title := .LinkTitle -}}
|
||||
{
|
||||
value: "{{ $title }}",
|
||||
label: "{{- if eq $url $baseURL }}{{ site.Params.description }}{{ else if in $url "tags" }}{{- T "pageListTitle" }}{{ $title }}{{ else }}{{- safeHTML .Params.description -}}{{ end -}}",
|
||||
url:"{{ $url }}"
|
||||
},
|
||||
{{- end -}}
|
||||
];
|
||||
$("#search").autocomplete({
|
||||
minLength: 0,
|
||||
source: projects,
|
||||
focus: function( event, ui ) {
|
||||
$("#search").val( ui.item.label );
|
||||
return false;
|
||||
},
|
||||
select: function( event, ui ) {
|
||||
$("#search").val( ui.item.label );
|
||||
$("#replyer").val( ui.item.value );
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.data('ui-autocomplete')._renderItem = function(ul, item) {
|
||||
return $('<li>')
|
||||
.append('<a href="' + item.url + '" alt="'+ item.label + '">' + item.value + '</a>' )
|
||||
.appendTo(ul);
|
||||
};
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
### HTML
|
||||
|
||||
And for the simplest code HTML, we use two elements `input` as:
|
||||
|
||||
{{< code "web-hugo-search-code-html-input" html >}}
|
||||
```html
|
||||
<input class="form-control" id="search" placeholder="{{ T "searchHolderTitle" }}">
|
||||
<input aria-hidden="true" id="replyer" class="hidden">
|
||||
```
|
||||
|
||||
* the first catch the searched text
|
||||
* the second return all found titles, and in the background the equivalent URL.
|
||||
|
@ -53,14 +81,58 @@ And for the simplest code HTML, we use two elements `input` as:
|
|||
|
||||
The fully code:
|
||||
|
||||
{{< code "web-hugo-search-code-tldr" html >}}
|
||||
```html
|
||||
<div id="search">
|
||||
<input class="form-control" id="search" placeholder="{{ T "searchHolderTitle" }}">
|
||||
<input aria-hidden="true" id="replyer" class="hidden">
|
||||
{{- $baseURL := site.BaseURL | absLangURL -}}
|
||||
<!-- Javascript -->
|
||||
<script>
|
||||
$(function() {
|
||||
var projects = [
|
||||
{{- range site.Pages -}}
|
||||
{{- $url := .RelPermalink -}}
|
||||
{{- $title := .LinkTitle -}}
|
||||
{
|
||||
value: "{{ $title }}",
|
||||
label: "{{- if eq $url $baseURL }}{{ site.Params.description }}{{ else if in $url "tags" }}{{- T "pageListTitle" }}{{ $title }}{{ else }}{{- safeHTML .Params.description -}}{{ end -}}",
|
||||
url:"{{ $url }}"
|
||||
},
|
||||
{{- end -}}
|
||||
];
|
||||
$("#search").autocomplete({
|
||||
minLength: 0,
|
||||
source: projects,
|
||||
focus: function( event, ui ) {
|
||||
$("#search").val( ui.item.label );
|
||||
return false;
|
||||
},
|
||||
select: function( event, ui ) {
|
||||
$("#search").val( ui.item.label );
|
||||
$("#replyer").val( ui.item.value );
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.data('ui-autocomplete')._renderItem = function(ul, item) {
|
||||
return $('<li>')
|
||||
.append('<a href="' + item.url + '" alt="'+ item.label + '">' + item.value + '</a>' )
|
||||
.appendTo(ul);
|
||||
};
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Demo
|
||||
|
||||
Voilà ! <br>
|
||||
In few minutes, an "internal search engine" is born on your static website Hugo.
|
||||
|
||||
Actually, on the [homepage](/en/), it's this {{< inside "web/hugo/hugo-search-jqueryui-autocomplete-json" "modified code" >}} running…
|
||||
See, the search holder on the menu navigation, at top right side ;)
|
||||
|
||||
----
|
||||
---
|
||||
|
||||
## Documentation
|
||||
|
||||
|
@ -75,5 +147,4 @@ Actually, on the [homepage](/en/), it's this {{< inside "web/hugo/hugo-search-jq
|
|||
* More explains about JQueryUI `Autocomplete()` method: See the [documentation](https://www.tutorialspoint.com/jqueryui/jqueryui_autocomplete.htm)
|
||||
* Another method to [build internal search engine](https://en.jeffprod.com/blog/2018/build-your-own-hugo-website-search-engine/), with VueJS + Axios librairies
|
||||
|
||||
----
|
||||
|
||||
---
|
||||
|
|
|
@ -9,9 +9,13 @@ tags: ["Hugo","Feed","RSS","Atom","JSON"]
|
|||
|
||||
## Description
|
||||
|
||||
Parmi les flux de données, {{< tag Hugo >}} est capable de créer plusieurs flux dont {{< abbr RSS "Really Simple Syndication" >}} *(actuellement, à la norme 2.0)*.
|
||||
Parmi les flux de données, {{< tag Hugo >}} est capable de créer plusieurs
|
||||
flux dont {{< abbr RSS "Really Simple Syndication" >}}
|
||||
*(actuellement, à la norme 2.0)*.
|
||||
|
||||
**Hugo** est donc capable de générer un flux {{< anchor RSS rss >}}, ou de type {{< anchor JSON json >}}, mais pas {{< anchor ATOM atom >}} - *pour ce dernier, nous verrons comment faire dans le chapitre ad hoc*.
|
||||
**Hugo** est donc capable de générer un flux {{< anchor RSS rss >}}, ou
|
||||
de type {{< anchor JSON json >}}, mais pas {{< anchor ATOM atom >}} -
|
||||
*pour ce dernier, nous verrons comment faire dans le chapitre ad hoc*.
|
||||
|
||||
## Documentation
|
||||
|
||||
|
@ -26,89 +30,139 @@ Un petit tour sur la documentation officielle Hugo :
|
|||
|
||||
## Détails Techniques
|
||||
|
||||
Commençons par les détails techniques suivants à-propos de la gestion de différents éléments ; chaque format de flux a ses propres spécificités, certaines sont communes ou peuvent se ressembler. Merci de lire les {{< anchor RFC "documentations tierces" >}} adéquates.
|
||||
Commençons par les détails techniques suivants à-propos de la gestion de
|
||||
différents éléments ; chaque format de flux a ses propres spécificités,
|
||||
certaines sont communes ou peuvent se ressembler. Merci de lire les
|
||||
{{< anchor RFC "documentations tierces" >}} adéquates.
|
||||
|
||||
### author
|
||||
|
||||
Les trois formats de flux gérent un élément `author` dans les différentes entrées générées. Quant à l'auteur du site, là où ATOM et JSON ont leur élément `author` avec leurs spécificités, RSS a son propre élément `managingEditor`, voire `webMaster`.
|
||||
Les trois formats de flux gérent un élément `author` dans les différentes
|
||||
entrées générées. Quant à l'auteur du site, là où ATOM et JSON ont leur
|
||||
élément `author` avec leurs spécificités, RSS a son propre élément
|
||||
`managingEditor`, voire `webMaster`.
|
||||
|
||||
Il faut configurer le bloc `author` dans le fichier de configuration, de telle manière : <br>
|
||||
`[author]` <br>
|
||||
`email = "courriel@domaine.tld"` <br>
|
||||
`name = "Nom Prénom"`
|
||||
Il faut configurer le bloc `author` dans le fichier de configuration,
|
||||
de telle manière :
|
||||
|
||||
```toml
|
||||
[params]
|
||||
[params.author]
|
||||
email = "courriel@domaine.tld"
|
||||
name = "Nom Prénom"
|
||||
```
|
||||
|
||||
### category
|
||||
|
||||
Là où ATOM et RSS sont capables de générer un élément `catégory`, JSON utilise l'élément `tag`.
|
||||
Là où ATOM et RSS sont capables de générer un élément `catégory`, JSON
|
||||
utilise l'élément `tag`.
|
||||
|
||||
Dans tous les cas, j'ai utilisé la taxonomie des tags pour les créer.
|
||||
|
||||
Il faut configurer la taxonomie dans le fichier de configuration, de telle manière : <br>
|
||||
`[taxonomies]` <br>
|
||||
`tag = "tags"`
|
||||
Il faut configurer la taxonomie dans le fichier de configuration, de
|
||||
telle manière :
|
||||
|
||||
```toml
|
||||
[taxonomies]
|
||||
tag = "tags"
|
||||
```
|
||||
|
||||
### copyright
|
||||
|
||||
Là où RSS a son élément `copyright`,
|
||||
|
||||
* ATOM peut annoncer par le biais d'un élément `link` qui permet de cibler un fichier de licence - *telle une licence {{< abbr CC "Creatives Commons" >}}* - ainsi que son élément `rights`.
|
||||
* ATOM peut annoncer par le biais d'un élément `link` qui permet de
|
||||
cibler un fichier de licence - *telle une licence {{< abbr CC "Creatives Commons" >}}* -
|
||||
ainsi que son élément `rights`.
|
||||
* JSON n'a rien de prévu.
|
||||
|
||||
Il faut configurer la variable `copyright` dans le fichier de configuration.
|
||||
|
||||
### description
|
||||
|
||||
Là où RSS et JSON ont leur élément `description` du flux, ATOM n'en a pas, mais il est possible d'utiliser l'élément `subtitle`.
|
||||
Là où RSS et JSON ont leur élément `description` du flux, ATOM n'en a pas,
|
||||
mais il est possible d'utiliser l'élément `subtitle`.
|
||||
|
||||
Concernant l'usage de l'élément `description`, j'utilise personnellement la variable `.Site.Params.description`.
|
||||
Concernant l'usage de l'élément `description`, j'utilise personnellement
|
||||
la variable `site.Params.description`.
|
||||
|
||||
Il faut configurer la variable `description` dans le fichier de configuration.
|
||||
|
||||
### generator
|
||||
|
||||
Seul ATOM et RSS sont capables de générer un élément `generator`, bien qu'ATOM le fasse plus finement.
|
||||
Seul ATOM et RSS sont capables de générer un élément `generator`, bien
|
||||
qu'ATOM le fasse plus finement.
|
||||
|
||||
On peut utiliser les variables spécifiques à Hugo.
|
||||
|
||||
### id
|
||||
|
||||
Pour RSS, l'identifiant d'une entrée est l'élément `guid`. ATOM et JSON ont un élément `id` . ATOM a aussi son identifiant de site.
|
||||
Pour RSS, l'identifiant d'une entrée est l'élément `guid`. ATOM et JSON
|
||||
ont un élément `id` . ATOM a aussi son identifiant de site.
|
||||
|
||||
Il est important de veiller à ce que cet identifiant soit unique ; il y a plusieurs manières de les générer :
|
||||
Il est important de veiller à ce que cet identifiant soit unique ; il y
|
||||
a plusieurs manières de les générer :
|
||||
|
||||
* Soit tout simplement par le biais de l'URL du site, ou de l'article correspondant à l'entrée : <br> `<id>{{ .Permalink }}</id>`
|
||||
* Soit en utilisant le schéma de notation `tag`, définie par la RFC 4151, de type `tag:identifiant,DATE:alphanumerique` et où `tag:identifiant,DATE` ne doit pas changer sur l'ensemble du site, seule la partie `alphanumerique` sera l'objet de l'unicité de l'article ou de l'identifiant du site :
|
||||
* où l'identifiant peut être soit une adresse mail, soit le nom de domaine ; ce dernier semble être la préférence.
|
||||
* où DATE doit correspondre à la norme ISO 8601, à minima l'année, codée sur 4 chiffres, telle que `2019` ; la préférence peut être donnée à la forme `YYYY-MM-DD` où l'année, le mois et le jour sont séparés par un tiret `-`, telle que `2019-10-07` qui peut correspondre à la date de création de votre domaine, par exemple.
|
||||
* Soit tout simplement par le biais de l'URL du site, ou de l'article
|
||||
correspondant à l'entrée : <br> `<id>{{ .Permalink }}</id>`
|
||||
* Soit en utilisant le schéma de notation `tag`, définie par la RFC 4151,
|
||||
de type `tag:identifiant,DATE:alphanumerique` et où `tag:identifiant,DATE`
|
||||
ne doit pas changer sur l'ensemble du site, seule la partie `alphanumerique`
|
||||
sera l'objet de l'unicité de l'article ou de l'identifiant du site :
|
||||
* où l'identifiant peut être soit une adresse mail, soit le nom de
|
||||
domaine ; ce dernier semble être la préférence.
|
||||
* où DATE doit correspondre à la norme ISO 8601, à minima l'année,
|
||||
codée sur 4 chiffres, telle que `2019` ; la préférence peut être
|
||||
donnée à la forme `YYYY-MM-DD` où l'année, le mois et le jour
|
||||
sont séparés par un tiret `-`, telle que `2019-10-07` qui peut
|
||||
correspondre à la date de création de votre domaine, par exemple.
|
||||
* où `alphanumerique` est un ensemble de lettres et de chiffres.
|
||||
* Pour exemple :
|
||||
* Pour l'identifiant du site : `{{ $url := urls.Parse .Permalink }}{{ $id := print "tag:" $url.Host ",2019-10-07:" }}<id>{{ $id }}website</id>`
|
||||
* Pour l'identifiant d'entrée : `<id>{{ $id }}{{ anchorize .RelPermalink }}</id>`
|
||||
* Pour RSS, remplacez la balise `<id>` par `<guid>`. De même, si vous utilisez la notation par tag ou par UURI, il vous faudra ajouter l'attribut `isPermalink`, tel que : `isPermaLink="false"`
|
||||
* Soit en utilisant le schéma de notation `UURI` définie par la RFC 4122 - *qui est humainement incompréhensible* ; l'avantage avec Hugo est qu'on peut la générer dynamiquement en utilisant la fonction `sha`, tout particulièrement `sha1` conforme à la version 5 de ladite numérotation, telle que : <br> `{{ $uuid := sha1 .Permalink }}<id>urn:uuid:{{substr $uuid 0 8}}-{{substr $uuid 10 4}}-{{substr $uuid 15 4}}-{{substr $uuid 20 4}}-{{substr $uuid 25 12}}</id>`
|
||||
* Pour l'identifiant du site :
|
||||
`{{ $url := urls.Parse .Permalink }}{{ $id := print "tag:" $url.Host ",2019-10-07:" }}<id>{{ $id }}website</id>`
|
||||
* Pour l'identifiant d'entrée :
|
||||
`<id>{{ $id }}{{ anchorize .RelPermalink }}</id>`
|
||||
* Pour RSS, remplacez la balise `<id>` par `<guid>`.
|
||||
De même, si vous utilisez la notation par tag ou par UURI,
|
||||
il vous faudra ajouter l'attribut `isPermalink`, tel que :
|
||||
`isPermaLink="false"`
|
||||
* Soit en utilisant le schéma de notation `UURI` définie par la RFC 4122 -
|
||||
*qui est humainement incompréhensible* ; l'avantage avec Hugo est qu'on
|
||||
peut la générer dynamiquement en utilisant la fonction `sha`, tout
|
||||
particulièrement `sha1` conforme à la version 5 de ladite numérotation,
|
||||
telle que :
|
||||
```hugo
|
||||
{{ $uuid := sha1 .Permalink }}<id>urn:uuid:{{substr $uuid 0 8}}-{{substr $uuid 10 4}}-{{substr $uuid 15 4}}-{{substr $uuid 20 4}}-{{substr $uuid 25 12}}</id>
|
||||
```
|
||||
|
||||
### image
|
||||
|
||||
Là où RSS gère l'élément `image` pour afficher le logo,
|
||||
|
||||
* ATOM et JSON gèrent deux éléments différents, `icon` pour l'image de favicon, et `logo` pour votre… logo !
|
||||
* ATOM et JSON gèrent deux éléments différents, `icon` pour l'image de
|
||||
favicon, et `logo` pour votre… logo !
|
||||
* JSON est capable, en plus, de gérer un avatar pour l'auteur.
|
||||
|
||||
### Limite
|
||||
|
||||
{{< note warning >}}Il semble nécessaire d'utiliser au moins Hugo v0.55.x{{< /note >}}
|
||||
|
||||
Le code Hugo suivant, *que j'utilise dans chacun des modèles*, permet de limiter le nombre d'entrées selon :
|
||||
Le code Hugo suivant, *que j'utilise dans chacun des modèles*, permet de
|
||||
limiter le nombre d'entrées selon :
|
||||
|
||||
* La limite du service RSS,
|
||||
* Si les pages ont le paramètre `disable_feed` sur `true`, elles ne sont pas incluses.
|
||||
* Si les pages ont le paramètre `disable_feed` sur `true`, elles ne sont
|
||||
pas incluses.
|
||||
* On capture le nombre de pages,
|
||||
* Puis on utilise la fonction Hugo `range` pour générer dynamiquement le nombre d'entrées - *l'usage de la fonction dans le modèle pour JSON différe légérement de celui pour les modèles ATOM et RSS* - :
|
||||
|
||||
`{{- $limit := (cond (le .Site.Config.Services.RSS.Limit 0) 65536 .Site.Config.Services.RSS.Limit) -}}` <br>
|
||||
`{{- $pages := where .Site.RegularPages ".Params.disable_feed" "!=" true -}}` <br>
|
||||
`{{- if ge $limit 1 -}}{{- $pages = $pages | first $limit -}}{{- end -}}` <br>
|
||||
* Puis on utilise la fonction Hugo `range` pour générer dynamiquement le
|
||||
nombre d'entrées - *l'usage de la fonction dans le modèle pour JSON
|
||||
différe légérement de celui pour les modèles ATOM et RSS* - :
|
||||
|
||||
```hugo
|
||||
{{- $limit := (cond (le site.Config.Services.RSS.Limit 0) 65536 site.Config.Services.RSS.Limit) -}}
|
||||
{{- $pages := where site.RegularPages ".Params.disable_feed" "!=" true -}}
|
||||
{{- if ge $limit 1 -}}{{- $pages = $pages | first $limit -}}{{- end -}}
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
|
@ -116,26 +170,76 @@ Le code Hugo suivant, *que j'utilise dans chacun des modèles*, permet de limite
|
|||
|
||||
### RSS
|
||||
|
||||
{{< note info >}}Il est possible de spécifier dans le fichier de configuration le format de sortie RSS pour `home`, `section` et les deux `taxonomy`, `taxonomyTerm`.{{< /note >}}
|
||||
{{< note info >}}Il est possible de spécifier dans le fichier de
|
||||
configuration le format de sortie RSS pour `home`, `section` et les deux
|
||||
`taxonomy`, `taxonomyTerm`.{{< /note >}}
|
||||
|
||||
Personnellement, je renomme le nom du flux RSS en modifiant dans le fichier de configuration, la variable `baseName` à `rss` parce que je ne pense pas que celui-ci doit porter le nom `index`. En effet, le nom `rss.xml` est plus parlant !
|
||||
Personnellement, je renomme le nom du flux RSS en modifiant dans le
|
||||
fichier de configuration, la variable `baseName` à `rss` parce que je ne
|
||||
pense pas que celui-ci doit porter le nom `index`.
|
||||
|
||||
`[outputs]` <br>
|
||||
`home = ["HTML", "RSS"]` <br>
|
||||
`[outputFormats.RSS]` <br>
|
||||
`baseName = "rss"`
|
||||
En effet, le nom `rss.xml` est plus parlant !
|
||||
|
||||
{{< note info >}}Sachez qu'il est possible de surcharger la génération native du flux RSS, en créant un modèle dans `_default`. {{< /note >}}
|
||||
```toml
|
||||
[outputs]
|
||||
home = ["HTML", "RSS"]
|
||||
[outputFormats.RSS]
|
||||
baseName = "rss"
|
||||
```
|
||||
|
||||
{{< note info >}}Sachez qu'il est possible de surcharger la génération
|
||||
native du flux RSS, en créant un modèle dans `_default`. {{< /note >}}
|
||||
|
||||
#### RSS:Template
|
||||
|
||||
{{< note warning >}}Il n'est pas nécessaire de créer ce modèle du fait que Hugo génére correctement, mais pour de l'anglais, le fichier RSS, nommé `index.xml`.{{< /note >}}
|
||||
{{< note warning >}}Il n'est pas nécessaire de créer ce modèle du fait
|
||||
que Hugo génére correctement, mais pour de l'anglais, le fichier RSS,
|
||||
nommé `index.xml`.{{< /note >}}
|
||||
|
||||
J'ai créé mon propre modèle, tenant compte du fait d'être multilangue.
|
||||
|
||||
----
|
||||
|
||||
{{< file "web-hugo-feed-template-rss" xml "layouts/_default/rss.xml" >}}
|
||||
```xml
|
||||
{{ printf `<?xml version="1.0" encoding="utf-8" standalone="yes" ?>` | safeHTML }}
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>{{ if eq .Title site.Title }}{{ site.Title }}{{ else }}{{ with .Title }}{{.}}{{ T "on" }}{{ end }}'{{ site.Title }}'{{ end }}</title>
|
||||
<link>{{ .Permalink }}</link>
|
||||
{{ with site.Params.description -}}<description>{{ . }}</description>{{- end }}
|
||||
<docs>http://blogs.law.harvard.edu/tech/rss</docs>
|
||||
<generator>Hugo {{ Hugo.Version }}</generator>
|
||||
<image>
|
||||
<description>Logo</description>
|
||||
<height>128</height>
|
||||
<link>{{ .Permalink }}</link>
|
||||
<title>{{ if eq .Title site.Title }}{{ site.Title }}{{ else }}{{ with .Title }}{{.}}{{ T "on" }}{{ end }}'{{ site.Title }}'{{ end }}</title>
|
||||
<url>{{ site.BaseURL }}img/Logo.png</url>
|
||||
<width>128</width>
|
||||
</image>
|
||||
{{ with site.LanguageCode }}<language>{{.}}</language>{{end}}
|
||||
{{ with site.Params.author.email }}<managingEditor>{{.}}{{ with site.Params.author.name }} ({{.}}){{end}}</managingEditor>
|
||||
<webMaster>{{.}}{{ with site.Author.name }} ({{.}}){{end}}</webMaster>{{end}}
|
||||
{{ with site.Copyright }}<copyright>© {{ $.Date.Format "2006" | safeHTML }} {{ site.Author.name }}; {{.}}</copyright>{{end}}
|
||||
{{ if not .Date.IsZero }}<lastBuildDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>{{ end }}
|
||||
{{ with .OutputFormats.Get "RSS" }}{{ printf `<atom:link href=%q rel="self" type=%q />` .Permalink .MediaType | safeHTML }}{{ end }}
|
||||
{{- $limit := (cond (le site.Config.Services.RSS.Limit 0) 65536 site.Config.Services.RSS.Limit) -}}
|
||||
{{- $pages := where site.Pages ".Params.disable_feed" "!=" true -}}
|
||||
{{- if ge $limit 1 -}}{{- $pages = $pages | first $limit -}}{{- end -}}
|
||||
{{- range first $limit $pages }}
|
||||
<item>
|
||||
<title>{{ .Title }}</title>
|
||||
<link>{{ .Permalink }}</link>
|
||||
{{ with .Summary }}<description>{{ . | html }}</description>{{end}}
|
||||
{{ with site.Params.author.email }}<author>{{.}}{{ with site.Params.author.name }} ({{.}}){{end}}</author>{{end}}{{ $url := printf "%s" "/tags/" | absLangURL }}
|
||||
{{ with .Params.tags }}{{ range . }}<category domain="{{ $url }}{{urlize .}}/">{{.}}</category>{{end}}{{end}}
|
||||
<guid>{{ .Permalink }}</guid>
|
||||
<pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
|
||||
</item>
|
||||
{{ end }}
|
||||
</channel>
|
||||
</rss>
|
||||
```
|
||||
|
||||
### Atom
|
||||
|
||||
|
@ -152,46 +256,107 @@ Il est nécessaire de modifier le fichier de configuration pour :
|
|||
##### Hugo >= 0.20
|
||||
Depuis Hugo 0.20, il faut ajouter :
|
||||
|
||||
`[mediaTypes]` <br>
|
||||
`[mediaTypes."application/atom+xml"]` <br>
|
||||
`suffix = "xml"`
|
||||
```toml
|
||||
[mediaTypes]
|
||||
[mediaTypes."application/atom+xml"]
|
||||
suffix = "xml"
|
||||
```
|
||||
|
||||
Là, nous avons donc implémenté un nouveau type de format ayant pour mime type : `application/atom+xml`, et pour nom d'extension : `xml`.
|
||||
Là, nous avons donc implémenté un nouveau type de format ayant pour mime
|
||||
type : `application/atom+xml`, et pour nom d'extension : `xml`.
|
||||
|
||||
##### Hugo >= 0.44
|
||||
|
||||
Depuis Hugo 0.44, pour que cela fonctionne correctement il faut ajouter :
|
||||
|
||||
`[mediaTypes]` <br>
|
||||
`[mediaTypes."application/atom+xml"]` <br>
|
||||
`suffixes = ["xml"]`
|
||||
```toml
|
||||
[mediaTypes]
|
||||
[mediaTypes."application/atom+xml"]
|
||||
suffixes = ["xml"]
|
||||
```
|
||||
|
||||
{{< note tip >}}Si votre ancienne configuration précédait la 0.44, il faut adapter/transformer la variable `suffix` en `suffixes = ['xml']` ! {{< /note >}}
|
||||
{{< note tip >}}Si votre ancienne configuration précédait la 0.44, il
|
||||
faut adapter/transformer la variable `suffix` en `suffixes = ['xml']` !
|
||||
{{< /note >}}
|
||||
|
||||
#### Atom::OuputFormat
|
||||
|
||||
La déclaration du format de sortie, à ajouter :
|
||||
|
||||
`[outputs]` <br>
|
||||
`[outputFormats.Atom]` <br>
|
||||
`baseName = "atom"` <br>
|
||||
`isPlainText = false` <br>
|
||||
`mediaType = "application/atom+xml"` <br>
|
||||
```toml
|
||||
[outputFormats.Atom]
|
||||
baseName = "atom"
|
||||
isPlainText = false
|
||||
mediaType = "application/atom+xml"
|
||||
```
|
||||
|
||||
Puis, il faut ajouter `"ATOM"` à votre variable `home`, tel que :
|
||||
|
||||
`[outputs]` <br>
|
||||
`home = ["HTML", "ATOM", "RSS"]`
|
||||
```toml
|
||||
[outputs]
|
||||
home = ["HTML", "ATOM", "RSS"]
|
||||
```
|
||||
|
||||
#### Atom::Template
|
||||
|
||||
Le modèle peut simplement être créé dans le répertoire `layouts/` et se nommer `index.atom.xml`, ou être dans son sous-répertoire `_default/` et se nommer, par exemple : `home.atom.xml`.
|
||||
Le modèle peut simplement être créé dans le répertoire `layouts/` et se
|
||||
nommer `index.atom.xml`, ou être dans son sous-répertoire `_default/` et
|
||||
se nommer, par exemple : `home.atom.xml`.
|
||||
|
||||
* Si le site est multilangue, les liens alternatifs vers la version de langue correspondante à l'entrée du site, aux flux atom, RSS, voire JSON sont générés.
|
||||
* Si le site est multilangue, les liens alternatifs vers la version de
|
||||
langue correspondante à l'entrée du site, aux flux atom, RSS, voire JSON
|
||||
sont générés.
|
||||
|
||||
----
|
||||
|
||||
{{< file "web-hugo-feed-template-atom" xml "layouts/_default/home.atom.xml" >}}
|
||||
```xml
|
||||
{{ printf `<?xml version="1.0" encoding="utf-8" standalone="yes" ?>` | safeHTML }}
|
||||
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="{{ with site.Language.Lang }}{{.}}{{end}}">
|
||||
<id>{{ .Permalink }}</id>
|
||||
<title>{{ if eq .Title site.Title }}{{ site.Title }}{{ else }}{{ with .Title }}{{.}}{{ T "on" }}{{ end }}'{{ site.Title }}'{{ end }}</title>
|
||||
{{ with site.Params.description -}}<subtitle>{{ . }}</subtitle>{{- end }}
|
||||
{{ with .OutputFormats.Get "ATOM" }}{{ printf `<link href=%q rel="self" type=%q />` .Permalink .MediaType | safeHTML }}{{end}}
|
||||
{{ range .AlternativeOutputFormats -}}
|
||||
<link href="{{ if eq .Name "HTML" }}{{ $.Permalink }}{{ else }}{{ printf `%s%s.%s` $.Permalink (.Name | lower) (index .MediaType.Suffixes 0) }}{{end}}" rel="alternate" {{ printf "type=%q" .MediaType.Type | safeHTMLAttr }} />
|
||||
{{end}}{{ if site.IsMultiLingual }}{{ range site.Languages }}{{ if ne .Lang site.Language.Lang }}{{ $lang := .Lang }}
|
||||
{{ with $.OutputFormats.Get "ATOM" }}{{ printf `<link href=%q hreflang=%q rel="alternate" type=%q />` (print $lang "/" .Name "." (index .MediaType.Suffixes 0) |absURL) $lang .MediaType | safeHTML }}{{end}}
|
||||
{{ range $.AlternativeOutputFormats -}}
|
||||
<link href="{{ if eq .Name "HTML" }}{{ printf `%s/` $lang | absURL }}{{ else }}{{ printf `%s/%s.%s` $lang (.Name | lower) (index .MediaType.Suffixes 0) | absURL }}{{end}}" hreflang="{{ $lang }}" rel="alternate" {{ printf "type=%q" .MediaType.Type | safeHTMLAttr }} />
|
||||
{{end}}{{end}}{{end}}{{end}}{{ with site.Copyright }}{{ $lang := site.Language.Lang }}
|
||||
<link href="http://creativecommons.org/publicdomain/zero/1.0/legalcode.{{ $lang }}" hreflang="{{ $lang }}" rel="license" />
|
||||
<link href="http://creativecommons.org/publicdomain/zero/1.0/deed.{{ $lang }}" hreflang="{{ $lang }}" rel="license" />
|
||||
<rights>© {{ $.Date.Format "2006" | safeHTML }} {{ site.Params.author.name }}</rights>{{end}}
|
||||
<icon>/img/favicon.ico</icon>
|
||||
{{ with site.Params.logo }}<logo>{{.}}</logo>{{end}}
|
||||
{{ if not .Date.IsZero }}<updated>{{ .Date.Format "2006-01-02T15:04:05-07:00" | safeHTML }}</updated>{{ end }}
|
||||
{{ with site.Params.author.name }}
|
||||
<author>
|
||||
<name>{{.}}</name>
|
||||
{{ with site.Params.author.email }}<email>{{.}}</email>{{end}}
|
||||
<uri>{{ $.Permalink }}</uri>
|
||||
</author>{{end}}
|
||||
<generator uri="https://gohugo.io" version="{{ Hugo.Version }}">Hugo</generator>
|
||||
{{- $limit := (cond (le site.Config.Services.RSS.Limit 0) 65536 site.Config.Services.RSS.Limit) -}}
|
||||
{{- $pages := where site.RegularPages ".Params.disable_feed" "!=" true -}}
|
||||
{{- if ge $limit 1 -}}{{- $pages = $pages | first $limit -}}{{- end -}}
|
||||
{{- range first $limit $pages }}
|
||||
<entry>
|
||||
<id>{{ .Permalink }}</id>
|
||||
<link href="{{ .Permalink }}" rel="alternate" type="text/html" />
|
||||
<title>{{ .Title }}</title>{{ with site.Params.author }}
|
||||
<author>
|
||||
<name>{{.}}</name>
|
||||
</author>{{end}}{{ $url := printf "%s" "/tags/" | absLangURL }}{{ with .Params.tags }}{{ range . }}
|
||||
<category term="{{.}}" scheme="{{ print $url (urlize .) | absLangURL }}/" />{{end}}
|
||||
{{end}}
|
||||
{{ with .Content }}<content type="html">{{ `<![CDATA[` | safeHTML }}{{.}}]]></content>{{end}}
|
||||
{{ with .Summary }}<summary type="html">{{ `<![CDATA[` | safeHTML }}{{.}}]]></summary>{{end}}
|
||||
<published>{{ .Date.Format "2006-01-02T15:04:05-07:00" | safeHTML }}</published>
|
||||
{{ if gt .Lastmod .Date }}<updated>{{ .Lastmod.Format "2006-01-02T15:04:05-07:00" | safeHTML }}</updated>{{end}}
|
||||
</entry>
|
||||
{{ end }}
|
||||
</feed>
|
||||
```
|
||||
|
||||
### JSON
|
||||
|
||||
|
@ -201,38 +366,80 @@ Pour générer le flux JSON, nous nous conformerons à la norme JSON Feed v1.
|
|||
|
||||
La déclaration de sortie de format à ajouter :
|
||||
|
||||
`[outputs]` <br>
|
||||
`[outputFormats.JSON]` <br>
|
||||
`mediaType = "application/json"` <br>
|
||||
`baseName = "feed"` <br>
|
||||
`suffix = "json"` <br>
|
||||
`IsHTML = false` <br>
|
||||
`IsPlainText = true` <br>
|
||||
`noUgly = false` <br>
|
||||
`rel = "alternate"`
|
||||
```toml
|
||||
[outputFormats.JSON]
|
||||
mediaType = "application/json"
|
||||
baseName = "feed"
|
||||
suffix = "json"
|
||||
IsHTML = false
|
||||
IsPlainText = true
|
||||
noUgly = false
|
||||
rel = "alternate"
|
||||
```
|
||||
|
||||
Puis, il faut ajouter la déclaration `JSON` à votre variable `home`, tel que :
|
||||
|
||||
`[outputs]` <br>
|
||||
`home = ["HTML", "ATOM", "JSON", "RSS"]`
|
||||
```toml
|
||||
[outputs]
|
||||
`home = ["HTML", "ATOM", "JSON", "RSS"]
|
||||
```
|
||||
|
||||
#### JSON::Template
|
||||
|
||||
##### JSON: Détails
|
||||
|
||||
En plus de la {{< anchor limite limite >}} mentionnée plus haut, nous récupèrons le nombre de page, pour boucler correctement car le dernier `item` ne doit pas être suivi du symbole ',' :
|
||||
|
||||
`{{- $length := (len $pages) -}}`
|
||||
En plus de la {{< anchor limite limite >}} mentionnée plus haut, nous
|
||||
récupèrons le nombre de page, pour boucler correctement car le dernier
|
||||
`item` ne doit pas être suivi du symbole ',' :
|
||||
|
||||
```hugo
|
||||
{{- $length := (len $pages) -}}
|
||||
```
|
||||
Et en fin de boucle `range`, nous ajoutons :
|
||||
```hugo
|
||||
{{ if ne (add $index 1) $length }},{{ end }}
|
||||
```
|
||||
Ainsi tant qu'il y a un élément suivant, il est précédé du symbole ','
|
||||
jusqu'au dernier.
|
||||
|
||||
`{{ if ne (add $index 1) $length }},{{ end }}`
|
||||
---
|
||||
|
||||
Ainsi tant qu'il y a un élément suivant, il est précédé du symbole ',' jusqu'au dernier.
|
||||
|
||||
____
|
||||
|
||||
{{< file "web-hugo-feed-template-json" json "layouts/index.json" >}}
|
||||
```json
|
||||
{{- $limit := (cond (le site.Config.Services.RSS.Limit 0) 65536 site.Config.Services.RSS.Limit) -}}
|
||||
{{- $pages := where site.RegularPages ".Params.disable_feed" "!=" true -}}
|
||||
{{- if ge $limit 1 -}}{{- $pages = $pages | first $limit -}}{{- end -}}
|
||||
{{- $length := (len $pages) -}}
|
||||
{
|
||||
"version": "https://jsonfeed.org/version/1",
|
||||
"title": "{{ site.Title }}",
|
||||
"home_page_url": "{{ site.BaseURL }}",
|
||||
{{ with .OutputFormats.Get "JSON" -}}"feed_url": "{{.Permalink}}",{{- end }}
|
||||
{{ with site.Params.description -}}"description": "{{ . }}",{{- end }}
|
||||
{{ with site.Params.author.name }}
|
||||
"author": {
|
||||
"avatar": "{{ with site.Params.logo }}{{ . }}{{ end}}",
|
||||
"name": "{{ . }}",
|
||||
"url": "http://huc.fr.eu.org"
|
||||
},
|
||||
{{- end }}
|
||||
{{ with site.Params.logo }}"icon": "{{ . }}",{{- end }}
|
||||
"favicon": "/img/favicon.ico",
|
||||
"items": [ {{- range $index, $elements := $pages -}}
|
||||
{
|
||||
"id": "{{ .Permalink }}",
|
||||
"url": "{{ .Permalink }}",
|
||||
"title": "{{ .Title | plainify }}",
|
||||
{{ with site.Params.Author }}"author": { "name": "{{ . }}" }{{ end }}{{ with .Content }},
|
||||
"content_text": {{ . | plainify | jsonify }},
|
||||
"content_html": {{ . | safeHTML | jsonify }}{{ end }}{{ with .Summary }},
|
||||
"summary": {{ . | plainify | jsonify }}{{ end }}{{ with .Params.tags }},
|
||||
"tags": [{{ range $tindex, $tag := . }}{{ if $tindex }}, {{ end }}"{{ $tag| htmlEscape }}"{{ end }}]{{ end }}{{ if .PublishDate }},
|
||||
"date_published": "{{ .PublishDate.Format "2006-01-02T15:04:05-01:00" | safeHTML }}"{{ end }}{{ if gt .Lastmod .Date }},
|
||||
"date_modified": "{{ .Lastmod.Format "2006-01-02T15:04:05-01:00" | safeHTML }}"{{ end }}
|
||||
}{{ if ne (add $index 1) $length }},{{ end }}{{- end }}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Documentations tierces
|
||||
|
||||
|
|
|
@ -48,9 +48,11 @@ Le type mime lié au format de description d'Opensearch est : `application/opens
|
|||
|
||||
Depuis Hugo 0.20, il faut ajouter :
|
||||
|
||||
`[mediaTypes]` <br>
|
||||
`[mediaTypes."application/opensearchdescription+xml"]` <br>
|
||||
`suffix = "xml"`
|
||||
```toml
|
||||
[mediaTypes]
|
||||
[mediaTypes."application/opensearchdescription+xml"]
|
||||
suffix = "xml"
|
||||
```
|
||||
|
||||
Là, nous avons donc implémenté un nouveau type de format ayant pour mime type : `application/opensearchdescription+xml`, et pour nom d'extension : `xml`.
|
||||
|
||||
|
@ -58,9 +60,11 @@ Là, nous avons donc implémenté un nouveau type de format ayant pour mime type
|
|||
|
||||
Depuis Hugo 0.44, pour que cela fonctionne correctement il faut ajouter :
|
||||
|
||||
`[mediaTypes]` <br>
|
||||
`[mediaTypes."application/opensearchdescription+xml"]` <br>
|
||||
`suffixes = ["xml"]`
|
||||
```toml
|
||||
[mediaTypes]
|
||||
[mediaTypes."application/opensearchdescription+xml"]
|
||||
suffixes = ["xml"]
|
||||
```
|
||||
|
||||
{{< note tip >}}Si votre ancienne configuration précédait la 0.44, il faut adapter/transformer la variable `suffix` en `suffixes = ['xml']` ! {{< /note >}}
|
||||
|
||||
|
@ -68,18 +72,22 @@ Depuis Hugo 0.44, pour que cela fonctionne correctement il faut ajouter :
|
|||
|
||||
La déclaration du format de sortie, à ajouter :
|
||||
|
||||
`[outputs]` <br>
|
||||
`[outputFormats.OpenSearch]` <br>
|
||||
`baseName = "opensearch"` <br>
|
||||
`isHTML = false` <br>
|
||||
`isPlainText = false` <br>
|
||||
`mediaType = "application/opensearchdescription+xml"` <br>
|
||||
`noUgly = true` <br>
|
||||
```toml
|
||||
[outputs]
|
||||
[outputFormats.OpenSearch]
|
||||
baseName = "opensearch"
|
||||
isHTML = false
|
||||
isPlainText = false
|
||||
mediaType = "application/opensearchdescription+xml"
|
||||
noUgly = true
|
||||
```
|
||||
|
||||
Puis, il faut ajouter `"OpenSearch"` à votre variable `home`, tel que :
|
||||
|
||||
`[outputs]` <br>
|
||||
`home = ["HTML", "OpenSearch"]` <br>
|
||||
```toml
|
||||
[outputs]
|
||||
home = ["HTML", "OpenSearch"]
|
||||
```
|
||||
|
||||
### Template
|
||||
|
||||
|
@ -95,7 +103,27 @@ Tenez-en compte, en supprimant les déclarations de langue, si ce n'est
|
|||
pas votre cas.
|
||||
{{</note>}}
|
||||
|
||||
{{< file "web-hugo-opensearch-template" xml "layouts/_default/index.opensearch.xml" >}}
|
||||
```xml
|
||||
{{ printf `<?xml version="1.0" encoding="utf-8" ?>` | safeHTML }}
|
||||
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/" xmlns:ie="http://schemas.microsoft.com/Search/2008/" xmlns:moz="http://www.mozilla.org/2006/browser/search/">
|
||||
<Attribution>© {{ $.Date.Format "2006" | safeHTML }} {{ site.Author.name }}; http://creativecommons.org/publicdomain/zero/1.0/legalcode.{{ site.Language.Lang }}</Attribution>
|
||||
<Contact>{{ site.Author.email | safeHTML }}</Contact>
|
||||
<Description>{{ i18n "opensearchDescription" }}</Description>
|
||||
<Developer>{{ site.Author.name | safeHTML }}</Developer>
|
||||
<InputEncoding>utf-8</InputEncoding>
|
||||
<Image width="64" height="64" type="image/png">{{ site.BaseURL }}img/Logo-64px.png</Image>
|
||||
<Image width="16" height="16" type="image/vnd.microsoft.icon">{{ site.BaseURL }}img/favicon.ico</Image>
|
||||
<Language>{{ site.LanguageCode }}</Language>
|
||||
<LongName>{{ site.Title }} :: {{ site.Language.Lang }}</LongName>
|
||||
<OutputEncoding>UTF-8</OutputEncoding>
|
||||
<ShortName>Websearch</ShortName>
|
||||
<SyndicationRight>open</SyndicationRight>
|
||||
<ie:PreviewUrl type="text/html" method="GET" template="{{ site.BaseURL }}{{ site.Language.Lang }}/tags/{searchTerms}/"/>
|
||||
<moz:SearchForm>{{ site.BaseURL }}{{ site.Language.Lang }}/tags/{searchTerms}/</moz:SearchForm>
|
||||
<Url template="{{ site.BaseURL }}{{ site.Language.Lang }}/tags/{searchTerms}/" type="text/html" />
|
||||
<Url rel="self" template="{{ site.BaseURL }}opensearch.xml" type="application/opensearchdescription+xml" />
|
||||
</OpenSearchDescription>
|
||||
```
|
||||
|
||||
## autopublication
|
||||
|
||||
|
@ -110,23 +138,31 @@ l'élément `ShortName` !{{</note>}}
|
|||
Si vous avez modifié votre configuration de Hugo pour générer un flux {{< inside2 a="atom" l="web:hugo:hugo-feed" t="Atom" >}}
|
||||
il vous faudra le modifier pour ajouter ce qui suit :
|
||||
|
||||
`<link href="{{ $.Site.BaseURL }}/opensearch.xml" rel="search" type="application/opensearchdescription+xml" title="Websearch" />`
|
||||
```html
|
||||
<link href="{{ site.BaseURL }}/opensearch.xml" rel="search" type="application/opensearchdescription+xml" title="Websearch" />
|
||||
```
|
||||
|
||||
### HTML
|
||||
|
||||
Ajouter un élément `link`, tel que :
|
||||
|
||||
`<link rel="search" href="/opensearch.xml" title="Websearch" type="application/opensearchdescription+xml">`
|
||||
```html
|
||||
<link rel="search" href="/opensearch.xml" title="Websearch" type="application/opensearchdescription+xml">
|
||||
```
|
||||
|
||||
### RSS
|
||||
|
||||
Si vous générez votre flux {{< inside2 a="rss" l="web:hugo:hugo-feed" t="RSS" >}}, veillez à le modifier pour ajouter :
|
||||
|
||||
* la déclaration de l'attribut `xmlns:atom="http://www.w3.org/2005/Atom"`
|
||||
dans votre élément `rss`, tel que : <br>
|
||||
`<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">`
|
||||
* afin de pouvoir déclarer un élément `atom:link`, tel que : <br>
|
||||
`<atom:link href="{{ $.Site.BaseURL }}/opensearch.xml" rel="search" type="application/opensearchdescription+xml" title="Websearch" />`
|
||||
dans votre élément `rss`, tel que :
|
||||
```html
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
```
|
||||
* afin de pouvoir déclarer un élément `atom:link`, tel que :
|
||||
```html
|
||||
<atom:link href="{{ site.BaseURL }}/opensearch.xml" rel="search" type="application/opensearchdescription+xml" title="Websearch" />
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
|
|
|
@ -21,6 +21,10 @@ Hugo a une fonction native `getJSON`.
|
|||
|
||||
Reprenons le code…
|
||||
|
||||
{{< note warning >}}
|
||||
Ne fonctionne pas en environnement de développement !
|
||||
{{</note>}}
|
||||
|
||||
## Code
|
||||
|
||||
### Hugo
|
||||
|
@ -28,8 +32,10 @@ Reprenons le code…
|
|||
Je construis une variable `$feed` qui injectera la valeur du chemin absolu
|
||||
de mon fichier **feed.json**.
|
||||
|
||||
`{{- $baseURL := (printf "%s%s/" $.Site.BaseURL $.Site.Language.Lang) | absLangURL -}}` <br>
|
||||
`{{- $feed := (printf "%s%s" $baseURL "/feed.json") | safeURL -}}`
|
||||
```hugo
|
||||
{{- $baseURL := site.BaseURL | absLangURL -}}
|
||||
{{- $feed := urls.JoinPath $baseURL "/feed.json" | absLangURL -}}
|
||||
```
|
||||
|
||||
### JQuery
|
||||
|
||||
|
@ -40,41 +46,114 @@ par la fonction `getJSON`. La suite du traitement est faite par la méthode
|
|||
|
||||
Voici le code :
|
||||
|
||||
{{< code "web-hugo-search-jquery-autocomplete-json-code-jqueryui" javascript >}}
|
||||
```js
|
||||
{{- with resources.Get $feed -}}
|
||||
<!-- Javascript -->
|
||||
<script>
|
||||
$(function() {
|
||||
var projects = [
|
||||
{{- range .items -}}
|
||||
{
|
||||
value: "{{ safeHTML .title }}",
|
||||
label: "{{ safeHTML .summary }}",
|
||||
url:"{{ safeURL .url }}"
|
||||
},
|
||||
{{- end -}}
|
||||
];
|
||||
$("#search").autocomplete({
|
||||
minLength: 0,
|
||||
source: projects,
|
||||
focus: function( event, ui ) {
|
||||
$("#search").val( ui.item.label );
|
||||
return false;
|
||||
},
|
||||
select: function( event, ui ) {
|
||||
$("#search").val( ui.item.label );
|
||||
$("#replyer").val( ui.item.value );
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.data('ui-autocomplete')._renderItem = function(ul, item) {
|
||||
return $('<li>')
|
||||
.append('<a href="' + item.url + '" alt="'+ item.label + '">' + item.value + '</a>' )
|
||||
.appendTo(ul);
|
||||
};
|
||||
});
|
||||
</script>
|
||||
{{- end -}}
|
||||
```
|
||||
|
||||
### HTML
|
||||
|
||||
La partie de code HTML est toujours aussi simple :
|
||||
|
||||
{{< code "web-hugo-search-code-html-input" html >}}
|
||||
```html
|
||||
<input class="form-control" id="search" placeholder="{{ T "searchHolderTitle" }}">
|
||||
<input aria-hidden="true" id="replyer" class="hidden">
|
||||
```
|
||||
|
||||
### TL;DR
|
||||
|
||||
L'ensemble du code :
|
||||
|
||||
{{< file "web-hugo-seach-jquery-autocomplete-json-code-tldr" "search-json.html" html >}}
|
||||
```html
|
||||
<div id="search">
|
||||
<input class="form-control" id="search" placeholder="{{ T "searchHolderTitle" }}">
|
||||
<input aria-hidden="true" id="replyer" class="hidden">
|
||||
{{- $baseURL := site.BaseURL | absLangURL -}}
|
||||
{{- $feed := urls.JoinPath $baseURL "/feed.json" | absLangURL -}}
|
||||
{{- with resources.Get $feed -}}
|
||||
<!-- Javascript -->
|
||||
<script>
|
||||
$(function() {
|
||||
var projects = [
|
||||
{{- range .items -}}
|
||||
{
|
||||
value: "{{ safeHTML .title }}",
|
||||
label: "{{ safeHTML .summary }}",
|
||||
url:"{{ safeURL .url }}"
|
||||
},
|
||||
{{- end -}}
|
||||
];
|
||||
$("#search").autocomplete({
|
||||
minLength: 0,
|
||||
source: projects,
|
||||
focus: function( event, ui ) {
|
||||
$("#search").val( ui.item.label );
|
||||
return false;
|
||||
},
|
||||
select: function( event, ui ) {
|
||||
$("#search").val( ui.item.label );
|
||||
$("#replyer").val( ui.item.value );
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.data('ui-autocomplete')._renderItem = function(ul, item) {
|
||||
return $('<li>')
|
||||
.append('<a href="' + item.url + '" alt="'+ item.label + '">' + item.value + '</a>' )
|
||||
.appendTo(ul);
|
||||
};
|
||||
});
|
||||
</script>
|
||||
{{- end -}}
|
||||
</div>
|
||||
```
|
||||
|
||||
**Explications** :
|
||||
---
|
||||
|
||||
Les plus avisés remarqueront un détail qui a son importance :
|
||||
* **regardez bien** la ligne trois, j'ai implémenté une condition qui teste si on est dans
|
||||
l'environnement de développement local, si oui le code n'est pas généré. <br>
|
||||
Pour l'explication, lire la section {{< anchor Erreur erreur >}}…
|
||||
Voilà !
|
||||
|
||||
---
|
||||
|
||||
Pour ce qui est de la démonstration, c'est ce qu'il y a sur la [page d'accueil](/fr/) de ce site ;)
|
||||
|
||||
### Erreur
|
||||
|
||||
{{< abbr Q Question >}} : Lors de la génération en local, vous avez une multitude d'erreur, telle
|
||||
que la suivante et le serveur s'arrête tout seul : <br>
|
||||
{{< abbr Q Question >}} : Lors de la génération en local, vous avez une
|
||||
multitude d'erreur, telle que la suivante et le serveur s'arrête
|
||||
tout seul : <br>
|
||||
`ERROR 2020/08/27 08:16:41 Failed to get JSON resource “http://localhost:1313/fr/feed.json”: Get “http://localhost:1313/fr/feed.json”: dial tcp [::1]:1313: connect: connection refused`
|
||||
|
||||
{{< abbr R Réponse >}} : Et, oui, en local, le serveur n'est pas capable d'appeler une donnée qui
|
||||
n'est pas encore générée. C'est pourquoi dans le script final, une condition
|
||||
est imbriquée pour vérifier l'environnement de création.
|
||||
|
||||
{{< abbr R Réponse >}} : En environnement local, le serveur n'est pas
|
||||
capable d'appeler une donnée qui n'est pas encore générée.
|
||||
|
||||
----
|
||||
|
||||
|
@ -83,3 +162,5 @@ est imbriquée pour vérifier l'environnement de création.
|
|||
* La documentation officielle : {{< gohugo n="search" s="tools" >}} - *lien en anglais*
|
||||
* La fonction Hugo `getJSON` : {{< gohugo n="data-templates" s="templates" a="load-local-files" >}} - *lien en anglais*
|
||||
* La méthode JQuery UI `autocomplete()` : https://jqueryui.com/autocomplete - *lien en anglais*
|
||||
|
||||
---
|
||||
|
|
|
@ -9,41 +9,80 @@ translationKey: "hugo-jqueryui-autocomplete"
|
|||
|
||||
## Description
|
||||
|
||||
Intégrer une fonction de recherche au sein du site généré par Hugo peut se faire de différentes manières.
|
||||
Intégrer une fonction de recherche au sein du site généré par Hugo peut
|
||||
se faire de différentes manières.
|
||||
|
||||
On va implémenter une manière très simple avec JQuery+UI, et cela nous prendra vraiment très peu de temps.
|
||||
On va implémenter une manière très simple avec JQuery+UI, et cela nous
|
||||
prendra vraiment très peu de temps.
|
||||
|
||||
Étant donné qu'on peut parcourir l'ensemble des pages du site grâce à la variable `.Site.Pages`, on va se servir du mécanisme de la méthode `autocomplete()` fournie par la bibliothèque JQueryUI, pour restituer les différents résultats selon le texte écrit.
|
||||
Étant donné qu'on peut parcourir l'ensemble des pages du site grâce à
|
||||
la variable globale `site.Pages`, on va se servir du mécanisme de la
|
||||
méthode `autocomplete()` fournie par la bibliothèque JQueryUI, pour
|
||||
restituer les différents résultats selon le texte écrit.
|
||||
|
||||
Bien sûr, j'assume le fait que vous savez intégrer les appels de scripts JQuery et JQueryUI au sein de votre propre site.
|
||||
Bien sûr, j'assume le fait que vous savez intégrer les appels de scripts
|
||||
JQuery et JQueryUI au sein de votre propre site.
|
||||
|
||||
## Codes
|
||||
|
||||
### Hugo
|
||||
|
||||
Pour récupèrer les pages en codant Hugo :
|
||||
|
||||
{{< code "web-hugo-search-code-hugo" hugo >}}
|
||||
|
||||
Nous créeons une variable `$pages` qui contient l'ensemble des pages du site, que nous allons inclure dans le code JQuery.
|
||||
|
||||
### JQueryUI
|
||||
|
||||
Pour la partie JQuery, nous utilisons la gestion des événements de la méthode `autocomplete()`, à la différence près est que la variable `var projects` va être implémentée par le biais de la fonction Hugo `range` appliquée sur la variable `$pages`.
|
||||
Pour la partie JQuery, nous utilisons la gestion des événements de la
|
||||
méthode `autocomplete()`, à la différence près est que la variable
|
||||
`projects` va être implémentée par le biais de la fonction Hugo `range`.
|
||||
|
||||
Le code JQuery :
|
||||
|
||||
{{< code "web-hugo-search-code-jqueryui" javascript >}}
|
||||
```js
|
||||
<script>
|
||||
$(function() {
|
||||
var projects = [
|
||||
{{- range site.Pages -}}
|
||||
{{- $url := .RelPermalink -}}
|
||||
{{- $title := .LinkTitle -}}
|
||||
{
|
||||
value: "{{ $title }}",
|
||||
label: "{{- if eq $url $baseURL }}{{ site.Params.description }}{{ else if in $url "tags" }}{{- T "pageListTitle" }}{{ $title }}{{ else }}{{- safeHTML .Params.description -}}{{ end -}}",
|
||||
url:"{{ $url }}"
|
||||
},
|
||||
{{- end -}}
|
||||
];
|
||||
$("#search").autocomplete({
|
||||
minLength: 0,
|
||||
source: projects,
|
||||
focus: function( event, ui ) {
|
||||
$("#search").val( ui.item.label );
|
||||
return false;
|
||||
},
|
||||
select: function( event, ui ) {
|
||||
$("#search").val( ui.item.label );
|
||||
$("#replyer").val( ui.item.value );
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.data('ui-autocomplete')._renderItem = function(ul, item) {
|
||||
return $('<li>')
|
||||
.append('<a href="' + item.url + '" alt="'+ item.label + '">' + item.value + '</a>' )
|
||||
.appendTo(ul);
|
||||
};
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
### HTML
|
||||
|
||||
Quant à la partie HTML, elle est très simple ; il faut à minima les deux éléments `input` suivants :
|
||||
Quant à la partie HTML, elle est très simple ; il faut à minima les deux
|
||||
éléments `input` suivants :
|
||||
|
||||
{{< code "web-hugo-search-code-html-input" html >}}
|
||||
```html
|
||||
<input class="form-control" id="search" placeholder="{{ T "searchHolderTitle" }}">
|
||||
<input aria-hidden="true" id="replyer" class="hidden">
|
||||
```
|
||||
|
||||
* Le premier élément `input` est celui qui "capte" le texte recherché
|
||||
* le second va permettre de retourner les informations trouvées.
|
||||
* La déclaration Hugo `{{ i18n "searchHolderTitle" }}` est juste pour le contexte multilangue de ce site ; à remplacer par du texte selon votre goût…
|
||||
* La déclaration Hugo `{{ i18n "searchHolderTitle" }}` est juste pour le
|
||||
contexte multilangue de ce site ; à remplacer par du texte selon votre goût…
|
||||
|
||||
Que vous faites suivre du code Hugo puis du code JQuery
|
||||
|
||||
|
@ -51,20 +90,59 @@ Que vous faites suivre du code Hugo puis du code JQuery
|
|||
|
||||
L'ensemble du code :
|
||||
|
||||
{{< code "web-hugo-search-code-tldr" html >}}
|
||||
```html
|
||||
<div id="search">
|
||||
<input class="form-control" id="search" placeholder="{{ T "searchHolderTitle" }}">
|
||||
<input aria-hidden="true" id="replyer" class="hidden">
|
||||
{{- $baseURL := site.BaseURL | absLangURL -}}
|
||||
<!-- Javascript -->
|
||||
<script>
|
||||
$(function() {
|
||||
var projects = [
|
||||
{{- range site.Pages -}}
|
||||
{{- $url := .RelPermalink -}}
|
||||
{{- $title := .LinkTitle -}}
|
||||
{
|
||||
value: "{{ $title }}",
|
||||
label: "{{- if eq $url $baseURL }}{{ site.Params.description }}{{ else if in $url "tags" }}{{- T "pageListTitle" }}{{ $title }}{{ else }}{{- safeHTML .Params.description -}}{{ end -}}",
|
||||
url:"{{ $url }}"
|
||||
},
|
||||
{{- end -}}
|
||||
];
|
||||
$("#search").autocomplete({
|
||||
minLength: 0,
|
||||
source: projects,
|
||||
focus: function( event, ui ) {
|
||||
$("#search").val( ui.item.label );
|
||||
return false;
|
||||
},
|
||||
select: function( event, ui ) {
|
||||
$("#search").val( ui.item.label );
|
||||
$("#replyer").val( ui.item.value );
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.data('ui-autocomplete')._renderItem = function(ul, item) {
|
||||
return $('<li>')
|
||||
.append('<a href="' + item.url + '" alt="'+ item.label + '">' + item.value + '</a>' )
|
||||
.appendTo(ul);
|
||||
};
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
```
|
||||
|
||||
Et, voilà ! <br>
|
||||
En quelques minutes, un "moteur de recherche" interne intégré à votre site Hugo.
|
||||
|
||||
*Les plus attentifs remarqueront de subtiles différences entre ce code entier
|
||||
et les explications ci-dessus… <br>
|
||||
Je vous laisse chercher !* ;-)
|
||||
---
|
||||
|
||||
Pour ce qui est de la démonstration, c'est ce qu'il y avait sur la [page d'accueil](/) de ce site. <br>
|
||||
Maintenant, c'est la version appelant le flux de syndication JSON qui
|
||||
fonctionne. *(cf : {{< inside "web/hugo/hugo-search-jqueryui-autocomplete-json" "" >}}* !
|
||||
## Démonstration
|
||||
|
||||
----
|
||||
Pour ce qui est de la démonstration, c'est ce qu'il y a dans le menu,
|
||||
en haut à droite de chacune des pages du site.
|
||||
|
||||
---
|
||||
|
||||
## Documentations
|
||||
|
||||
|
@ -75,5 +153,4 @@ fonctionne. *(cf : {{< inside "web/hugo/hugo-search-jqueryui-autocomplete-json"
|
|||
* De plus amples explications sur la méthode `Autocomplete()` de JQueryUI : lire la [documentation](https://www.tutorialspoint.com/jqueryui/jqueryui_autocomplete.htm) - *lien en anglais*
|
||||
* Une autre méthode de [moteur de recherche interne](https://fr.jeffprod.com/blog/2018/un-moteur-de-recherche-interne-pour-votre-site-hugo/), cette fois-ci avec les bibliothèques VueJS + Axios
|
||||
|
||||
----
|
||||
|
||||
---
|
||||
|
|
|
@ -28,8 +28,8 @@ Le principe est l'utilisation des alias d'URL.
|
|||
|
||||
En partant du principe de l'utilisation du format toml, ouvrez le fichier que vous voulez rediriger et dans son entête, ajoutez :
|
||||
|
||||
```cfg
|
||||
aliases: [/ancienne/URL/de/publication/fichier/]
|
||||
```toml
|
||||
aliases = [/ancienne/URL/de/publication/fichier/]
|
||||
```
|
||||
|
||||
*Si votre format de fichier de configuration est autre, adaptez !*
|
||||
|
@ -41,13 +41,13 @@ suivantes :
|
|||
|
||||
⇒ Ajoutez un type de media
|
||||
|
||||
```cfg
|
||||
```toml
|
||||
[mediaTypes."conf/nginx"]
|
||||
```
|
||||
|
||||
⇒ Ajoutez une sortie à générer, pour la variable **home** :
|
||||
|
||||
```cfg
|
||||
```toml
|
||||
[outputs]
|
||||
home = ["HTML", "nginx", …]
|
||||
```
|
||||
|
@ -55,7 +55,7 @@ suivantes :
|
|||
⇒ Ajoutez la sortie du format adéquat pour créer le fichier de redirections
|
||||
pour nginx :
|
||||
|
||||
```cfg
|
||||
```toml
|
||||
[outputFormats.nginx]
|
||||
baseName = "redirections.conf"
|
||||
isPlainText = true
|
||||
|
@ -70,11 +70,10 @@ Puis, créer le **layout** nécessaire : `layout/index.nginx`, tel que :
|
|||
|
||||
```cfg
|
||||
# Nginx redirect
|
||||
{{ range $p := .Site.Pages -}}
|
||||
{{ range .Aliases }}
|
||||
rewrite ^{{ . }}$ {{ $p.RelPermalink }} permanent;
|
||||
{{ end -}}
|
||||
{{- end -}}
|
||||
{{- range $p := site.Pages -}}
|
||||
{{- range .Aliases }}
|
||||
rewrite ^{{ . }}$ {{ $p.RelPermalink }} permanent;{{ end }}
|
||||
{{- end }}
|
||||
```
|
||||
|
||||
---
|
||||
|
@ -102,7 +101,7 @@ nginx: [emerg] open() "/var/www/htdocs/doc.huc.fr.eu.org/www/fr/nginx-conf/redir
|
|||
|
||||
Et, oui le fichier existe bien, au bon endroit :
|
||||
|
||||
```
|
||||
```sh
|
||||
$ ls -al /var/www/htdocs/doc.huc.fr.eu.org/www/fr/nginx-config/redirections.conf
|
||||
-rw-r--r-- 1 www www 397 Jul 28 13:23 /var/www/htdocs/doc.huc.fr.eu.org/www/fr/nginx-config/redirections.conf
|
||||
```
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
# Nginx redirect
|
||||
{{ range $p := site.Pages -}}
|
||||
{{ range .Aliases }}
|
||||
rewrite ^{{ . }}$ {{ $p.RelPermalink }} permanent;
|
||||
{{ end -}}
|
||||
{{- end -}}
|
||||
{{- range $p := site.Pages -}}
|
||||
{{- range .Aliases }}
|
||||
rewrite ^{{ . }}$ {{ $p.RelPermalink }} permanent;{{ end }}
|
||||
{{- end }}
|
||||
|
|
|
@ -59,8 +59,9 @@
|
|||
{{ partial "utils/icon" (dict "$" $.Dot "name" "search" "class" "post-meta-icon") }}
|
||||
<input class="form-control" id="search" placeholder="{{ T "searchHolderTitle" }}">
|
||||
<input aria-hidden="true" id="replyer" class="hidden" hidden>
|
||||
{{- if eq hugo.Environment "development" -}}{{ partial "utils/search.js" (dict "Dot" .Dot) }}{{ else }}{{ partial "utils/search.json" (dict "Dot" .Dot) }}{{- end -}}
|
||||
</li>
|
||||
{{/* if eq hugo.Environment "development" -}}{{ partial "utils/search.js" . }}{{ else }}{{ partial "utils/search.json" . }}{{- end */}}
|
||||
{{- partial "utils/search.js" . -}}
|
||||
</li>
|
||||
</ul>
|
||||
{{- end -}}
|
||||
</nav>
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
{{- $baseURL := (partial "func/baseURL" .) | relLangURL -}}
|
||||
<!-- Javascript -->
|
||||
{{- $currentNode := . -}}
|
||||
{{- $currentNode.Scratch.Set "pages" site.Pages -}}
|
||||
{{- $pages := ($currentNode.Scratch.Get "pages") -}}
|
||||
{{- $baseURL := (partial "func/baseURL" .) | absLangURL -}}
|
||||
<script>
|
||||
$(function() {
|
||||
var projects = [
|
||||
{{- range $pages -}}
|
||||
{{- $url := .Permalink | safeURL -}}
|
||||
{{- $title := safeHTML .Title -}}
|
||||
{{- range site.Pages -}}
|
||||
{{- $url := .RelPermalink -}}
|
||||
{{- $title := .LinkTitle -}}
|
||||
{
|
||||
value: "{{ $title }}",
|
||||
label: "{{- if eq $url $baseURL }}{{ site.Params.description }}{{ else if in $url "tags" }}{{- T "pageListTitle" }}{{ $title }}{{ else }}{{- safeHTML .Params.description -}}{{ end -}}",
|
||||
|
|
|
@ -1,22 +1,17 @@
|
|||
{{- $baseURL := (partial "func/baseURL" .) | absLangURL -}}
|
||||
{{- $feed := urls.JoinPath $baseURL "/feed.json" | absLangURL -}}{{ $feed }}
|
||||
{{- with resources.Get $feed -}}
|
||||
<!-- Javascript -->
|
||||
<script>
|
||||
{{/* $baseURL := (printf "%s%s" $.Site.BaseURL $.Site.Language.Lang) | absLangURL */}}
|
||||
{{- $baseURL := (partial "func/baseURL" .) | absLangURL -}}
|
||||
{{- $feed := (printf "%s%s" $baseURL "/feed.json") | safeURL -}}
|
||||
$(function() {
|
||||
var projects = [
|
||||
{{- with getJSON $feed -}}
|
||||
{{- range .items -}}
|
||||
{{- $url := safeURL .url -}}
|
||||
{{- $title := safeHTML .title -}}
|
||||
{{- $desc := safeHTML .summary -}}
|
||||
{{- range .items -}}
|
||||
{
|
||||
value: "{{ $title }}",
|
||||
label: "{{ $desc }}",
|
||||
url:"{{ $url }}"
|
||||
value: "{{ safeHTML .title }}",
|
||||
label: "{{ safeHTML .summary }}",
|
||||
url:"{{ safeURL .url }}"
|
||||
},
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
];
|
||||
$("#search").autocomplete({
|
||||
minLength: 0,
|
||||
|
@ -38,3 +33,6 @@ $(function() {
|
|||
};
|
||||
});
|
||||
</script>
|
||||
{{- else -}}
|
||||
<!-- unavailable resource {{ $feed }} -->
|
||||
{{- end -}}
|
||||
|
|
Loading…
Reference in New Issue