riot / route Goto Github PK
View Code? Open in Web Editor NEWSimple isomorphic router
License: MIT License
Simple isomorphic router
License: MIT License
Hi,
i have a route.base('/translations)
and when i click on link with href="/translations/login"
my url becoming /translationslogin.
How i can create translations/login?
I see that the docs mention riot-route is capable of isomorphic operation.
Is it possible to run two routers at once?
I wanted to make a new riot-route release but it seems that the tests keep failing in the dev
branch. @cognitom any clue about what's the issue? The master
branch does not have any problem
The router should call decodeURIComponent
on parameters before providing them to the callbacks, so that the callbacks receive the intended values rather than the URI-encoded values.
http://plnkr.co/edit/YZpDmc?p=preview
This router works in Chrome, but not work in Internet Explorer 11
Every time the tag is mounted, the page automatically redirects back to the last url when using the back functionality in js.
<a href="{ window.history.back() }" class="button secondary expanded raised-button ink">Back</a>
Do you want to request a feature or report a bug?
This is a bug
What is the current behavior?
The page does not open in ie11. I get an error: Invalid character
What is the expected behavior?
No error
IE is breaking when it tries to evaluate the template literal here:
https://github.com/riot/route/blob/master/dist/cjs.route.js#L59
Per the MDN it doesn't look like those are supported in IE at all.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
Steps to reproduce:
Try to use the router in an application loaded into IE11
I've found this doesn't work out of the box without setting riot.route.base('/')
Since this now uses history.pushState
shouldn't the default base be '/'
instead of '#'
?
I'm thinking about tag-based router as a new feature. I'm now working on feature/route-tag branch and I'd like to share my current idea here. Nothing was decided yet. Any feedback is welcome!
riot-route-tag
(draft)riot-route
riot
, too<app>
<router>
<route path="fruit/apple"><p>Apple</p></route>
<route path="fruit/banana"><p>Banana</p></route>
<route path="fruit/*"><inner-tag /></route>
</router>
</app>
<inner-tag>
<p>{ name } is not found</p>
<script>
this.on('route', name => this.name = name)
</script>
</inner-tag>
<router>
base
attribute (optional)const r = route.create()
so it creates subrouter<route>
path
attribute<route path="fruit/apple">
is equivalent to r('fruit/apple', () => { ... })
riot-route
insideWe could import them like this:
import route from 'riot-route'
// or
import route from 'riot-route/lib/tag' // note that it's not same as cjs below
const route = require('riot-route')
// or
const route = require('riot-route/tag')
packages
dir?require('riot-route/tag')
is not compatible with import 'riot-route/tag'
.if
implementation πsee riot/riot#1820
I discovered strange behavior that I believe can't be right. I'm seeing this on
Have a look at the plunkr here and click the links one after the other:
https://plnkr.co/edit/bGUkr1sueLDtcFrxd9sj
The problem is that the last click actually does change the url but no events are triggered (hashchange, popstate), also the riot handler is not run as in the steps before.
Also, I noticed that step 3 doesn't seem to add state. Perhaps this is why IE thinks that the current fragment is already "#a/b" so there is no event to trigger?
Any ideas?
Relative links work only on second click, if the location.hash
is set.
www.google.com
)When calling riot.route.start()
in Safari it gets auto-executed immediately. When I pass true
to this function my handler for the route is executed twice. This is only the case for Safari and not for FF or Chrome.
See this plunker:
http://plnkr.co/edit/uzjtYKZ9Rc5qb2T0XGaY?p=preview
Open it in Chrome and see the console:
initializing
route accessed
Safari:
initializing
route accessed
route accessed
See also the discussion on riot/riot#1063.
router
to this separated submodule from riot
router.base('/foo')
router('/bar/*', function(id) { ... })
(allow only wild card)Any feedback is appreciated π
If the route base is #
how do I link to a specific spot within a page? Normally you'd do something like some-page/#target
but that would trigger the Router. Any help here would be appreciated! :)
For testing this library, I'd like to introduce WebdriverIO. We're using Karma now, but even if it's a simple unit test, it can't handle page transition. It makes the tests difficult, especially for the libraries like riot-route
.
I've done the most part of the research. But some points are still open. Your feedback is welcome.
Saucelabs widget doesn't support multiple test in one repo, IFIK...
Previously, when a match is found, no other routes are triggered. Now multiple routes are firing.
I noticed this updating from riot 2.3.18 -> 2.5.0.
It appears to be caused by changes in riot observable, because it works correctly if I roll that back. Nothing in this route repo has changed in a while.
Example:
route('/post/*.amp.html', function() { /* */ })
route('/post/*', function() { /* */ })
Given the url: /post/title-of-my-post
The expected result is for the second route to trigger.
The actual result is both get triggered, and also appears to be a race condition of which one gets triggered first.
Currently the dist
folder contains route.js
that is meant to be used in nodejs but actually there is no way to use a standalone release that could be directly included in a browser environment without riot or an additional build step. Probably the package.json should point to the lib/index.js
file and the dist/route.js
should contain a build release including riot-observable
as well.
Hi guys (@cognitom @GianlucaGuarini ), is it possible to have routes without hash ?
I tried this :
riot.route.base('/')
It's working for /first
but it can't get the second one in /first/second
and I get this error :
I get the same error with just adding trailing slash like that /first/
It's the way used here https://github.com/riot/examples/blob/gh-pages/router-complex/index.html#L28 but it seems not working.
In fact the riot.route.base canβt be the same as parser
#/first/second
is working
/first#second
is working
/first/second
is not working
Obviously, this bug appears only when we enter the adress directly in the adress bar. I get almost the same bug with every version of superstatic.
It would be interesting to have the option of middlewares on routes, executing before they get properly handled. E.g.
riot.route('/products/new', function() {
// show view
}, ['UserController.isLogged']);
The idea is that middleware would always return a boolean. true
firing the route callback, false
preventing it from being handled.
There is also the .next()
approach, discussed on Issue #25. Maybe we could define which approach would be the more interesting.
Does anyone have a best practice or nice way to show/hide tags on a per-route basis? Ideally it would be mounting/unmounting the tag from the DOM entirely over simply showing/hiding, but I'm interested to see what others are doing.
/**
* Disable the default riot route parser
*/
riot.route.parser(function(path) {
console.info("parser",path);
return path; // return the path "as-is"
});
/**
* Handle route change event
*/
riot.route(function (path) {
console.info("route is change to",path);
});
riot.route.start(true);
I expect that my callback is called on every change of the url (as in the version 2.3.4)
But it is not true in case the route is changed from index.html#blog
to index.html#
The callback in the route.parser
is invoked with empty path, and the riot.route
callback is not called
PS: I don't know how to generate route problem with plunker
As natural naming convention, riot-router
seems the best. But this name was already taken by another user. (and that seems also a nice library)
https://www.npmjs.com/package/riot-router
At this time, I've chosen riot-route
for the package name.
https://github.com/riot/router/blob/master/package.json#L2
Any thought?
route('/en', '/en/home');
route('/zh', '/zh/home');
I have tried to update the dependencies and I was not able to run the tests in the dev
branch. @cognitom could you help on this please?
I need to load and unload sub-components dynamically and they have inner routes themselves.
I wanted to stop subRoute when component is unmounting, so the handlers wouldn't accumulate.
The code from router API doesn't work. I've tried in in playground and the error is same.
var subRoute = riot.route.create()
subRoute('/fruit/apple', function() { /* */ })
subRoute.stop()
Could riot/route
get a patch version bump and be updated in the next riot release?
There are a couple bug fixes that would be nice to include along with riot.
Also, the dev branch needs to be merged into master.
I'm starting to create an app for one client using Riot and one of the use cases is that the base route can change due localization, so I tried to use a regular expression in riot.route.base
method and it worked as a charm even though the docs don't mention it.
I've been inspecting the code to see if that's expected or not, because I wanted to make sure that it won't stop to work in path/minor version and I've clearly seen that method comments (api docs) specify that the parameters can be a string
or RegExp
, so I make the assumption that's a feature.
If you can assert all of this, I will send a PR with an update of the docs.
I updated from riot 2.x to 3.01 and I am using webpack:
Router β cjs.route.js:97 ReferenceError: Can't find variable: central
Any idea?
Note: Using Riot 2.3.1
So I was rewriting my webapp which used:
http://example.com#media/id
In the new version the base by default is '#' but it affects every link in the webpage, using or not using '#' so I couldn't click any links because it didn't do anything at all. I really needed to get it working so I finally changed the base to '/' and then the url in the adressbar started to change as I clicked the links but, It does nothing, just works with registered routes, in my case '/media...' after changing the base.
To get it working I needed to register '/..' and then redirect by javascript if the destiny was different from the origin. Here is the code (Which right now doesn't think in queries) I used to get this working If it is of any help:
getUrl = ->
"#{window.location.protocol}//#{window.location.host}#{window.location.pathname}"
oldMediaId = null
baseUrlForRouter = getUrl()
$(document).ready ->
riot.route.base('/')
riot.route 'media/*', (mediaid)->
if mediaid? and oldMediaId != mediaid
mediaPopupExec(mediaid)
oldMediaId = mediaid
riot.route '/..', () ->
tUrl = getUrl()
if tUrl != baseUrlForRouter
window.location.replace(tUrl)
riot.route.start(true)
So I can't find anything to solve it in a more official way. Usually in ExpressJS (Node.js) routes are like (req, res, next), and the next param is to call the next registered route which fits the actual route with his filter. If it doesn't have any other, it makes the default move, which in Express usually would be 404 because It doen't find any route, but here would be to send it to the clicked url.
In less words: When any route doesn't satisfy the asked route, it ""shouldn't do event.preventDefault()"" (Just as an example XD)
Sorry if there is an official way to do this, but I couldn't find it :S
Hi guys, with the riot-router, when I click the back button on the browser, the page address did change back to the previous one but the page was not reloaded. Is this a bug or designed like this? if expected, how should I make the content also change back? Regards!
Hello
I created a basic app with Riot 3.1.0, and the latest router (I built it from sources, as riot+route.min.js doesn't seem to be available on jsdelivr).
The app contains three files:
hello.tag:
<hello>
<span>Hello { opts.name }!</span>
</hello>
app.tag:
<app>
<router>
<route path="">
<hello name={ name }></hello>
</route>
</router>
<script>
this.name = "World"
</script>
</app>
index.html:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<app></app>
<script type="text/javascript" src="riot+compiler.min.js"></script>
<script src="route+tag.min.js"></script>
<script type="riot/tag" data-src="./app.tag"></script>
<script type="riot/tag" data-src="./hello.tag"></script>
<script type="text/javascript">
riot.mount('app')
</script>
</body>
</html>
I expected this to display "Hello World!" but the result is "Hello!".
In hello.tag, this.opts.name is an empty string.
Did I miss something, or is there a real problem?
Hi, my scenario is like this:
My code is now like this (v2.3):
studyRoute(view, id) {
switch(view) {
case 'news':
require('./views/news-view.html')
self.loadView('news-view', id)
break
default:
riot.route('news/1') // is this supported?
}
}
riot.route(self.studyRoute)
riot.route.start()
riot.route.exec()
If I start with empty path url, it will bring me to /#news/1
, which is correct. However after changing the url, the studyRoute is not called again, thus my actual logic is not executed.
I am not sure if it is due to I am not writing the correct code, or a bug. Please advise :)
I have faced with strange behaviour of single page application built with riot.js . Its rendering was delayed until loading of all external js libraries finishes. It includes async externals, iframes content, etc. After investigation it became clear that route.start(true)
calls appropriate route handler only after 'load' event browser trgiggers.
It was not trivial to find the reason, a lot of time was spent. I suggest to describe this behaviour in documentation and suggest to explicitly call of route.exec()
where it`s possible. My problem was solved as follows:
riot.route.start() // call of start(true) delays route processing before 'onload' event raises
riot.route.exec() // so need call exec() in place
Hi guys,
New to riot and redux and trying to follow better practices and patterns.
So, I've done this example:
https://github.com/Sendoushi/code-examples/blob/redux-riot/src/bootstrap.js
How would you improve?
I know this isn't an issue, a help wanted.
I have route: /login?path=*
But when I go to url: http://localhost:8000/login?path=test
, and of my routes handling this one.
Is it posible to make hash fragment starts with #!
?
It is necessary for Search Engine Crawlers.
https://developers.google.com/webmasters/ajax-crawling/docs/specification
There's very little point in having a route matcher that does not (1) regard the values obtained by riot.parser.fn1
and (2) inconsistently produces callback function parameters.
Eg:
riot.route('/fruit/*', function(name) { /* */ })
riot.route('/fruit/apple', function() { /* */ })
riot.route('/fruit/orange', function() { /* */ })
Not only is there a name
parameter JUST for wildcard matching, but this setup requires fruit
as the bare minimum abstraction.
Expectedly, all route callbacks should plug into the values obtained by parser.fn1
. In the default scenario, this looks like:
riot.route('/fruit/*', function(collection, id, action) { /* */ })
riot.route('/fruit/apple', function(collection, id, action){ /* */ })
riot.route('/fruit/orange', function(collection, id, action) { /* */ })
Of course, some parameters may still be undefined, but at least you can always expect a set of parameters in the callback.
My second point: We have to have a full set of routes just for fruit
, and will have to repeat the same set for cars
and another for trees
, etc.
This practice only makes sense when you're designating routes for a specific tag or a specific set of tags. This same practice prevent you from having a succinct, global level routes declaration.
The same solution allows for:
// (1)
riot.route('..', function (collection, id, action) {
// ..
});
// (2)
riot.route('fruit/apple/..', function (custom, parser, args) {
// .. long-tail url, read it
});
(1)
: While this isn't a recommended only solution, it allows for a nice last resort/"catch-all" which has the power to run its own logic based on params
(2)
: Dependent on our desired URL structure (and appropriate parser fn), we can allow for deep, complex URLs and handle them all at once without having to declare multiple blocks, repeating boilerplate.
Anyway, Issue getting a bit long here. If this is approved, I have the matching PR ready to be opened. It's a simple 2-line fix
After repo name changed (riot-router --> riot-route), coveralls seems not working. I've already changed the source and synced it. There's something buggy. Some issues like this is reported on coveralls' repo.
lemurheavy/coveralls-public#603
I have tried including the new router in the new riot build https://github.com/riot/riot/blob/2.3.0/lib/riot.js
but it does not pass the old router tests. Do I need to test a build script with esperanto or do we stick with smash? In case we want to use smash the router code should be wrapped in its own IIFE avoiding to pollute the global scope. What do you recommend?
OK:
<a href="/go/to/somewhare" title="Somewhere">Somewhere</a>
NG:
<a href="#go/to/somewhare" title="Somewhere">Somewhere</a>
I'm playing around with the 3.0 version of Riot and the router has been removed. I'm wondering if there is a release of the stand alone router on a CDN someplace?
I've checked a few including cdn.jsdelivr.net (where I'm grabbing the 3.0 riot from) but I cant seem to locate the router code.
I'm using https://cdn.rawgit.com/riot/route/master/dist/route.js
for now, but a released version on CDN would be much better.
When using # as the base, route.query()
for these URLs is not behaving correctly:
index.html?param=xyz#/search
=> { param: "xyz#/search" }
index.html?param=xyz#/search?q=keyword
=> { param: "xyz#/search?q=keyword" }
Where ?param=xyz
are query params for the server rather than the router.
It's not entirely clear how it should behave. The docs don't address it and the specs only test with '/' base. My expectation is that if using a # base, the router should only consider query params after the #. Which would look like this:
index.html?param=xyz#/search
=> {}
index.html?param=xyz#/search?q=keyword
=> { q: "keyword" }
When using '/' as the base, the issue doesn't exist because there's only one set of query params which is shared between server and router.
I didn't manage to write a spec to show this failing because the code behaves differently when running in the test suite (it doesn't use location.href).
route('fruit/*', function() {
// This is not invoked
})
route('fruit/red-apple')
Failing test: https://github.com/gdub22/route/commit/0a1c43664460a6e304680d06e5ecd11fbd3a94d3
We should simply allow something like the exec
method to work server-side. This way, you can pass it the request path and let your route handlers do any rendering they normally would do on the client side.
I can work on a PR if you agree with the idea.
I'm used to link with a CTRL+click opening in a new tab/window. Is there a way to do that with the riot.route
?
Or replace my riot.route
with a href
that the router picks up?
Thanks!
I have this setup for riot routing -
var router = function(page,id) {
function change_page(current_page){
RiotControl.trigger('page_changed', current_page, xmenu.last_page)
xmenu.last_page = current_page;
}
page = !page ? 'home' : page;
change_page(page);
}
// Riot router
riot.route(router)
// Execute router function once for rendering the items
riot.route.exec(router);
when I click a link with href="#home" or set location.hash the callback function 'router' is never called in ie11 works fine in chrome and ff.
@tipiirai can't we change the API of route.exec()
?
v2.2 allowed a custom callback for this function, but I'd like to make it callable without a callback.
// v2.2
riot.exec(callback)
// v2.3
riot.exec()
I often use it this manner in v2.2, but it looks redundant:
// v2.2
var callback = function(id) {
/* do something */
}
riot(callback)
riot.exec(callback)
And if there're multiple routings, we have no way to exec
. Any advice or thought?
(At this time, this would be the only point which is not compatible with v2.2)
History API provides two methods for updating state: pushState
and replaceState
. The latter is used when there is no intention to create a new history entry. There are realistic use cases for this. Other frameworks that have routing provide such method (e.g. Backbone and Mithril). Is it possible to add such option to Riot?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.