olivernn / davis.js

RESTful degradable JavaScript routing using pushState
http://davisjs.com
532 stars 58 forks source link

problem with hash #44

Open mirzadelic opened 12 years ago

mirzadelic commented 12 years ago

Hi, i use default demo with 2 links, and alert, now i included hash and title plugin. and my code is:

    <script type="text/javascript">
        Davis.extend(Davis.hashRouting({ prefix: "!"}));

        var app = Davis(function () {
            this.use(Davis.title);

            this.configure(function () {
                this.generateRequestOnPageLoad = true
            });
            this.get('/welcome/:name', function (req) {
                alert("Hello " + req.params['name']);
                this.setTitle(req.params['name']);
            });
        });

        app.start();

    </script>

        <a href="#!/welcome/oliver">greet oliver</a> //link 1
        <a href="#!/welcome/bob">greet bob</a> //link 1

now problem is when i click on link, it redirect me to: http://localhost/%23!/welcome/bob#!/welcome/bob What is the problem ? :(

olivernn commented 12 years ago

Sorry for late response. So we discussed this a little on stackoverflow, also there is a gist with some more discussion.

So as you mentioned there is a bug with the approach that I suggested in that you end up with two hashes, this may or may not be a problem, but it is definitely not correct.

I think the way the hashRouting plugin works at the moment is not quite right, the guy who contribuited it wanted to be able to fall back to hashes when pushState is not available. I don't think this is the right approach and would advise against it. Because of this I will re-write, or create a separate extension, so that you can use Davis with hashes instead of pushState.

You also mention wanting to prefix the hash with a bang, this can be done by setting the prefix:

Davis.extend(Davis.hashRouting({ prefix: "!" }))

Hope that helps, if you have any more questions lets carry this discussion on here.

mirzadelic commented 12 years ago

Thanks man, just tell me if you can, when there will be your hash plugin i will wait for it ?

olivernn commented 12 years ago

I'll try and put something together over the weekend, I have a few other fixes that need to be done as well. I'll let you know when an early version is up if you like, would appreciate some help in testing it etc.

mirzadelic commented 12 years ago

Yes, please inform me, and i can try to help you with testing..

mirzadelic commented 12 years ago

Any news about new version ?

olivernn commented 12 years ago

Sorry for the delay in getting this to you, been stupid busy with work recently…

Anyway I've put together a really simple implementation of a hash based router for Davis here. It is much simpler than the current extension, there is no fallback from the pushState routing etc.

This is currently a work in progress but please try it out in your app and give me any feedback etc.

mirzadelic commented 12 years ago

Thanks man, it works, now look my code and tell me if this is right way:

<script type="text/javascript">
    Davis.extend(Davis.hash)

    var app = Davis(function () {

        this.use(Davis.title);

        this.get('/welcome/:name', function (req) {
            console.log("Hello " + req.params['name']);
            this.setTitle(req.params['name']);
        });

    });

    app.start();

</script>

<a href="#/welcome/oliver">greet oliver</a>
<a href="#/welcome/bob">greet bob</a>

in this way it works fine, that is correct using ?

And 2 more questions:

This is in work, so it will be better in time.. Thanks, and i'm here if you need someone to test.

olivernn commented 12 years ago

Your example looks correct to me, again if you run into any issues let me know, or fork the gist and make changes as you require them.

Yep, currently there is no way of specifying a prefix, this can be easily added through some configuration options being passed to the extension. The reason some sites use the bang (!) prefix is for google ajax crawling.

Good point on the generateRequestOnPageLoad setting too, feel free to add that yourself or I can update the gist at some point.

mirzadelic commented 12 years ago

My bad, generateRequestOnPageLoad works just fine.. i tried.. And what is your suggestion about bang (!) prefix, should that option exist in plugin ? btw, there is solution for bang(!) using:

  var current = function () {
    return window.location.hash.replace(/^(#!)?\/?/, '/')
  }

hope this is correct ?

Thanks.

olivernn commented 12 years ago

Yes I think it should be an option that is passed when extending Davis with the extension, something like this:

Davis.extend(Davis.hash({prefix: '!'))

I think the way this would be implemented would be to add the prefix in the assign method and strip it out in the current method.

var assign = function (req) {
    if (req.method === 'get') {
        window.location.hash = '!' + req.location()
    } else {
        triggerHandlers(req)
    }
}

var current = function () {
    return window.location.hash.replace(/^#?\!?\/, '/')
}
mirzadelic commented 12 years ago

You will add this option ? When you will have time to work on this?

There is error in this function;

var current = function () {
    return window.location.hash.replace(/^#?\!?\/, '/')
}
mirzadelic commented 12 years ago

I gave up use of hashbang plugin, i will use plugin on default(history)... This hashbang method is not helping me at all, still works only on html5 browsers, so i will use davis.js plugin without hash. Thanks for help.

olivernn commented 12 years ago

What part of the hashbang method only works for you on HTML5 browsers? The hash extension that I showed you should work anywhere, interested to know what issue is preventing you from using it in older browsers.

mirzadelic commented 12 years ago

Hashbang method works on HTML4 browsers ? But search engines doesn't se pages with hashband, only google :(

olivernn commented 12 years ago

Routing via the location.hash is perfectly workable in older browsers, there are some issues, notably that the hashchange event isn't supported everywhere, however there are workarounds for this that mean that this style of routing can be made to work pretty much everywhere.

Whether search engines can use sites that have hash based routing and whether it is a good fit for you style of application is a different question altogether.

In summary I still want to update the hash extensions that is currently in davis to be more similar to the one I linked to earlier in this discussion. I don't think trying to be clever and falling back to hash routing if push state is not available is a good idea (it opens up many edge cases) etc, hence why I want a simpler hash based extension.

mirzadelic commented 12 years ago

Then it would be nice to make hash extension to run only if browser is html4, and on html5 to use normal pushstate with normal urls. What you think about that?

mirzadelic commented 12 years ago

Any news ? :(

olivernn commented 12 years ago

Yes, I haven't got any further with the hash extension, although I think the gisted version I linked earlier is basically the hash plugin.

I won't be doing any kind of fallback behaviour, i.e. using pushState in capable browsers and then hash based routing in other browsers as I think the specifics of this are best left to the application developers. But using the hash extension you should be able to do this yourself if you application needs it.