Skip to content

Commit

Permalink
[iar#178] Allow customization of robots.txt.
Browse files Browse the repository at this point in the history
Serve `/robots.txt` from a template instead of from a static file to
allow for customization by extensions and site owners. See
ckan/ideas#178.
  • Loading branch information
torfsen committed Jul 15, 2016
1 parent 5a92e2c commit 9756909
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 6 deletions.
3 changes: 3 additions & 0 deletions ckan/config/routing.py
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,9 @@ def make_map():
m.connect('/testing/primer', action='primer')
m.connect('/testing/markup', action='markup')

# robots.txt
map.connect('/(robots.txt)', controller='template', action='view')

# Mark all unmarked routes added up until now as core routes
for route in map.matchlist:
if not hasattr(route, '_ckan_core'):
Expand Down
11 changes: 8 additions & 3 deletions ckan/controllers/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

import ckan.lib.base as base
import ckan.lib.render
from ckan.common import response


class TemplateController(base.BaseController):

def view(self, url):
"""By default, the final controller tried to fulfill the request
u"""By default, the final controller tried to fulfill the request
when no other routes match. It may be used to display a template
when all else fails, e.g.::
Expand All @@ -28,12 +29,16 @@ def view(self, url):
By default this controller aborts the request with a 404 (Not
Found)
"""
if url.endswith(u'.txt'):
response.headers[u'Content-Type'] = u'text/plain; charset=utf-8'
# Default content-type is text/html
try:
return base.render(url)
except ckan.lib.render.TemplateNotFound:
if url.endswith('.html'):
if url.endswith(u'.html'):
base.abort(404)
url += '.html'
url += u'.html'
response.headers[u'Content-Type'] = u'text/html; charset=utf-8'
try:
return base.render(url)
except ckan.lib.render.TemplateNotFound:
Expand Down
6 changes: 4 additions & 2 deletions ckan/public/robots.txt → ckan/templates/robots.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
User-agent: *
{% block all_user_agents -%}
Disallow: /dataset/rate/
Disallow: /revision/
Disallow: /dataset/*/history
Disallow: /api/

User-Agent: *
Crawl-Delay: 10
{%- endblock %}

{% block additional_user_agents -%}
{%- endblock %}
19 changes: 19 additions & 0 deletions ckan/tests/controllers/test_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# encoding: utf-8

from nose.tools import assert_equal

import ckan.tests.helpers as helpers


class TestTemplateController(helpers.FunctionalTestBase):

def test_content_type(self):
cases = {
u'/robots.txt': u'text/plain; charset=utf-8',
u'/page': u'text/html; charset=utf-8',
u'/page.html': u'text/html; charset=utf-8',
}
app = self._get_test_app()
for url, expected in cases.iteritems():
response = app.get(url, status=200)
assert_equal(response.headers.get(u'Content-Type'), expected)
1 change: 0 additions & 1 deletion ckan/tests/test_coding_standards.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,6 @@ def find_unprefixed_string_literals(filename):
u'ckan/controllers/revision.py',
u'ckan/controllers/storage.py',
u'ckan/controllers/tag.py',
u'ckan/controllers/template.py',
u'ckan/controllers/user.py',
u'ckan/controllers/util.py',
u'ckan/exceptions.py',
Expand Down
14 changes: 14 additions & 0 deletions ckan/tests/test_robots_txt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# encoding: utf-8

from nose.tools import assert_equal, ok_

import ckan.tests.helpers as helpers


class TestRobotsTxt(helpers.FunctionalTestBase):

def test_robots_txt(self):
app = self._get_test_app()
response = app.get(u'/robots.txt', status=200)
assert_equal(response.headers.get(u'Content-Type'), u'text/plain; charset=utf-8')
ok_(u'User-agent' in response)

0 comments on commit 9756909

Please sign in to comment.