123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- # -*- coding: utf-8 -*-
- """
- This plugin enables a kind of permalink which can be used to refer to a piece
- of content which is resistant to the file being moved or renamed.
- """
- import itertools
- import logging
- import os
- import os.path
- from pelican import signals
- from pelican.generators import Generator
- from pelican.utils import clean_output_dir
- from pelican.utils import mkdir_p
- logger = logging.getLogger(__name__)
- def article_url(content):
- '''
- Get the URL for an item of content
- '''
- return '{content.settings[SITEURL]}/{content.url}'.format(
- content=content).encode('utf-8')
- REDIRECT_STRING = '''
- <!DOCTYPE HTML>
- <html lang="en-US">
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="refresh" content="0;url={url}">
- <script type="text/javascript">
- window.location.href = "{url}"
- </script>
- <title>Page Redirection to {title}</title>
- </head>
- <body>
- If you are not redirected automatically, follow the
- <a href='{url}'>link to {title}</a>
- </body>
- </html>
- '''
- class PermalinkGenerator(Generator):
- '''
- Generate a redirect page for every item of content with a
- permalink_id metadata
- '''
- def generate_context(self):
- '''
- Setup context
- '''
- self.permalink_output_path = os.path.join(
- self.output_path, self.settings['PERMALINK_PATH'])
- self.permalink_id_metadata_key = (
- self.settings['PERMALINK_ID_METADATA_KEY'])
- def generate_output(self, writer=None):
- '''
- Generate redirect files
- '''
- logger.info(
- 'Generating permalink files in %r', self.permalink_output_path)
- clean_output_dir(self.permalink_output_path, [])
- mkdir_p(self.permalink_output_path)
- for content in itertools.chain(
- self.context['articles'], self.context['pages']):
- for permalink_id in content.get_permalink_ids_iter():
- permalink_path = os.path.join(
- self.permalink_output_path, permalink_id) + '.html'
- redirect_string = REDIRECT_STRING.format(
- url=article_url(content),
- title=content.title)
- open(permalink_path, 'w').write(redirect_string)
- def get_permalink_ids_iter(self):
- '''
- Method to get permalink ids from content. To be bound to the class last
- thing.
- '''
- permalink_id_key = self.settings['PERMALINK_ID_METADATA_KEY']
- permalink_ids = self.metadata.get(permalink_id_key, '')
- for permalink_id in permalink_ids.split(','):
- if permalink_id:
- yield permalink_id.strip()
- def get_permalink_ids(self):
- '''
- Method to get permalink ids from content. To be bound to the class last
- thing.
- '''
- return list(self.get_permalink_ids_iter())
- def get_permalink_path(self):
- """Get just path component of permalink."""
- try:
- first_permalink_id = next(self.get_permalink_ids_iter())
- except StopIteration:
- return None
- return '/{settings[PERMALINK_PATH]}/{first_permalink}'.format(
- settings=self.settings, first_permalink=first_permalink_id)
- def get_permalink_url(self):
- '''
- Get a permalink URL
- '''
- return "/".join((self.settings['SITEURL'], self.get_permalink_path()))
- PERMALINK_METHODS = (
- get_permalink_ids_iter,
- get_permalink_ids,
- get_permalink_url,
- get_permalink_path,
- )
- def add_permalink_methods(content_inst):
- '''
- Add permalink methods to object
- '''
- for permalink_method in PERMALINK_METHODS:
- setattr(
- content_inst,
- permalink_method.__name__,
- permalink_method.__get__(content_inst, content_inst.__class__))
- def add_permalink_option_defaults(pelicon_inst):
- '''
- Add perlican defaults
- '''
- pelicon_inst.settings.setdefault('PERMALINK_PATH', 'permalinks')
- pelicon_inst.settings.setdefault(
- 'PERMALINK_ID_METADATA_KEY', 'permalink_id')
- def get_generators(_pelican_object):
- return PermalinkGenerator
- def register():
- signals.get_generators.connect(get_generators)
- signals.content_object_init.connect(add_permalink_methods)
- signals.initialized.connect(add_permalink_option_defaults)
|