RSS permalink is Atom permalink somehow

The URL in the RSS self link is wrong:

<atom:link href="https://willfaught.com/paige/atom.xml" rel="self" type="application/rss+xml"/>

It should be https://willfaught.com/paige/rss.xml, not https://willfaught.com/paige/atom.xml.

The code in layouts/_default/rss.xml is:

{{ $page := . }}
...
{{ printf `<atom:link href="%s" rel="self" type="application/rss+xml"/>` $page.Permalink | safeHTML }}

In the site’s hugo.toml, I have:

[outputs]
home = ["atom", "html", "json", "rss"]
section = ["atom", "html", "rss"]
taxonomy = ["atom", "html", "rss"]

In the module’s hugo.toml, I have:

[mediatypes."application/atom+xml"]
suffixes = ["xml"]

[outputformats.atom]
basename = "atom"
ishtml = false
isplaintext = false
mediatype = "application/atom+xml"
name = "atom"
nougly = true
permalinkable = false
rel = "alternate"

[outputformats.rss]
basename = "rss"
ishtml = false
isplaintext = false
mediatype = "application/rss+xml"
name = "rss"
nougly = true
permalinkable = false
rel = "alternate"

I have layouts/_default/rss.xml and layouts/_default/list.atom.xml.

No idea why .Permalink in layouts/_default/rss.xml is https://willfaught.com/paige/atom.xml. :confused:

Does anyone see the cause?

Why do you use print in the template?

<atom:link href="{{.RelPermalink}}" rel="alternate" type="{{ safeHTML .MediaType.Type }}" />

.RelPermalink is a solution :wink:

I think I was having encoding issues with the type attribute value. I like your idea of using safeHTML just for the attribute.

I redefined RSS as FEED type to exclude collisions with build-in types.
You can set a fix type in the template :wink:

<atom:link href="{{.RelPermalink}}" rel="alternate" type="application/rss+xml" />

For cross reference: https://github.com/gohugoio/hugo/issues/11555

@jmooring The repro steps that I put in the ticket do show the issue for me:

  1. git clone git@github.com:willfaught/paige.git
  2. cd paige
  3. git checkout f00db61 # the commit before my workaround fix
  4. cd exampleSite
  5. hugo server --enableGitInfo
  6. curl http://localhost:1313/rss.xml | grep atom:link

Output:

<atom:link href="http://localhost:1313/atom.xml" rel="self" type="application/rss+xml"/>

I understand. But unless I’m missing something, with the simple test case we have proven that there is not a bug. So it is something about your site or theme. If you can come up with a minimal example, so that we don’t have to dig through lines of code, that would be quite helpful.

It’s proven that there’s not a bug for a simple test case, but it hasn’t proven that there isn’t a bug triggered by non-trivial, yet valid behavior. I don’t know what I can do to simplify the test case further. I did verify that if you strip out everything from Paige’s exampleSite except for go.mod, go.sum, and hugo.toml, it still reproduces:

All of go.mod:

module github.com/willfaught/paige/exampleSite

go 1.20

require github.com/willfaught/paige v0.70.3-0.20231012041032-f00db61ac995 // indirect
replace github.com/willfaught/paige => ../

All of hugo.toml:

[[module.imports]]
path = "github.com/willfaught/paige"

[outputs]
home = ["atom", "html", "rss"]

Beyond that, there is only the RSS template in Paige. layouts/_default/rss.xml:

{{ $page := . }}

{{ $copyright := site.Copyright }}
{{ $description := or $page.Description "Recent content" }}
{{ $format := "Mon, 02 Jan 2006 15:04:05 MST" }}
{{ $guids := dict }}
{{ $html := $page.AlternativeOutputFormats.Get "html" }}
{{ $language := site.LanguageCode | default site.Language.Lang }}
{{ $lastbuilddate := (partial "paige/changed.html" $page).Format $format }}
{{ $limit := site.Config.Services.RSS.Limit }}
{{ $link := ($page.AlternativeOutputFormats.Get "html").Permalink }}
{{ $managingeditor := $page.Param "paige.feed.rss.managing_editor" }}
{{ $pagetitle := $page.Title | markdownify | plainify }}
{{ $sitetitle := site.Title | markdownify | plainify }}
{{ $subpages := slice }}
{{ $webmaster := $page.Param "paige.feed.rss.web_master" }}

{{ range (cond $page.IsHome site $page).RegularPages }}
    {{ if not (.Param "paige.feed.hide_page") }}
        {{ $subpages = $subpages | append . }}
    {{ end }}
{{ end }}

{{ if gt $limit 0 }}
    {{ $subpages = $subpages | first $limit }}
{{ end }}

{{ $titles := slice ($page.Title | markdownify) }}

{{ range .Ancestors }}
    {{ $titles = $titles | append (.Title | markdownify) }}
{{ end }}

{{ $title := delimit $titles " · " }}

{{ if not $title }}
    {{ warnf "layouts/_default/rss.xml: page %s does not have a title" $page.RelPermalink }}
{{ end }}

{{ printf "<?xml version=\"1.0\" encoding=\"utf-8\"?>" | safeHTML }}
<rss version="2.0" {{ with $language }} xml:lang="{{ . }}" {{ end }} xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        {{ printf `<atom:link href="%s" rel="self" type="application/rss+xml"/>` $page.Permalink | safeHTML }}
...

That’s all there is.

If you add this content at layouts/_default/rss.xml in exampleSite:

{{ $page := . }}

{{ $language := "" }}

{{ printf "<?xml version=\"1.0\" encoding=\"utf-8\"?>" | safeHTML }}
<rss version="2.0" {{ with $language }} xml:lang="{{ . }}" {{ end }} xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        {{ printf `<atom:link href="%s" rel="self" type="application/rss+xml"/>` $page.Permalink | safeHTML }}
    </channel>
</rss>

it still reproduces.

Could the issue be in how Atom is configured in Paige? I have in Paige’s hugo.toml:

[mediatypes."application/atom+xml"]    
suffixes = ["xml"]

[outputformats.atom]
basename = "atom"
ishtml = false
isplaintext = false
mediatype = "application/atom+xml"
name = "atom"
nougly = true
permalinkable = false
rel = "alternate"

[outputformats.rss]
basename = "rss"
ishtml = false
isplaintext = false
mediatype = "application/rss+xml"
name = "rss"
nougly = true
permalinkable = false
rel = "alternate"

OK, let’s troubleshoot this together…

Step 1

Can I reproduce the problem you describe using your theme, your example site, and your RSS template?

git clone --recurse-submodules https://github.com/willfaught/paige
cd paige/
git checkout f00db61
cd exampleSite/
hugo server --enableGitInfo
curl http://localhost:1313/rss.xml | grep atom:link

Yes.

Step 2

Can I reproduce the problem you describe using your theme, your example site, and Hugo’s built-in RSS template?

No.

Step 3

What is different about your RSS template?

Your RSS template (where $page is the context passed into the template):

{{ printf `<atom:link href="%s" rel="self" type="application/rss+xml"/>` $page.Permalink | safeHTML }}

The built-in RSS template:

{{- with .OutputFormats.Get "RSS" }}
  {{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML }}
{{- end }}

Step 4

Why does that matter?

https://gohugo.io/templates/output-formats/#link-to-output-formats?

.Permalink and .RelPermalink on Page will return the first output format defined for that page (usually HTML if nothing else is defined). This is regardless of the template file they are being called from.

{{ with .OutputFormats.Get "json" }}
{{ .RelPermalink }} → /that-page/index.json
{{ end }}

https://gohugo.io/templates/rss/#include-feed-reference

{{ with .OutputFormats.Get "rss" -}}
{{ printf .Rel .MediaType.Type .Permalink site.Title | safeHTML }}
{{ end }}

And the “first output format” you defined for that page was…

home = ["atom", "html", "json", "rss"]

…atom.

Please use the construct as shown in the documentation, and as used in the built-in RSS template.

1 Like

I see, I wasn’t thinking of page permalinks as referring to a particular output format, but of course they do. This does the trick:

{{ $feed := ($page.OutputFormats.Get "rss").Permalink }}

Thank you so much! :pray:

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.