Hi,
I’m trying to understand the Routing module of the anvil-extras, and I have a couple of foundational doubts.
I apologize for the lenght of the post, but these are fundamental concepts to understand in order to use the Routing module correctly.
First, the things I believe I’ve understood:
-
The app is a single page app.
-
The url is not going to change.The hash is used internally to determine the navigation (where to go)
-
The url can be just the url with an empty hash, it can have a hash (which indicates the Form/Page to which to navigate), and also can have parameters in the form of a key/value pair dictionary ().
-
And finally you can pass a parameter as part of the url and specify a pattern and this will define a dynamic variable.
-
There is a template form, which acts as a container of the rest of the application forms. This template has just a header, navigation bar, and a content panel (in which you’ll place the other forms once called, substituting the previous content)
-
There could be several templates, and all of them must be imported in the starting module or form of the application in order to be candidates.
Now comes mi first doubt:
How does the Routing know which is the template form to load?
I’ve seen 2 applications in which the starting form/module ends with:
routing.launch()
And they both load the correct template, and then the Home form (which haven’t been set anywhere I could see). Neither of them are called explicitly.
So,
- It is just as simple as, it is going to load “the first form you import in the starting module” and has a special decorator (as you will see in the examples I pasted below), and then, to load the Home form it will automatically search for a form with a decorator that matches the current url_hash, which at this point is blank?
- Or the order is not relevant, and it is just the decorator’s content?
I’ve taken these examples from two different applications, and they all seem to work on that premise.
These are the contents of the starting module/form in the application tree:
@routing.main_router
class MainForm(MainFormTemplate):
or
@routing.default_template
class RouterPublic(RouterPublicTemplate):
And in both cases there is a Home form with a decorator like this:
@routing.route(‘home’, title=‘Home | RoutingExample’) #multiple decorators allowed
@routing.route(‘’, title=‘Home | RoutingExample’)
(I assume the first one is for using somewhere else in the application, and the second the one that takes by default for matching the hash when routing.launch() is executed)
Second doubt:
In case I have several 1st level templates is it correct to say that for selecting which one will load first I need to do something like this:
routing.set_hash_url(‘the first parameter of the @routing.routedecorator of the form I want to load first’) and then: routing.launch()
For example:
routing.set_url_hash(“login”, replace_current_url=True), in which case the first form called will be the one that has @routing.route(‘login’) preceding the Class of the form.or
Having several forms with a blank first parameter, but conditions that evaluate to True or False and determine if the form will be loaded. Like this:
from … import Globals
@routing.template(path=“admin”, priority=1, condition=lambda: Globals.admin is not None)
class AdminRouterForm(AdminRouterTemplate):or
In case all the Forms have blank path and no condition, the chosen will be the one with the highest priority?
In this case, in which order are the forms evaluated?
I assume that there couldn’t be more than one template with the same path and condition. I’m I right? (because they will both match to be )
Third doubt
How do you achieve the actual navigation?
If it is explicit in the code you just write:
routing.set_url_hash(‘article?id=’, load_from_cache=False)
and this will make the app navigate to the article Form?
And in case you are going to navigate based on a click event, you can use a generic click event for all the links in the Form, like this:
def nav_link_click(self, **event_args):
“”“This method is called when a navigation link is clicked”“”
url_hash = event_args[‘sender’].tag.url_hash
routing.set_url_hash(url_hash)
Here, I assume that there is a sender argument that is passed to the function and that contains the hash of the Form you want to navigate to.
This should have been set before with something like :
self.blog_posts_link.tag.url_hash = ‘blog-posts’
self.articles_link.tag.url_hash = ‘articles’
But I’m not really sure if this sender argument is something standard or not? Where does the sender argument come from?**
Or else you can put the routing.set_url_hash(url_hash) in the click event of every button or link you want to use to navigate, and hard code the usr_hash in each of the calls.
Have I got it right so far? In case I haven’t, could you please correct me?
Thank you very much!
Warm regards
Ricardo