Relative paths like "#../../resource" possible to support?

173 views
Skip to first unread message

Daniel Dotsenko

unread,
May 17, 2012, 2:43:23 PM5/17/12
to sam...@googlegroups.com
Hi.

Trying to put together a Sammy.js-based site composed of a few pages that refer to each other. However, do not want to hardcode the hash path within the links. Was wondering how I can wire up 

Example:

#/projectname/article/introduction/
#/projectname/article/LineSmoothing/
#/projectname/article/API/
#/projectname/demo/basic/
#/projectname/demo/TransactionCapture/
#/projectname/

I anticipate possibility of changing "projectname" or reusing some of the children pages for other projects (clones, for example). 

I would like to refer from #/projectname/article/introduction/ to #/projectname/article/LineSmoothing/ as "#../LineSmoothing/" or from #/projectname/article/introduction/ to #/projectname/demo/basic/ as "#../../demo/basic/"

A scant look over Sammy's code does not give me hints at this kind of functionality. (I am also royally confused by the multitude of history backends and how they track < a > clicks.)

I don't mind coding this in and understand I need:
1)  to catch the < a > clicks before they change window.location, 
2) See if a.href has "relative link patern, if yes
3) extract current path from pre-changed location,
4) chop the hash part and form new full hash part
5) push that into router

Will this work with all of the hash change / history plugins or only some? I only care about support for old style (ones that work same across all browsers) paths that actually contain "#" in them. The new hash-less URLs are of no interest to me, so if that one cannot "front-run" and reform the hash url, i would not mind.

Again, i don't mind coding this if you think this is feasible. Thoughts, tips for me?

Daniel.

Daniel Dotsenko

unread,
May 17, 2012, 3:14:12 PM5/17/12
to sam...@googlegroups.com
HI

Contemplated for a sec using "document.referrer" as a post-click way of resolving "relative" hashes. But, no dice. After setLocation  document.referrer returns an empty string.

Otherwise, I could have just had a catch-all route set for /\#\..*/ where i could probably scrape prior path from  document.referrer, form a proper hash based on prior path and current "relative" and set new location...

So, still interested in your answer if front-running A tag clicks and massaging the URI would be possible.

Daniel.

Daniel D.

unread,
May 17, 2012, 7:17:48 PM5/17/12
to sam...@googlegroups.com
Managed to scratch my own itch. Wrote front-running event handler for
clicks on A tags. In case anyone may need something like this:

This works with Sammy.js 6.x latest. (Did not have a reason to upgrade
to or test with 7.x)

Upon click on A tag, "relative" hash like "#../../path/resource" is
computed against current ("referrer") hash (for, example,
"#/asdf/qwer/zxvc/this_part_is_not_folder" to result in
"#/asdf/path/resource". The new resolved "absolute" hash is written
into href of the clicked link and we release the event. It bubbles up
and "finishes" the click, now with new href.

Presto: "relative" hash references between AJAXy subpages.

------------------

$(sammy_controlled_element_selector).on('click.sammy_front_runner',
'a', function(e){
/** @preserve
Copyright 2012 - Willow Systems Corporation (willow-systems.com)
MIT or GPLv2
*/
var $t = $(e.currentTarget)
, encodedHash = $t.attr('href')

// if encodedHash starts with "#.." indicating start of relative hash
if (encodedHash.substr(0, 3) === '#..'){
var resolvedURL = $t.prop('href').split(encodedHash)
// if there is nothing trailing the relative hash fragment in
resolved URL
if (resolvedURL.length === 2 && resolvedURL[1] === ''){
var newHashParts = window.location.hash.split('/')
// regardless of if the end was "/" (resulting in last
string of "") or "file.ext", it's not a name of "dir". Dropping.
newHashParts.pop()
// chopping off "#" and splitting the dirs in new relative hash
var encodedHashParts = encodedHash.substr(1,
encodedHash.length).split('/')
, section
while(encodedHashParts.length){
section = encodedHashParts.shift()
if (section === "..") {
if (newHashParts.length > 1 /* we are keeping '#'
in place */) {newHashParts.pop()}
}
else if (section === ".") {}
else {newHashParts.push(section)}
}
var newHash = newHashParts.join('/')
$t.attr('href', newHash)
$t.prop('href', resolvedURL[0] + newHash)
}
}
return true;
})


-----------------------------------
> --
> You received this message because you are subscribed to the Google Groups
> "Sammy.js" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/sammyjs/-/dqfXzV9oDsMJ.
>
> To post to this group, send email to sam...@googlegroups.com.
> To unsubscribe from this group, send email to
> sammyjs+u...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/sammyjs?hl=en.

Daniel Dotsenko

unread,
May 21, 2012, 5:47:39 PM5/21/12
to sam...@googlegroups.com
Put together a Sammy plugin that resolves relative hash like "#./anotherpage" or "#../../folder/resource" against current hash.

This saves us from rewriting the page templates every time hash to them changes, and they now can refer to eachother without knowing parent folder's hash.

Here is a demo:

Code (plugins, tests, example) is here:

The plugins were written for 0.6.x branch, but (per tests) seem to work against 0.7.x too.

If someone cares, enjoy.

Daniel.

On Thursday, May 17, 2012 11:43:23 AM UTC-7, Daniel Dotsenko wrote:
Reply all
Reply to author
Forward
0 new messages