allow {key} in slug + allow sorting and hashing
This commit is contained in:
@@ -31,33 +31,35 @@ class GroupBySource(VirtualSourceObject):
|
|||||||
record: Record,
|
record: Record,
|
||||||
group: str,
|
group: str,
|
||||||
config: Config,
|
config: Config,
|
||||||
children: Optional[Dict[Record, List[object]]] = None,
|
children: Optional[Dict[Record, List[Any]]] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(record)
|
super().__init__(record)
|
||||||
self.key = config.slugify(group)
|
self.key = config.slugify(group)
|
||||||
self.group = group
|
self.group = group
|
||||||
self.config = config
|
self.config = config
|
||||||
# make sure children are on the same pad
|
|
||||||
self._children = {} # type: Dict[Record, List[object]]
|
|
||||||
for child, extras in (children or {}).items():
|
|
||||||
if child.pad != record.pad:
|
|
||||||
child = record.pad.get(child.path)
|
|
||||||
self._children[child] = extras
|
|
||||||
self._reverse_reference_records()
|
|
||||||
# evaluate slug Expression
|
# evaluate slug Expression
|
||||||
if '{key}' in config.slug:
|
if config.slug and '{key}' in config.slug:
|
||||||
self.slug = config.slug.replace('{key}', self.key)
|
self.slug = config.slug.replace('{key}', self.key)
|
||||||
else:
|
else:
|
||||||
self.slug = self._eval(config.slug, field='slug')
|
self.slug = self._eval(config.slug, field='slug')
|
||||||
assert self.slug != Ellipsis, 'invalid config: ' + config.slug
|
assert self.slug != Ellipsis, 'invalid config: ' + config.slug
|
||||||
if self.slug and self.slug.endswith('/index.html'):
|
if self.slug and self.slug.endswith('/index.html'):
|
||||||
self.slug = self.slug[:-10]
|
self.slug = self.slug[:-10]
|
||||||
|
# make sure children are on the same pad
|
||||||
|
self._children = {} # type: Dict[Record, List[Any]]
|
||||||
|
for child, extras in (children or {}).items():
|
||||||
|
if child.pad != record.pad:
|
||||||
|
child = record.pad.get(child.path)
|
||||||
|
self._children[child] = extras
|
||||||
|
self._reverse_reference_records()
|
||||||
# extra fields
|
# extra fields
|
||||||
for attr, expr in config.fields.items():
|
for attr, expr in config.fields.items():
|
||||||
setattr(self, attr, self._eval(expr, field='fields.' + attr))
|
setattr(self, attr, self._eval(expr, field='fields.' + attr))
|
||||||
|
|
||||||
def _eval(self, value: str, *, field: str) -> Any:
|
def _eval(self, value: Any, *, field: str) -> Any:
|
||||||
''' Internal only: evaluates Lektor config file field expression. '''
|
''' Internal only: evaluates Lektor config file field expression. '''
|
||||||
|
if not isinstance(value, str):
|
||||||
|
return value
|
||||||
pad = self.record.pad
|
pad = self.record.pad
|
||||||
alt = self.record.alt
|
alt = self.record.alt
|
||||||
try:
|
try:
|
||||||
@@ -80,14 +82,6 @@ class GroupBySource(VirtualSourceObject):
|
|||||||
# Actual path to resource as seen by the browser
|
# Actual path to resource as seen by the browser
|
||||||
return build_url([self.record.path, self.slug]) # slug can be None!
|
return build_url([self.record.path, self.slug]) # slug can be None!
|
||||||
|
|
||||||
def __getitem__(self, name: str) -> object:
|
|
||||||
# needed for preview in admin UI
|
|
||||||
if name == '_path':
|
|
||||||
return self.path
|
|
||||||
elif name == '_alt':
|
|
||||||
return self.record.alt
|
|
||||||
return None
|
|
||||||
|
|
||||||
def iter_source_filenames(self) -> Iterator[str]:
|
def iter_source_filenames(self) -> Iterator[str]:
|
||||||
''' Enumerate all dependencies '''
|
''' Enumerate all dependencies '''
|
||||||
if self.config.dependencies:
|
if self.config.dependencies:
|
||||||
@@ -100,7 +94,8 @@ class GroupBySource(VirtualSourceObject):
|
|||||||
# -----------------------
|
# -----------------------
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def children(self) -> Dict[Record, List[object]]:
|
def children(self) -> Dict[Record, List[Any]]:
|
||||||
|
''' Returns dict with page record key and (optional) extra value. '''
|
||||||
return self._children
|
return self._children
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -111,17 +106,36 @@ class GroupBySource(VirtualSourceObject):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def first_extra(self) -> Optional[object]:
|
def first_extra(self) -> Optional[Any]:
|
||||||
''' Returns first additional / extra info object of first page. '''
|
''' Returns first additional / extra info object of first page. '''
|
||||||
if not self._children:
|
if not self._children:
|
||||||
return None
|
return None
|
||||||
val = iter(self._children.values()).__next__()
|
val = iter(self._children.values()).__next__()
|
||||||
return val[0] if val else None
|
return val[0] if val else None
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
# Used for virtual path resolver and |sort(attribute="x") filter
|
||||||
|
if key in ('_path', '_alt'):
|
||||||
|
return getattr(self, key[1:])
|
||||||
|
if hasattr(self, key):
|
||||||
|
return getattr(self, key)
|
||||||
|
return None
|
||||||
|
|
||||||
def __lt__(self, other: 'GroupBySource') -> bool:
|
def __lt__(self, other: 'GroupBySource') -> bool:
|
||||||
''' The "group" attribute is used for sorting. '''
|
# Used for |sort filter ("group" is the provided original string)
|
||||||
return self.group < other.group
|
return self.group < other.group
|
||||||
|
|
||||||
|
def __eq__(self, other: object) -> bool:
|
||||||
|
# Used for |unique filter
|
||||||
|
if self is other:
|
||||||
|
return True
|
||||||
|
return isinstance(other, GroupBySource) and \
|
||||||
|
self.path == other.path and self.slug == other.slug
|
||||||
|
|
||||||
|
def __hash__(self) -> int:
|
||||||
|
# Used for hashing in set and dict
|
||||||
|
return hash((self.path, self.slug))
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return '<GroupBySource path="{}" children={}>'.format(
|
return '<GroupBySource path="{}" children={}>'.format(
|
||||||
self.path, len(self._children))
|
self.path, len(self._children))
|
||||||
|
|||||||
Reference in New Issue
Block a user