toddler.router
Routing in toddler is focused on linking components in component tree. This component tree is built by use-link hook or even better with wrap-link function.
I.E.
(defnc HelloWorld
{:wrap [(wrap-link
:toddler.router/ROOT
[{:id ::component-1
:name "testing1"}
{:id ::component-2
:name "testing2"}])]}
[]
($ World {:message "Hey there!"}))
Other hooks and functions in this namespace are here to help you:
- Navigate component tree by sending user to component URL or adding parameters in browser URL that will have effect on your application state
- Check if component is rendered by comparing path in routing tree to current browser location.
- Check if user has rights to access some route by protecting routes with :roles and :permissions
Ensure that user is redirected to landing page that is ment for him by using LandingPage component
*component-tree*
dynamic
Component tree cache. This is where toddler router adds components and looks for routing information.
Authorized
Wrapper component that will render children if user is authorized to access component with :id in props
clj->query
(clj->query data)
Function will turn clojure map into URLSearchParams
component->location
(component->location tree id)
For given component tree and component id function will return zipper location if id is found.
component-path
(component-path tree id)
Function will walk component tree to find component with id and when found will return all URL for that component.
component-tree-zipper
(component-tree-zipper root)
Function returns routing tree zipper
LandingPage
Component that is active when routing location is at :url from props. If so, then this component will look for :landing priority
in *component-tree*
and sort all found components by priority.
Component with highest priority is chosen and its URL is computed and user agent is redirected to that URL.
Link
Component will link parrent with id and children with routing info. Check out use-link hook to see how to structure children routing info.
location->map
(location->map location)
For given js/Location object will return hashmap that contains: :pathname :hash :origin :search
maybe-add-base
(maybe-add-base base url)
For given base and url will add base prefix if it exists to url. If base is nil than URL is returned
maybe-remove-base
(maybe-remove-base base url)
For given base and url will return URL without base. If base is nil function will return URL immediately
on-path?
(on-path? tree path id)
For given path and component id function will get component path and check if given path starts with component path.
If it does, than component is on path (true)
Protect
Component will set protection contexts. Contexts like -permissions-, -roles- and -super-.
Use it as high as possible in your rendered app.
Provider
Component will wrap js/window history functionalities for pushing poping, replacing history as well as navigation functions like back, forward and go.
This functions are provided in -navigation- context.
Another context is provided, and that is -router- context that is holds information about current location and component tree.
dispatch function to interact with -router- reducer is available through -dispatch- context.
base - is base that this Provider should include in its context. I.E. if your application is served under /some/url than you should specify that as base URL
($ Provider
{:base "my-app"}
(d/div "Hello world"))
query->clj
(query->clj qp)
Function will URLSearchParams into clojure map
reducer
multimethod
Multifunction where you can extend router functionality.
Default implementations exist for routing events of type:
- :location/change
- ::add-components
remove-component
(remove-component tree id)
Function will remove component with id from component tree
Rendered
Component will render children if compnoent with :id from props is active (is contained in current URL)
set-component
(set-component tree {:keys [id parent children], :as component})
Function used to add component to component tree. For given component tree add component by specifying component id and component parent.
use-authorized?
(use-authorized?)
(use-authorized? id)
Hook that will return true if user is authorized to access component with “id”. If not will return false.
If ID is ommited, than authorized will check if user is superuser.
use-component-name
(use-component-name id)
For given component id, hook will return component name.
If component :name was keyword it will try to translate that keyword.
If component :name is string it won’t translate. Just return that name
If component doesn’t have :name, hook will try to translate component id (only if component exists in component tree)
use-component-path
(use-component-path component)
Hook will return url for component[id]
use-component-tree
(use-component-tree)
Hook will return routing tree for -router- context
use-go-to
(use-go-to component)
Hook will return function that will redirect browser to component[id]
. Returned function can be called with parameters, and those parameters will be set in URL query.
use-is-super?
(use-is-super?)
Hook that will return true if user is in super roles or false if he isn’t
use-link
(use-link parent children)
Hook will link parent with children components and add that to component tree for current -router- context. Children is expected to be map of:
- :id - Component ID. Should uniquely identify component
- :name - Name of component. Can be used to resolve what to display. If :name is of type string than use-component-name hook will return that name.
When keyword is used as name value use-component-name will try to resolve that keyword as translation in respect to locale in current app/locale context. - :hash - Optional hash that is appended to component URL
- :segment - Segment of path that is conjoined to all parent segments. Used to resolve if component is rendered or not and in use-go-to hook to resolve what is target path if I wan’t to “go” to component with id
- :roles - #{} with roles that are allowed to access this component
- :permissions - #{} with permissions that are allowed to access this component
- :landing -
[number]
to mark this component as possible landing site with number priority
Linking should start with parent :toddler.router/ROOT component, as this component is parent to all other components
use-location
(use-location)
Hook will return location from -router- context. Location will contain following keys:
{:pathname (.-pathname location)
:hash (subs (.-hash location) 1)
:origin (.-origin location)
:search (.-search location)}
use-query
(use-query)
(use-query action)
Hook returns [query-params query-setter]
. Query params are values that are pulled from URLSearchParams and query-setter is function that when called will set URLSearchParams
use-rendered?
(use-rendered? id)
Hook will return true if component with id is rendered, by checking if browser location contains component path.
use-url->components
(use-url->components)
Hook will return sequence of rendered components for current browser location
wrap-authorized
(wrap-authorized component)
(wrap-authorized component id)
Wrapper that will use Authorized component to render children if user is authorized
wrap-landing
(wrap-landing component url)
(wrap-landing component url enforce-access?)
Wrapper that will use LandingPage component to encapsulate component
wrap-link
(wrap-link component parent children)
Utility function to link component with children. Will use Link.
wrap-rendered
(wrap-rendered component)
(wrap-rendered component id)
Wrapper that will use Rendered component to render children if navigation is at component with id
wrap-router
(wrap-router component)
(wrap-router component base)
Wrapper that will use Provider component to encapsulate component