Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

RSS feed converts relative urls to absolute urls #282

Closed
wants to merge 1 commit into from

1 participant

@amanking

A common guideline is to use absolute urls instead of relative urls for RSS feeds. This is because some feed readers such as feedburner do not resolve the relative urls to the feed source domain. Relative urls also become a problem when people receive feed updates via email.

This pull request converts relative urls to absolute urls when compiling the RSS xml.

Please note that the request is against this commit:
8918706
Google Analytics now optionally supports setting _setDomainName using domain_name config value

I could not successfully get my current blog to work against the latest master of ruhoh.rb

@amanking

Closing this pull request as the commit was not against latest code. A merge-able pull request for the same issue is here: #284

@amanking amanking closed this
@amanking amanking deleted the amanking:rss_with_absolute_urls branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 4, 2014
  1. @amanking

    RSS feed converts relative urls to absolute urls to support reading p…

    amanking authored
    …osts correctly in feedburner and email
This page is out of date. Refresh to see the latest.
View
25 features/javascripts.feature
@@ -4,11 +4,17 @@ Feature: Javascripts
so I can make my content interactive
Scenario: Defining javascripts
- Given some files with values:
- | file | body |
- | javascripts/base.js | var meep; |
- | javascripts/app.js | console.log('haro world') |
- | javascripts/custom.js | console.log('haro world') |
+ Given a config file with value:
+ """
+ {
+ "production_url" : "http://www.fakedomain.com"
+ }
+ """
+ And some files with values:
+ | file | body |
+ | javascripts/base.js | var meep; |
+ | javascripts/app.js | console.log('haro world') |
+ | javascripts/custom.js | console.log('haro world') |
And the file "_root/index.html" with body:
"""
{{# javascripts.load }}
@@ -22,8 +28,13 @@ Feature: Javascripts
And this file should have the fingerprinted javascripts "base, app, custom"
Scenario: Defining javascripts in a theme
- Given a config file with values:
- | sample_theme | { "use" : "theme" } |
+ Given a config file with value:
+ """
+ {
+ "production_url" : "http://www.fakedomain.com",
+ "sample_theme": { "use" : "theme" }
+ }
+ """
And some files with values:
| file | body |
| javascripts/base.js | var meep; |
View
56 features/rss.feature
@@ -0,0 +1,56 @@
+Feature: RSS
+ As a content publisher
+ I want to generate RSS feed for my posts
+ so that my blog subscribers can track my writings
+
+ Scenario: Generate RSS feed if enabled
+ Given a config file with value:
+ """
+ {
+ "production_url" : "http://www.fakedomain.com",
+ "posts" : { "rss" : { "enable" : true } }
+ }
+ """
+ And some files with values:
+ | file | body |
+ | posts/watermelon.html | I like to eat watermelon =) |
+ | posts/orange.html | I do not like to eat orange |
+ When I compile my site
+ Then my compiled site should have the file "posts/rss.xml"
+ And this file should contain the content "http://www.fakedomain.com"
+ And this file should contain the content "I like to eat watermelon =)"
+ And this file should contain the content "I do not like to eat orange"
+
+ Scenario: Do not generate RSS feed if not enabled
+ Given a config file with value:
+ """
+ {
+ "production_url" : "http://www.fakedomain.com",
+ "posts" : { "rss" : { "enable" : false } }
+ }
+ """
+ And some files with values:
+ | file | body |
+ | posts/watermelon.html | I like to eat watermelon =) |
+ | posts/orange.html | I do not like to eat orange |
+ When I compile my site
+ Then my compiled site should NOT have the file "posts/rss.xml"
+
+ Scenario: Generate RSS feed with all relative urls converted to absolute urls to support various feed readers including feedburner and emailed posts
+ Given a config file with value:
+ """
+ {
+ "production_url" : "http://www.fakedomain.com",
+ "posts" : { "rss" : { "enable" : true } }
+ }
+ """
+ And some files with values:
+ | file | body |
+ | posts/watermelon.html | I like to eat <a href="articles/fruits/fav.html">watermelon</a> =)|
+ | posts/orange.html | I do not like to eat <a href="http://www.othersite.com/fruits/orange.html">orange</a> |
+ | posts/apple.html | I like to eat <a href="articles/fruits/fav.html">apple</a> <img src="/images/smiley.html"><span> especially <a href="articles/fruits/red-apples.html">red ones</a></span> |
+ When I compile my site
+ Then my compiled site should have the file "posts/rss.xml"
+ And this file should contain the content "I like to eat <a href="http://www.fakedomain.com/articles/fruits/fav.html">watermelon</a> =)"
+ And this file should contain the content "I do not like to eat <a href="http://www.othersite.com/fruits/orange.html">orange</a>"
+ And this file should contain the content "I like to eat <a href="http://www.fakedomain.com/articles/fruits/fav.html">apple</a> <img src="http://www.fakedomain.com/images/smiley.html"><span> especially <a href="http://www.fakedomain.com/articles/fruits/red-apples.html">red ones</a></span>"
View
4 features/step_defs.rb
@@ -2,6 +2,10 @@
matcher.downcase.gsub(' ', '_')
end
+Given(/^a config file with value:$/) do |string|
+ make_config(JSON.parse(string))
+end
+
Given(/^a config file with values:$/) do |table|
data = table.rows_hash
data.each{ |key, value| data[key] = JSON.parse(value) }
View
25 features/stylesheets.feature
@@ -4,11 +4,17 @@ Feature: Stylesheets
so I can make my content presentation pleasing to the eye and intuitive for my readers
Scenario: Defining stylesheets
- Given some files with values:
- | file | body |
- | stylesheets/base.css | body { color: black } |
- | stylesheets/app.css | div { color: black } |
- | stylesheets/custom.css | div { color: black } |
+ Given a config file with value:
+ """
+ {
+ "production_url" : "http://www.fakedomain.com"
+ }
+ """
+ And some files with values:
+ | file | body |
+ | stylesheets/base.css | body { color: black } |
+ | stylesheets/app.css | div { color: black } |
+ | stylesheets/custom.css | div { color: black } |
And the file "_root/index.html" with body:
"""
{{# stylesheets.load }}
@@ -22,8 +28,13 @@ Feature: Stylesheets
And this file should have the fingerprinted stylesheets "base, app, custom"
Scenario: Defining stylesheets in a theme
- Given a config file with values:
- | sample_theme | { "use" : "theme" } |
+ Given a config file with value:
+ """
+ {
+ "production_url" : "http://www.fakedomain.com",
+ "sample_theme": { "use" : "theme" }
+ }
+ """
And some files with values:
| file | body |
| stylesheets/base.css | blah {} |
View
12 features/widgets/google_prettify.feature
@@ -4,9 +4,15 @@ Feature: Google Prettify Widget
so I can easily add customized functionality without polluting my content files
Scenario: Rendering a custom defined widget
- Given some files with values:
- | file | body |
- | _root/index.md | {{{ widgets.google_prettify }}} |
+ Given a config file with value:
+ """
+ {
+ "production_url" : "http://www.fakedomain.com"
+ }
+ """
+ And some files with values:
+ | file | body |
+ | _root/index.md | {{{ widgets.google_prettify }}} |
When I compile my site
Then my compiled site should have the file "index.html"
And this file should have the content node "script[src='http://cdnjs.cloudflare.com/ajax/libs/prettify/188.0.0/prettify.js']|"
View
32 features/widgets/syntax.feature
@@ -4,32 +4,32 @@ Feature: Syntax widget
so users can more easily understand code examples I publish
Scenario: Using prettify syntax highlighter
- Given the file "config.yml" with body:
+ Given a config file with value:
"""
- widgets:
- syntax:
- use: "prettify"
+ {
+ "production_url" : "http://www.fakedomain.com",
+ "widgets" : { "syntax" : { "use" : "prettify" } }
+ }
"""
- Given some files with values:
- | file | body |
- | _root/index.md | {{{ widgets.syntax }}} |
+ And some files with values:
+ | file | body |
+ | _root/index.md | {{{ widgets.syntax }}} |
When I compile my site
Then my compiled site should have the file "index.html"
And this file should have the content node "script[src='/assets/widgets/syntax/javascripts/prettify.js']|"
And my compiled site should have the file "assets/widgets/syntax/javascripts/prettify.js"
Scenario: Using prettify syntax highlighter with cdn enabled
- Given the file "config.yml" with body:
+ Given a config file with value:
"""
- widgets:
- syntax:
- use: "prettify"
- cdn:
- enable: true
+ {
+ "production_url" : "http://www.fakedomain.com",
+ "widgets" : { "syntax" : { "use" : "prettify", "cdn" : { "enable" : true } } }
+ }
"""
- Given some files with values:
- | file | body |
- | _root/index.md | {{{ widgets.syntax }}} |
+ And some files with values:
+ | file | body |
+ | _root/index.md | {{{ widgets.syntax }}} |
When I compile my site
Then my compiled site should have the file "index.html"
And this file should have the content node "script[src='http://cdnjs.cloudflare.com/ajax/libs/prettify/188.0.0/prettify.js']|"
View
40 lib/ruhoh/resources/pages/compiler.rb
@@ -7,7 +7,7 @@ def run
pages = @collection.all
resource_name = @collection.resource_name
Ruhoh::Friend.say { cyan "#{resource_name.capitalize}: (#{pages.count} #{resource_name})" }
-
+
FileUtils.cd(@ruhoh.paths.compiled) {
pages.each do |data|
view = @ruhoh.master_view(data['pointer'])
@@ -35,9 +35,9 @@ def pagination
total_pages = (pages_count.to_f/config["per_page"]).ceil
Ruhoh::Friend.say { cyan "#{resource_name} paginator: (#{total_pages} pages)" }
-
+
FileUtils.cd(@ruhoh.paths.compiled) {
- total_pages.times.map { |i|
+ total_pages.times.map { |i|
# if a root page is defined we assume it's getting compiled elsewhere.
next if (i.zero? && config["root_page"])
@@ -72,15 +72,16 @@ def rss
xml.rss(:version => '2.0') {
xml.channel {
xml.title_ data['title']
- xml.link_ @ruhoh.config['production_url']
- xml.pubDate_ Time.now
+ xml.description_ (data['description'] ? data['description'] : data['title'])
+ xml.link_ production_url
+ xml.pubDate_ Time.now
pages.each do |page|
view = @ruhoh.master_view(page.pointer)
xml.item {
xml.title_ page.title
- xml.link "#{@ruhoh.config['production_url']}#{page.url}"
+ xml.link "#{production_url}#{page.url}"
xml.pubDate_ page.date if page.date
- xml.description_ (page.try(:description) ? page.description : view.render_content)
+ xml.description_ with_absolute_urls(page.try(:description) ? page.description : view.render_content)
}
end
}
@@ -97,5 +98,28 @@ def rss
Ruhoh::Friend.say { green " > #{compiled_path}" }
}
end
+
+ private
+
+ def with_absolute_urls(content_html)
+ doc = Nokogiri::HTML::DocumentFragment.parse(content_html)
+ doc.xpath("*[@href|@src]|*//*[@href|@src]").each do |tag|
+ fix_url_in(tag, 'href') || fix_url_in(tag, 'src')
+ end
+ doc.to_s
+ end
+
+ def absolutify_url(url)
+ URI.join(production_url, url)
+ end
+
+ def production_url
+ @ruhoh.config['production_url']
+ end
+
+ def fix_url_in(tag, attribute)
+ return unless tag[attribute]
+ tag[attribute] = absolutify_url(tag[attribute])
+ end
end
-end
+end
Something went wrong with that request. Please try again.