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

Handle Variables in the URL #61

Merged
merged 23 commits into from
Jan 6, 2022
Merged

Conversation

AnnMarieW
Copy link
Collaborator

@AnnMarieW AnnMarieW commented Dec 7, 2021

Closes #45

This is a new feature for handing variables in the URL.

Creates a new parameter path_template in dash.page_registry

  • path_template:
    Add variables to a URL by marking sections with <variable_name>. The layout function
    then receives the <variable_name> as a keyword argument.
    e.g. path_template= "/asset/<asset_id>"
    path = "/assets/a100"
    layout will receive {"asset_id":"a100"}

If no path is supplied when calling dash.register_page() then it will be inferred from the path_template. Variables will default to "none".
e.g. "/asset/<asset_id>" => "/asset/none"

@AnnMarieW AnnMarieW changed the title Path variables Handle Variables in the URL Dec 7, 2021
if template_segments[i].startswith("<"):
# removes the "<" ">" around the variable key
variable_key = template_segments[i][1:-1]
path_segments[i] = None if path_segments[i] == "None" else path_segments[i]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This "None" -> None conversion worries me - what if you really did want to pass "None" as the parameter? Can we just leave it as "None"? I know up above we use "None" in the path when registering the page but I'm not sure this is a good idea either - for example, how is that going to work in the title, description, and image?

path_to_title = {
page["path"]: page["title"] for page in dash.page_registry.values()
}
path_to_description = {
page["path"]: page["description"] for page in dash.page_registry.values()
}
path_to_image = {
page["path"]: page["image"] for page in dash.page_registry.values()
}

I suspect the better way to handle this will be to take the path-to-layout finder and turn it into a path-to-page finder, then use that both here and in interpolate_index

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, I could imagine users wanting title, description, and image to each potentially be a function of the path variables... But for now we should just ensure they work correctly as constant values for each registered page.

Copy link
Collaborator Author

@AnnMarieW AnnMarieW Dec 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dropped the "None" => None conversion.

Copy link
Collaborator Author

@AnnMarieW AnnMarieW Dec 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, I could imagine users wanting title, description, and image to each potentially be a function of the path variables... But for now we should just ensure they work correctly as constant values for each registered page.

I think one way to do this is to create a dash.path_registry. Initially it could be created from the data in dash.page_registry. Then people could add other path data to it. However, is this worthwhile? Would this be a popular feature?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect the better way to handle this will be to take the path-to-layout finder and turn it into a path-to-page finder, then use that both here and in interpolate_index.

Good suggestion - I added a path_to_page function in this commit

@AnnMarieW AnnMarieW mentioned this pull request Dec 20, 2021
@AnnMarieW
Copy link
Collaborator Author

AnnMarieW commented Dec 20, 2021

Hey @alexcjohnson This is ready for another review. I moved tests to #66 so it doesn't hold up things that are finished, such as:

  • Fixed the "None" => None conversion.

  • Fixed it so that the page title and meta tags are correct with path variables

  • The assets/ and pages/ folders are now optional. If pages/ can't be found, it no longer raises an Exception, but it does print a message. The message could help debug if not finding pages/ is unintentional.

  • There is now a check that the paths are unique for each module in dash.page_registry. This should help prevent bugs.

  • There is now a check that pathnames start with a /. Previously the / was missing in some cases when the layout was added directly to dash.register_page()

  • Updated docs and included new info on path variables and query strings

Copy link
Collaborator

@alexcjohnson alexcjohnson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Stricter pattern checking https://github.com/plotly/dash-labs/pull/61/files#r778960479 would be nice but we could do that later as well.
💃

def _validate_template(template):
template_segments = template.split("/")
for s in template_segments:
if ("<" or ">") in s and not (s.startswith("<") and s.endswith(">")):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

("<" or ">") in s -> I think you mean ("<" in s or ">" in s)

Also need to check that < and > are NOT in s[1: -1]

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also need to check that < and > are NOT in s[1: -1]

Just to summarize our discussion: Since the variables are passed to the layout in a dict as strings, there should not be a restriction about including < or > . However, the most common use case is that the keys are Python variables, so now there is a warning message if the variable is not a valid Python variable name.

added warning message if path variables are not valid Python variable names
Copy link
Collaborator

@alexcjohnson alexcjohnson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright I think we have a winner! 💃

@AnnMarieW AnnMarieW merged commit b8d0a3f into plotly:main Jan 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Multi Page Apps [feature request]: variables in the path
3 participants