From a39787c1a2c32dc936dba9ace73a0fcef0b73098 Mon Sep 17 00:00:00 2001 From: Kyle Fuller Date: Fri, 23 Dec 2011 22:01:32 +0000 Subject: [PATCH] Add settings to change the URL's and SAVE_AS paths Example usage: * ARTICLE_URL = 'posts/{date:%Y}/{date:%b}/{date:%d}/{slug}/' * ARTICLE_SAVE_AS = 'posts/{date:%Y}/{date:%b}/{date:%d}/{slug}/index.html' This removes CLEAN_URLS and ARTICLE_PERMALINK_STRUCTURE because these new settings can produce the same result. --- docs/settings.rst | 54 +++++++++++++++++++++++-------------- pelican/contents.py | 62 +++++++++++++++++++++++++++---------------- pelican/generators.py | 17 +----------- pelican/settings.py | 9 ++++++- 4 files changed, 82 insertions(+), 60 deletions(-) diff --git a/docs/settings.rst b/docs/settings.rst index 2d40d4ec..b93c8c11 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -24,12 +24,7 @@ Basic settings ================================================ ===================================================== Setting name (default value) What does it do? ================================================ ===================================================== -`ARTICLE_PERMALINK_STRUCTURE` (``''``) Empty by default. Enables some customization of URL - structure (see below for more detail). `AUTHOR` Default author (put your name) -`CLEAN_URLS` (``False``) If set to `True`, the URLs will not be suffixed by - `.html`, so you will have to setup URL rewriting on - your web server. `DATE_FORMATS` (``{}``) If you do manage multiple languages, you can set the date formatting here. See "Date format and locales" section below for details. @@ -79,16 +74,14 @@ Setting name (default value) What does it do? .. [#] Default is the system locale. -Article permalink structure ---------------------------- +URL Settings +------------ -This setting allows you to output your articles sorted by date, provided that -you specify a format as specified below. This format follows the Python -``datetime`` directives: - -* %Y: Year with century as a decimal number. -* %m: Month as a decimal number [01,12]. -* %d: Day of the month as a decimal number [01,31]. +You can customize the URL's and locations where files will be saved. The URL's and +SAVE_AS variables use python's format strings. These variables allow you to place +your articles in a location such as '{slug}/index.html' and link to then as +'{slug}' for clean urls. These settings give you the flexibility to place your +articles and pages anywhere you want. Note: If you specify a datetime directive, it will be substituted using the input files' date metadata attribute. If the date is not specified for a @@ -99,15 +92,36 @@ information. Also, you can use other file metadata attributes as well: -* category: '%(category)s' -* author: '%(author)s' -* tags: '%(tags)s' -* date: '%(date)s' +* slug +* date +* lang +* author +* category Example usage: -* '/%Y/%m/' will render something like '/2011/07/sample-post.html'. -* '/%Y/%(category)s/' will render something like '/2011/life/sample-post.html'. +* ARTICLE_URL = 'posts/{date:%Y}/{date:%b}/{date:%d}/{slug}/' +* ARTICLE_SAVE_AS = 'posts/{date:%Y}/{date:%b}/{date:%d}/{slug}/index.html' + +This would save your articles in something like '/posts/2011/Aug/07/sample-post/index.html', +and the URL to this would be '/posts/2011/Aug/07/sample-post/'. + +================================================ ===================================================== +Setting name (default value) what does it do? +================================================ ===================================================== +`ARTICLE_URL` ('{slug}.html') The URL to refer to an ARTICLE. +`ARTICLE_SAVE_AS` ('{slug}.html') The place where we will save an article. +`ARTICLE_LANG_URL` ('{slug}-{lang}.html') The URL to refer to an ARTICLE which doesn't use the + default language. +`ARTICLE_LANG_SAVE_AS` ('{slug}-{lang}.html' The place where we will save an article which + doesn't use the default language. +`PAGE_URL` ('pages/{slug}.html') The URL we will use to link to a page. +`PAGE_SAVE_AS` ('pages/{slug}.html') The location we will save the page. +`PAGE_LANG_URL` ('pages/{slug}-{lang}.html') The URL we will use to link to a page which doesn't + use the default language. +`PAGE_LANG_SAVE_AS` ('pages/{slug}-{lang}.html') The location we will save the page which doesn't + use the default language. +================================================ ===================================================== Timezone -------- diff --git a/pelican/contents.py b/pelican/contents.py index 8cd36186..bc42d41e 100644 --- a/pelican/contents.py +++ b/pelican/contents.py @@ -24,6 +24,7 @@ class Page(object): if not settings: settings = _DEFAULT_CONFIG + self.settings = settings self._content = content self.translations = [] @@ -55,29 +56,6 @@ class Page(object): if not hasattr(self, 'slug') and hasattr(self, 'title'): self.slug = slugify(self.title) - # create save_as from the slug (+lang) - if not hasattr(self, 'save_as') and hasattr(self, 'slug'): - if self.in_default_lang: - if settings.get('CLEAN_URLS', False): - self.save_as = '%s/index.html' % self.slug - else: - self.save_as = '%s.html' % self.slug - - clean_url = '%s/' % self.slug - else: - if settings.get('CLEAN_URLS', False): - self.save_as = '%s-%s/index.html' % (self.slug, self.lang) - else: - self.save_as = '%s-%s.html' % (self.slug, self.lang) - - clean_url = '%s-%s/' % (self.slug, self.lang) - - # change the save_as regarding the settings - if settings.get('CLEAN_URLS', False): - self.url = clean_url - elif hasattr(self, 'save_as'): - self.url = self.save_as - if filename: self.filename = filename @@ -115,6 +93,30 @@ class Page(object): if not hasattr(self, prop): raise NameError(prop) + @property + def url_format(self): + return { + 'slug': getattr(self, 'slug', ''), + 'lang': getattr(self, 'lang', 'en'), + 'date': getattr(self, 'date', datetime.now()), + 'author': self.author, + 'category': getattr(self, 'category', 'misc'), + } + + @property + def url(self): + if self.in_default_lang: + return self.settings.get('PAGE_URL', 'pages/{slug}.html').format(**self.url_format) + + return self.settings.get('PAGE_LANG_URL', 'pages/{slug}-{lang}.html').format(**self.url_format) + + @property + def save_as(self): + if self.in_default_lang: + return self.settings.get('PAGE_SAVE_AS', 'pages/{slug}.html').format(**self.url_format) + + return self.settings.get('PAGE_LANG_SAVE_AS', 'pages/{slug}-{lang}.html').format(**self.url_format) + @property def content(self): if hasattr(self, "_get_content"): @@ -138,6 +140,20 @@ class Page(object): class Article(Page): mandatory_properties = ('title', 'date', 'category') + @property + def url(self): + if self.in_default_lang: + return self.settings.get('ARTICLE_URL', '{slug}.html').format(**self.url_format) + + return self.settings.get('ARTICLE_LANG_URL', '{slug}-{lang}.html').format(**self.url_format) + + @property + def save_as(self): + if self.in_default_lang: + return self.settings.get('ARTICLE_SAVE_AS', '{slug}.html').format(**self.url_format) + + return self.settings.get('ARTICLE_LANG_SAVE_AS', '{slug}-{lang}.html').format(**self.url_format) + class Quote(Page): base_properties = ('author', 'date') diff --git a/pelican/generators.py b/pelican/generators.py index d9d584a4..7ad3d276 100644 --- a/pelican/generators.py +++ b/pelican/generators.py @@ -239,21 +239,6 @@ class ArticlesGenerator(Generator): if not is_valid_content(article, f): continue - add_to_url = u'' - if 'ARTICLE_PERMALINK_STRUCTURE' in self.settings: - article_permalink_structure = self.settings['ARTICLE_PERMALINK_STRUCTURE'] - article_permalink_structure = article_permalink_structure.lstrip('/').replace('%(', "%%(") - - # try to substitute any python datetime directive - add_to_url = article.date.strftime(article_permalink_structure) - # try to substitute any article metadata in rest file - add_to_url = add_to_url % article.__dict__ - add_to_url = [slugify(i) for i in add_to_url.split('/')] - add_to_url = os.path.join(*add_to_url) - - article.url = urlparse.urljoin(add_to_url, article.url) - article.save_as = urlparse.urljoin(add_to_url, article.save_as) - if article.status == "published": if hasattr(article, 'tags'): for tag in article.tags: @@ -348,7 +333,7 @@ class PagesGenerator(Generator): def generate_output(self, writer): for page in chain(self.translations, self.pages): - writer.write_file('pages/%s' % page.save_as, self.get_template('page'), + writer.write_file(page.save_as, self.get_template('page'), self.context, page=page, relative_urls = self.settings.get('RELATIVE_URLS')) diff --git a/pelican/settings.py b/pelican/settings.py index cf6b23e5..ec6ec483 100644 --- a/pelican/settings.py +++ b/pelican/settings.py @@ -26,7 +26,14 @@ _DEFAULT_CONFIG = {'PATH': None, 'REVERSE_ARCHIVE_ORDER': False, 'REVERSE_CATEGORY_ORDER': False, 'DELETE_OUTPUT_DIRECTORY': False, - 'CLEAN_URLS': False, # use /blah/ instead /blah.html in urls + 'ARTICLE_URL': '{slug}.html', + 'ARTICLE_SAVE_AS': '{slug}.html', + 'ARTICLE_LANG_URL': '{slug}-{lang}.html', + 'ARTICLE_LANG_SAVE_AS': '{slug}-{lang}.html', + 'PAGE_URL': 'pages/{slug}.html', + 'PAGE_SAVE_AS': 'pages/{slug}.html', + 'PAGE_LANG_URL': 'pages/{slug}-{lang}.html', + 'PAGE_LANG_SAVE_AS': 'pages/{slug}-{lang}.html', 'RELATIVE_URLS': True, 'DEFAULT_LANG': 'en', 'TAG_CLOUD_STEPS': 4,