feat: add support for pagination
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
from lektor.db import Record # isinstance
|
||||
from lektor.utils import build_url
|
||||
from typing import TYPE_CHECKING, Dict, List, Tuple, Optional, Iterable
|
||||
from typing import TYPE_CHECKING, Dict, List, NamedTuple, Optional, Iterable
|
||||
from .util import build_url
|
||||
from .vobj import VPATH, GroupBySource
|
||||
if TYPE_CHECKING:
|
||||
from lektor.environment import Environment
|
||||
@@ -8,6 +8,21 @@ if TYPE_CHECKING:
|
||||
from .config import Config
|
||||
|
||||
|
||||
class ResolverEntry(NamedTuple):
|
||||
slug: str
|
||||
group: str
|
||||
config: 'Config'
|
||||
page: Optional[int]
|
||||
|
||||
def equals(
|
||||
self, path: str, attribute: str, group: str, page: Optional[int]
|
||||
) -> bool:
|
||||
return self.slug == group \
|
||||
and self.config.key == attribute \
|
||||
and self.config.root == path \
|
||||
and self.page == page
|
||||
|
||||
|
||||
class Resolver:
|
||||
'''
|
||||
Resolve virtual paths and urls ending in /.
|
||||
@@ -15,7 +30,7 @@ class Resolver:
|
||||
'''
|
||||
|
||||
def __init__(self, env: 'Environment') -> None:
|
||||
self._data = {} # type: Dict[str, Tuple[str, str, Config]]
|
||||
self._data = {} # type: Dict[str, ResolverEntry]
|
||||
env.urlresolver(self.resolve_server_path)
|
||||
env.virtualpathresolver(VPATH.lstrip('@'))(self.resolve_virtual_path)
|
||||
|
||||
@@ -34,7 +49,9 @@ class Resolver:
|
||||
def add(self, vobj: GroupBySource) -> None:
|
||||
''' Track new virtual object (only if slug is set). '''
|
||||
if vobj.slug:
|
||||
self._data[vobj.url_path] = (vobj.key, vobj.group, vobj.config)
|
||||
# page_num = 1 overwrites page_num = None -> same url_path()
|
||||
self._data[vobj.url_path] = ResolverEntry(
|
||||
vobj.key, vobj.group, vobj.config, vobj.page_num)
|
||||
|
||||
# ------------
|
||||
# Resolver
|
||||
@@ -46,7 +63,8 @@ class Resolver:
|
||||
if isinstance(node, Record):
|
||||
rv = self._data.get(build_url([node.url_path] + pieces))
|
||||
if rv:
|
||||
return GroupBySource(node, rv[0]).finalize(rv[2], rv[1])
|
||||
return GroupBySource(
|
||||
node, rv.slug, rv.page).finalize(rv.config, rv.group)
|
||||
return None
|
||||
|
||||
def resolve_virtual_path(self, node: 'SourceObject', pieces: List[str]) \
|
||||
@@ -54,8 +72,15 @@ class Resolver:
|
||||
''' Admin UI only: Prevent server error and null-redirect. '''
|
||||
if isinstance(node, Record) and len(pieces) >= 2:
|
||||
path = node['_path'] # type: str
|
||||
attr, grp, *_ = pieces
|
||||
for slug, group, conf in self._data.values():
|
||||
if attr == conf.key and slug == grp and path == conf.root:
|
||||
return GroupBySource(node, slug).finalize(conf, group)
|
||||
attr, grp, *optional_page = pieces
|
||||
page = None
|
||||
if optional_page:
|
||||
try:
|
||||
page = int(optional_page[0])
|
||||
except ValueError:
|
||||
pass
|
||||
for rv in self._data.values():
|
||||
if rv.equals(path, attr, grp, page):
|
||||
return GroupBySource(
|
||||
node, rv.slug, rv.page).finalize(rv.config, rv.group)
|
||||
return None
|
||||
|
||||
Reference in New Issue
Block a user