Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better handling of multiple matching template wildcard paths #996

Closed
simonw opened this issue Oct 7, 2020 · 3 comments
Closed

Better handling of multiple matching template wildcard paths #996

simonw opened this issue Oct 7, 2020 · 3 comments

Comments

@simonw
Copy link
Owner

simonw commented Oct 7, 2020

I tried building this:

templates/pages/{topic}.html
templates/pages/{topic}/{slug}.html

And it didn't work - hits to /foo/bar which should have been rendered by the {slug}.html template were instead rendered by the top level {topic.html} template.

@simonw
Copy link
Owner Author

simonw commented Oct 7, 2020

Relevant code:

datasette/datasette/app.py

Lines 1030 to 1037 in 14982bd

if template is None:
# Try for a pages/blah/{name}.html template match
for regex, wildcard_template in self.page_routes:
match = regex.match(request.scope["path"])
if match is not None:
context.update(match.groupdict())
template = wildcard_template
break

datasette/datasette/app.py

Lines 951 to 954 in 14982bd

self.page_routes = [
(route_pattern_from_filepath(filepath[len("pages/") :]), filepath)
for filepath in pattern_templates
]

datasette/datasette/app.py

Lines 1197 to 1207 in 14982bd

def route_pattern_from_filepath(filepath):
# Drop the ".html" suffix
if filepath.endswith(".html"):
filepath = filepath[: -len(".html")]
re_bits = ["/"]
for bit in _curly_re.split(filepath):
if _curly_re.match(bit):
re_bits.append("(?P<{}>[^/]*)".format(bit[1:-1]))
else:
re_bits.append(re.escape(bit))
return re.compile("".join(re_bits))

@simonw
Copy link
Owner Author

simonw commented Oct 7, 2020

This line was meant to handle this case, by only matching non-/ characters. Looks like it did not have the desired effect:

re_bits.append("(?P<{}>[^/]*)".format(bit[1:-1]))

Maybe because the finished regex doesn't include ^ and $ anchors?

@simonw
Copy link
Owner Author

simonw commented Oct 7, 2020

One option: compare the length of the matches and pick the shortest one.

@simonw simonw closed this as completed in 5070425 Oct 7, 2020
@simonw simonw added this to the Datasette 0.50 milestone Oct 8, 2020
simonw added a commit that referenced this issue Oct 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant