Add ability to parse root site deployment path (#2)
This commit is contained in:
parent
4dc36533cb
commit
245efe7db9
@ -8,7 +8,7 @@ Most of this code is adapted from [http4s](http4s.org)'s route parsing and path
|
|||||||
Add to library dependencies:
|
Add to library dependencies:
|
||||||
|
|
||||||
```
|
```
|
||||||
"com.clovellytech" %%% "outwatch-router" % "0.0.5"
|
"com.clovellytech" %%% "outwatch-router" % "0.0.6"
|
||||||
```
|
```
|
||||||
|
|
||||||
See [documentation][doc-root]
|
See [documentation][doc-root]
|
||||||
|
@ -12,10 +12,19 @@ final case class Replace(path: Path) extends Action
|
|||||||
|
|
||||||
final case class RouterState[P](page: P)
|
final case class RouterState[P](page: P)
|
||||||
|
|
||||||
class AppRouter[P](root: Path, f: Path => P) {
|
/**
|
||||||
|
* An AppRouter handles parsing of URLs and mapping to pages of the given type.
|
||||||
|
* @param siteRoot - The prefix part of a pathname, or the subpath at which your site is applied.
|
||||||
|
* Usually this is just Root, but your site might need a prefix as in /my_site/[parsed pathname]
|
||||||
|
* @param parent - The parent path at which this router is mounted. You can have routers contained in subroots of your site.
|
||||||
|
* @param f - a mapping function from a Path to a page P.
|
||||||
|
* @tparam P - Your page type, such as a sealed trait root type.
|
||||||
|
*/
|
||||||
|
class AppRouter[P](siteRoot: Path, parent: Path, f: Path => P) {
|
||||||
|
// Sync from the required page to the window.location
|
||||||
def routerReducer(state: RouterState[P], action: Action): RouterState[P] = action match {
|
def routerReducer(state: RouterState[P], action: Action): RouterState[P] = action match {
|
||||||
case Replace(path) =>
|
case Replace(path) =>
|
||||||
window.history.replaceState("", "", Path(root, path).toString)
|
window.history.pushState("", "", Path(siteRoot, Path(parent, path)).toString)
|
||||||
state.copy(page = f(path))
|
state.copy(page = f(path))
|
||||||
case _ => state
|
case _ => state
|
||||||
}
|
}
|
||||||
@ -39,5 +48,33 @@ object AppRouter{
|
|||||||
create[P](Root, notFound)(f)
|
create[P](Root, notFound)(f)
|
||||||
|
|
||||||
def create[P](parent: Path, notFound: P)(f: PartialFunction[Path, P]): AppRouter[P] =
|
def create[P](parent: Path, notFound: P)(f: PartialFunction[Path, P]): AppRouter[P] =
|
||||||
new AppRouter[P](parent, f.lift.andThen(_.getOrElse(notFound)))
|
new AppRouter[P](Root, parent, f.lift.andThen(_.getOrElse(notFound)))
|
||||||
|
|
||||||
|
def createParseSiteRoot[P](notFound: P)(f: PartialFunction[Path, P]): AppRouter[P] =
|
||||||
|
createParseSiteRoot[P](Root, notFound)(f)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Automatically determine what siteroot we're using, based on the current URL and expected parent.
|
||||||
|
* For example, your site could be deployed at /example/directory/, your router root path could be /names,
|
||||||
|
* and the current url could be /example/directory/names/alice. So given the call:
|
||||||
|
* createParseSubRoot[Page](Path("/names"), NotFound)(f), the router will work out that the window location
|
||||||
|
* prefix must be /example/directory/names, and will handle actions such as Replace(Path("/names/bob"))
|
||||||
|
* @param parent the parent for this router, another path perhaps managed by another router
|
||||||
|
* @param notFound - the default case page assignment
|
||||||
|
* @param f - a router function from Path to instances of your page type
|
||||||
|
* @tparam P - your page type
|
||||||
|
*/
|
||||||
|
def createParseSiteRoot[P](parent: Path, notFound: P)(f: PartialFunction[Path, P]): AppRouter[P] = {
|
||||||
|
val initUrl = window.location.pathname
|
||||||
|
// url is of form /sra/srb/src/pa/pb/pc...
|
||||||
|
// so just drop the parent part from the right of the url if it exists.
|
||||||
|
|
||||||
|
val siteRoot = initUrl.lastIndexOf(parent.toString) match {
|
||||||
|
case x if x < 1 => Root
|
||||||
|
case x => Path(initUrl.substring(0, x))
|
||||||
|
}
|
||||||
|
|
||||||
|
val routerFun: Path => P = f.lift.andThen(_.getOrElse(notFound))
|
||||||
|
new AppRouter[P](siteRoot, parent, routerFun)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
object Version{
|
object Version{
|
||||||
val version = "0.0.5"
|
val version = "0.0.6"
|
||||||
val scalaVersion = "2.12.8"
|
val scalaVersion = "2.12.8"
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user