mirror of
https://github.com/getpelican/pelican.git
synced 2025-10-15 20:28:56 +02:00
contents: Convert StaticContent to Static, a Page subclass
Static needs a lot of the same handling as other pages, so make it a subclass of Page. The rename from StaticContent to Static makes for cleaner configuration settings (STATIC_URL instead of STATICCONTENT_URL). All currently generated Static instances override the save_as attribute explicitly on initialization, but it isn't hard to imagine wanting to adjust STATIC file output based on metadata (e.g. extracted from their source filename). With this union, the framework for manipulating URLs and filenames is shared between all source file types.
This commit is contained in:
parent
9cbf5c0cbe
commit
49bf80ec39
3 changed files with 109 additions and 27 deletions
|
|
@ -85,8 +85,7 @@ class Content(object):
|
||||||
if not hasattr(self, 'slug') and hasattr(self, 'title'):
|
if not hasattr(self, 'slug') and hasattr(self, 'title'):
|
||||||
self.slug = slugify(self.title)
|
self.slug = slugify(self.title)
|
||||||
|
|
||||||
if source_path:
|
self.source_path = source_path
|
||||||
self.source_path = source_path
|
|
||||||
|
|
||||||
# manage the date format
|
# manage the date format
|
||||||
if not hasattr(self, 'date_format'):
|
if not hasattr(self, 'date_format'):
|
||||||
|
|
@ -119,6 +118,14 @@ class Content(object):
|
||||||
|
|
||||||
signals.content_object_init.send(self)
|
signals.content_object_init.send(self)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
if self.source_path is None:
|
||||||
|
return repr(self)
|
||||||
|
elif six.PY3:
|
||||||
|
return self.source_path or repr(self)
|
||||||
|
else:
|
||||||
|
return str(self.source_path.encode('utf-8', 'replace'))
|
||||||
|
|
||||||
def check_properties(self):
|
def check_properties(self):
|
||||||
"""Test mandatory properties are set."""
|
"""Test mandatory properties are set."""
|
||||||
for prop in self.mandatory_properties:
|
for prop in self.mandatory_properties:
|
||||||
|
|
@ -130,6 +137,7 @@ class Content(object):
|
||||||
"""Returns the URL, formatted with the proper values"""
|
"""Returns the URL, formatted with the proper values"""
|
||||||
metadata = copy.copy(self.metadata)
|
metadata = copy.copy(self.metadata)
|
||||||
metadata.update({
|
metadata.update({
|
||||||
|
'path': self.metadata.get('path', self.get_relative_source_path()),
|
||||||
'slug': getattr(self, 'slug', ''),
|
'slug': getattr(self, 'slug', ''),
|
||||||
'lang': getattr(self, 'lang', 'en'),
|
'lang': getattr(self, 'lang', 'en'),
|
||||||
'date': getattr(self, 'date', datetime.now()),
|
'date': getattr(self, 'date', datetime.now()),
|
||||||
|
|
@ -250,6 +258,8 @@ class Content(object):
|
||||||
"""
|
"""
|
||||||
if not source_path:
|
if not source_path:
|
||||||
source_path = self.source_path
|
source_path = self.source_path
|
||||||
|
if source_path is None:
|
||||||
|
return None
|
||||||
|
|
||||||
return os.path.relpath(
|
return os.path.relpath(
|
||||||
os.path.abspath(os.path.join(self.settings['PATH'], source_path)),
|
os.path.abspath(os.path.join(self.settings['PATH'], source_path)),
|
||||||
|
|
@ -279,26 +289,88 @@ class Quote(Page):
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class StaticContent(object):
|
@functools.total_ordering
|
||||||
|
class URLWrapper(object):
|
||||||
|
def __init__(self, name, settings):
|
||||||
|
self.name = name
|
||||||
|
self.slug = slugify(self.name)
|
||||||
|
self.settings = settings
|
||||||
|
|
||||||
|
def as_dict(self):
|
||||||
|
return self.__dict__
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
return hash(self.name)
|
||||||
|
|
||||||
|
def _key(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
def _normalize_key(self, key):
|
||||||
|
return six.text_type(key)
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
return self._key() == self._normalize_key(other)
|
||||||
|
|
||||||
|
def __ne__(self, other):
|
||||||
|
return self._key() != self._normalize_key(other)
|
||||||
|
|
||||||
|
def __lt__(self, other):
|
||||||
|
return self._key() < self._normalize_key(other)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
def _from_settings(self, key, get_page_name=False):
|
||||||
|
"""Returns URL information as defined in settings.
|
||||||
|
|
||||||
|
When get_page_name=True returns URL without anything after {slug} e.g.
|
||||||
|
if in settings: CATEGORY_URL="cat/{slug}.html" this returns
|
||||||
|
"cat/{slug}" Useful for pagination.
|
||||||
|
|
||||||
|
"""
|
||||||
|
setting = "%s_%s" % (self.__class__.__name__.upper(), key)
|
||||||
|
value = self.settings[setting]
|
||||||
|
if not isinstance(value, six.string_types):
|
||||||
|
logger.warning('%s is set to %s' % (setting, value))
|
||||||
|
return value
|
||||||
|
else:
|
||||||
|
if get_page_name:
|
||||||
|
return os.path.splitext(value)[0].format(**self.as_dict())
|
||||||
|
else:
|
||||||
|
return value.format(**self.as_dict())
|
||||||
|
|
||||||
|
page_name = property(functools.partial(_from_settings, key='URL',
|
||||||
|
get_page_name=True))
|
||||||
|
url = property(functools.partial(_from_settings, key='URL'))
|
||||||
|
save_as = property(functools.partial(_from_settings, key='SAVE_AS'))
|
||||||
|
|
||||||
|
|
||||||
|
class Category(URLWrapper):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Tag(URLWrapper):
|
||||||
|
def __init__(self, name, *args, **kwargs):
|
||||||
|
super(Tag, self).__init__(name.strip(), *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class Author(URLWrapper):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@python_2_unicode_compatible
|
||||||
|
class Static(Page):
|
||||||
@deprecated_attribute(old='filepath', new='source_path', since=(3, 2, 0))
|
@deprecated_attribute(old='filepath', new='source_path', since=(3, 2, 0))
|
||||||
def filepath():
|
def filepath():
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def __init__(self, src, dst=None, settings=None):
|
@deprecated_attribute(old='src', new='source_path', since=(3, 2, 0))
|
||||||
if not settings:
|
def src():
|
||||||
settings = copy.deepcopy(_DEFAULT_CONFIG)
|
return None
|
||||||
self.src = src
|
|
||||||
self.url = dst or src
|
|
||||||
|
|
||||||
# On Windows, make sure we end up with Unix-like paths.
|
@deprecated_attribute(old='dst', new='save_as', since=(3, 2, 0))
|
||||||
if os.name == 'nt':
|
def dst():
|
||||||
self.url = self.url.replace('\\', '/')
|
return None
|
||||||
self.source_path = os.path.join(settings['PATH'], src)
|
|
||||||
self.save_as = os.path.join(settings['OUTPUT_PATH'], self.url)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.source_path
|
|
||||||
|
|
||||||
|
|
||||||
def is_valid_content(content, f):
|
def is_valid_content(content, f):
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ from jinja2 import (
|
||||||
)
|
)
|
||||||
|
|
||||||
from pelican.contents import (
|
from pelican.contents import (
|
||||||
Article, Page, Category, StaticContent, is_valid_content
|
Article, Page, Category, Static, is_valid_content
|
||||||
)
|
)
|
||||||
from pelican.readers import read_file
|
from pelican.readers import read_file
|
||||||
from pelican.utils import copy, process_translations, mkdir_p
|
from pelican.utils import copy, process_translations, mkdir_p
|
||||||
|
|
@ -122,8 +122,7 @@ class Generator(object):
|
||||||
return files
|
return files
|
||||||
|
|
||||||
def add_source_path(self, content):
|
def add_source_path(self, content):
|
||||||
location = os.path.relpath(os.path.abspath(content.source_path),
|
location = content.get_relative_source_path()
|
||||||
os.path.abspath(self.path))
|
|
||||||
self.context['filenames'][location] = content
|
self.context['filenames'][location] = content
|
||||||
|
|
||||||
def _update_context(self, items):
|
def _update_context(self, items):
|
||||||
|
|
@ -523,23 +522,32 @@ class StaticGenerator(Generator):
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
f_rel = f_rel.replace('\\', '/')
|
f_rel = f_rel.replace('\\', '/')
|
||||||
# TODO remove this hardcoded 'static' subdirectory
|
# TODO remove this hardcoded 'static' subdirectory
|
||||||
sc = StaticContent(f_rel, os.path.join('static', f_rel),
|
sc = Static(
|
||||||
settings=self.settings)
|
content=None,
|
||||||
|
metadata={'save_as': os.path.join('static', f_rel)},
|
||||||
|
settings=self.settings,
|
||||||
|
source_path=f_rel)
|
||||||
self.staticfiles.append(sc)
|
self.staticfiles.append(sc)
|
||||||
self.context['filenames'][f_rel] = sc
|
self.add_source_path(sc)
|
||||||
# same thing for FILES_TO_COPY
|
# same thing for FILES_TO_COPY
|
||||||
for src, dest in self.settings['FILES_TO_COPY']:
|
for src, dest in self.settings['FILES_TO_COPY']:
|
||||||
sc = StaticContent(src, dest, settings=self.settings)
|
sc = Static(
|
||||||
|
content=None,
|
||||||
|
metadata={'save_as': dest},
|
||||||
|
settings=self.settings,
|
||||||
|
source_path=src)
|
||||||
self.staticfiles.append(sc)
|
self.staticfiles.append(sc)
|
||||||
self.context['filenames'][src] = sc
|
self.add_source_path(sc)
|
||||||
|
|
||||||
def generate_output(self, writer):
|
def generate_output(self, writer):
|
||||||
self._copy_paths(self.settings['THEME_STATIC_PATHS'], self.theme,
|
self._copy_paths(self.settings['THEME_STATIC_PATHS'], self.theme,
|
||||||
'theme', self.output_path, '.')
|
'theme', self.output_path, '.')
|
||||||
# copy all StaticContent files
|
# copy all Static files
|
||||||
for sc in self.staticfiles:
|
for sc in self.staticfiles:
|
||||||
mkdir_p(os.path.dirname(sc.save_as))
|
source_path = os.path.join(self.path, sc.source_path)
|
||||||
shutil.copy(sc.source_path, sc.save_as)
|
save_as = os.path.join(self.output_path, sc.save_as)
|
||||||
|
mkdir_p(os.path.dirname(save_as))
|
||||||
|
shutil.copy(source_path, save_as)
|
||||||
logger.info('copying {} to {}'.format(sc.source_path, sc.save_as))
|
logger.info('copying {} to {}'.format(sc.source_path, sc.save_as))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,8 @@ _DEFAULT_CONFIG = {'PATH': '.',
|
||||||
'PAGE_SAVE_AS': 'pages/{slug}.html',
|
'PAGE_SAVE_AS': 'pages/{slug}.html',
|
||||||
'PAGE_LANG_URL': 'pages/{slug}-{lang}.html',
|
'PAGE_LANG_URL': 'pages/{slug}-{lang}.html',
|
||||||
'PAGE_LANG_SAVE_AS': 'pages/{slug}-{lang}.html',
|
'PAGE_LANG_SAVE_AS': 'pages/{slug}-{lang}.html',
|
||||||
|
'STATIC_URL': '{path}',
|
||||||
|
'STATIC_SAVE_AS': '{path}',
|
||||||
'CATEGORY_URL': 'category/{slug}.html',
|
'CATEGORY_URL': 'category/{slug}.html',
|
||||||
'CATEGORY_SAVE_AS': 'category/{slug}.html',
|
'CATEGORY_SAVE_AS': 'category/{slug}.html',
|
||||||
'TAG_URL': 'tag/{slug}.html',
|
'TAG_URL': 'tag/{slug}.html',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue