vanntile
vanntile

Reputation: 2787

create a template url-routing script

I want to create an url-routing script using javascript as much as possible, but also accepting jQuery in the code. The js file has to change the url path (although I used location.hash instead of location.pathname) and the content of a div with the view id (from external files) accordingly.

Example configuration:

home.html content:

<p>This is content of home page</p>

about.html content:

<p>This is the content of the about page </p>

What I have done so far:

'use strict';
var Router = {
root: '/',
routes: [],
urls: [],
titles: [],
navigate: function() {
    location.hash = this.root;
    return this;
},
add: function(thePath, theUrl, theTitle) {
    this.routes.push(thePath);
    this.urls.push(theUrl);
    this.titles.push(theTitle);
},
loading: function() {
    this.navigate();
    var r = this.routes;
    var u = this.urls;
    window.onload = function() {
        $("#view").load("tpl/home.html");
    };
    window.onhashchange = function() {
        for (var i = 0; i < r.length; i++) {
            if (location.hash == r[i]) {
                $("#view").load(u[i]);
            }
        }
    };
}
};
Router.add("#/home", "tpl/home.html", "Home Page");
Router.add("#/about", "tpl/about.html", "About Page");
Router.loading();

Desired type of url:

http://mywebsite.com/
http://mywebsite.com/about

I know there are more than enough libraries that make the routing, like AngularJS and Crossroad, I want to know how this could be done.

Upvotes: 2

Views: 5826

Answers (4)

Camel
Camel

Reputation: 345

You might be interested by frontexpress.

My library fix your case like below:

// Front-end application
const app = frontexpress();

const homeMiddleware = (req, res) => {
  document.querySelector('#view').innerHTML = '<p>This is content of home page</p>';
}

app.get('/', homeMiddleware);

app.get('/home', homeMiddleware);

app.get('/about', (req, res) => {
  document.querySelector('#view').innerHTML = '<p>This is the content of the about page </p>';
}); 

Obviously, you can get the template files from the server. The #view will be feeded as below:

document.querySelector('#view').innerHTML = res.responseText;

More detailed sample in this gist

Upvotes: 2

Bob Dill
Bob Dill

Reputation: 1010

Your request reads like what you're attempting to do is to add a "path+file" ("/tpl/about.html") to a base url ("www.myhost.com"). If that's the case, then you need to dynamically extract the host name from your current document and then append the new URL to the existing base. You can get the existing host name by executing the following commands in javascript:

var _location = document.location.toString();
var serverNameIndex = _location.indexOf('/', _location.indexOf('://') + 3);
var serverName = _location.substring(0, serverNameIndex) + '/';

This will return a string like: "http://www.myhost.com/" to which you can now append your new URL. All of this can be done in javascript prior to sending to the server.
If you only want the server name, without the leading http or https, then change the last line to be:

var serverName = _location.substring(_location.indexOf('://') + 3, serverNameIndex) + '/';



Lets break your code down a little bit:

       function loading() {

"location.hash" is set based on the URL most recently clicked (www.myhost.home/#about). One essential question is, is this the action that you want, or do you want to pass in a value from the html for the onClick operation? It seems like that would be a more effective approach for you.

            var a = $.inArray(location.hash, routes),
                template = urls[a];

var a will be set to either -1 or the location of "location.hash" in the "routes array. If location.hash does not exist in routes, then a==-1 and the script will fail, because you're setting template = urls[-1]. You may want to move setting template to inside the "else" statement.

           if (a === -1) {
                location.hash = root;
                $("#view").load(urls[0]);
            }
            else {yada yada yada
            }

You could use a sequence in your html analogous to:

<a onclick="loading('#about')">Go to About Page</a>

Upvotes: 0

vanntile
vanntile

Reputation: 2787

I have worked with what your answers and I have build the following Router. The only issue remains that it still uses location.hash

(function() {
    var Router = {
        root: '#/',
        routes: [],
        urls: [],
        titles: [],
        add: function(thePath, theUrl, theTitle) {
            this.routes.push(thePath);
            this.urls.push(theUrl);
            this.titles.push(theTitle);
        },
        navigate: function() {
            var routes = this.routes,
                urls = this.urls,
                root = this.root;

            function loading() {
                var a = $.inArray(location.hash, routes),
                    template = urls[a];
                if (a === -1) {
                    location.hash = root;
                    $("#view").load(urls[0]);
                }
                else {
                    $("#view").load(template);
                    if (a === 0) {
                        window.scrollTo(0, 0);
                    }
                    else {
                        window.scrollTo(0, 90);
                    }
                }
            }
            window.onload = loading;
            window.onhashchange = loading;
        }
    };
    Router.add("#/", "tpl/home.html", "Home Page");
    Router.add("#/about", "tpl/about.html", "About Page");
    Router.add("#/licence", "tpl/licence.html", "MIIT Licence");
    Router.add("#/cabala", "tpl/cabala.html", "Cabala Checker");
    Router.add("#/articles/esp", "tpl/article1.html", "ESP");
    Router.add("#/fanfics/the-chupacabra-case", "tpl/article2.html", "The Chupacabra Case");
    Router.navigate();
})();

Upvotes: 0

nothingisnecessary
nothingisnecessary

Reputation: 6233

To make this URL work - http://mywebsite.com/about - you need a server that knows how to route this request. Since the actual file name is about.html your server must know what to do with extensionless URLs.

Usually, the server uses the file extension as a clue for how to serve up content. For example, if it sees file.php it knows to use the PHP component, for .aspx it knows to use the ASP.NET component, and for .htm or .html it knows to respond with plain HTML (and usually serves the file instead of processing it). Your server must have some rules for what to do with any request, whether it has an extension or not, but without an extension you need to provide an explicit routing rule for that request..

The capabilities for JavaScript to do routing are limited because it requires the user to already be on your site. You can do some interesting things if you parse the URL parameters or use hashes and use them for routing, but that still requires requesting a page from your site as the first step.

For example: the server is already doing some level of "extensionless routing" when you give it this request:

http://mywebsite.com/

The parts of the URL are:

  • http - protocol
  • (port 80 is implied because it is default HTTP port)
  • mywebsite.com - domain AKA host
  • / the path

The server sees / and uses what IIS calls a "default document" (I think apache calls it "default index" or "default page"). The server has been configured to return a file such as "index.html" or "default.htm" in this case. So when you request http://mywebsite.com/ you actually may get back the equivalent of http://mywebsite.com/index.html

When the server sees http://mywebsite.com/about it may first look for a folder named about and next for a file named about, but since your file is actually named about.html and is in a different folder (/tpl) the server needs some help to know how to translate http://mywebsite.com/about into the appropriate request - which for you would be http://mywebsite.com/#/about so that it requests the routing page (assuming it is the default document in the web app root folder) so that the browser can parse and execute the JavaScript that does the routing. Capisce?

Upvotes: 4

Related Questions