What to base your links on
Creating links in Domino is a pain. There are so many ways to do it. These many methods also need to take account of where you are at in the hierarchy of the database's structure in order to predict how the link should be built and where it should be relative to. Let's try and make it a little easier shall we.
The Problem:
If you are like me, and use Pass-Thru HTML as the basis of all your forms, then you probably find yourself constantly referring to the path of the current database when you create a link. This is not only a chore but can also be a strain on the server if it has to calculate the path every time you add a link.
The normal method seems to be to have one Computed for Display field called something like "DBPath", which has the following formula:
@ReplaceSubstring( @Subset ( @DBName; -1 ); "\\"; "/")
Then, whenever you create a link to any other part of the database, you can use this value to make it complete and relative to the server. This usually involves adding some type of computation to the form. Consider the screenshot below:
This form contains the field called DBPath and some links that point to pages within this database. The links are made relative by using Computed Text values in each whose value it the same as the DBPath field's value.
I've also seen occasions where people have used numerous fields to achieve this goal, like below:
Not nice. You would never catch me doing this.
The Solution:
Previously I have talked about how to create links that are simpler to manage. The article talked about making links relative so that there was little or no need for the DBPath field. However, this method had its drawbacks and I have since found a fool-proof method that removes all need for the repeated use of this field.
This new method uses the <base> element's href attribute to set the base URL of all relative references in the document. Let's look at an example. If the following line of HTML were the first line in the <head> tag then all we would no longer need to add the path of the database to all our SRC and HREF attributes.
<base href="http://www.codestore.net/A55692/store.nsf/">
So to add a link to the global.js JavaScript Page Element all we need to add to the <head> is:
<script type="text/javascript" src="global.js"></script>
Or to add a link to a form that opens another form we just add:
<a href="other?OpenForm">Other Form</a>
One area in which this is extremely useful is when we use the "Treat as HTML" property for a view. No longer do we need to add the path in the column that contains the view. All we need now a formula similar to the following:
"<td><a href=\"viewname/" + @Text(@DocumentUniqueID) + "?OpenDocument\">" + FieldValue + "</a></td>"
Implementation:
Hopefully by now you are seeing the potential benefits of this method. It makes life a lot easier, trust me. Let's see how to add it to our forms.
First thing to do is make sure that all your forms contain the "DBPath" CFD field with the above formula (OK so I lied about no longer needing that field) and a CFD field called "Server_Name" with a value the same its name.
Secondly we need to add the following line of code as the first line in the HTML Head Contents section of all the forms:
"<base href=\"http://" + Server_Name + "/" + DBPath + "\/" />"
The form we looked at above will now like a little simpler:
But, what if....
If you start to use this on new forms you create, it won't be long before you notice some strange behaviour. Links that should go here go there, images are missing and JavaScript functions don't work anymore. Don't worry it's easy to fix.
The thing you need to do is take account of all the linked resources that are not relative to the current path. For these all you need do is make them absolute by adding the preceding / to them. Like so:
<a href="/another/database.nsf/different?OpenForm">Other Form</a>
Et voila...
A correct Path evaluation
I believe that you forgot something in your @ReplaceSubstring formula.
What about the spaces ??? If you try to replace a URL with your results it will fail because NO URL Location accept spaces ==> the @replacesubstring formula will be :
@ReplaceSubstring (@Subset(@dbname;-1) ; "\\":" " ; "/":"+");
PS : That's really great site !
Reply
Re: A correct Path evaluation
Thanks for that Laurent. I always appreciate valuable feedback ;)
The reason I left out the removal of spaces is that, as a Domino developer who does no Client work, I never create a database with a file name including spaces or any design elements that have spaces in them. I suggest others do the same...
Jake CodeMaster
Reply
Show the rest of this thread
Another undocumented path evaluation
Another undocumented path evalution I found in one of Lotus' templates is to use @URLEncode.
syntax: @URLEncode("Domino";<string>)
This function is equal to the Javascript 'escape' function. The escape function encodes special characters in the specified string and returns the new string. It encodes spaces, punctuation, and any other character that is not an ASCII alphanumeric character, with the exception of these characters.
So use this @function for path calculation:
@URLEncode("Domino";@Subset(@DbName;-1));
You can use this function to encode al designelements.......ie. @URLEncode("Domino";@ViewName))
Reply
Re: Another undocumented path evaluation
If you leave out domino in the @UrlEncode then you will get utf-8 which is better than the domino which uses it's own format.
@UrlEncode("";URL)
keep on with the good stuff,
kester
Reply
Show the rest of this thread
Re: Another undocumented path evaluation
This function will be very useful--thanks--but you really don't want to use it to create your links, since it will turn slashes into ' %5C', rendering them useless.
The way original way (with the modification for spaces!) is the best way I know of to calculate links.
Reply
Re: Another undocumented path evaluation
Hello! Great site, Jake! It always helps a lot!
I've been looking into '@URLEncode' to change strings in the urls. My application is French and has some accents in it. ~:| Is there a '@URLDecode' or equivalent? I've seen people write about, but there's not much info out there.
Thanks, in advance,
Steve in Montreal. =8D
Reply
Show the rest of this thread
Using JavaScript to get the path
Here's a handy function I use a lot to get the path of the current database in JavaScript. I find it useful to redirect the browser based on some UI changes, ie:
location.href = getDBPath() + '/MyAgent?OpenAgent&Name=' + szName;
Brendon Upson webWise Network Consultants http://www.wnc.net.au
------- code -------
function getDBPath() { var pathname = window.location.pathname; var iPos = window.location.pathname.toString().toLowerCase().lastIndexOf('.nsf'); if(iPos>0) return pathname.substring(0, iPos+4);
return pathname; }
Reply
Re: Using JavaScript to get the path
Hey, this proofs that you ARE smarter than Lotus (if that says soemthing). At least up to Release 5.0.4 (didn't check any recent version) they forgot the to LowerCase method when using some similar stuff in their WebMail template...
Still I feel that in general calculating URLs is and should be a server's, not a client's task. And as I don't see any real drawbacks, I'll probably stick to the DBPath field method.
Reply
Re: Using JavaScript to get the path
Reply
DOLS problem with this?????
I think I set this up the way you said. I found the DOLS didn't want to work anymore. It would get the first page, but none of the links, graphics or CSS worked. I think this is because of the port 89 part of it.
http://127.0.0.1:89/Sub_0/members/dancytron/ObieDiscuss.nsf/
Or maybe I just screwed it up.
Reply
fix seems
add server_port field with same settings as other fields (I started with subform in SVG database from last week).
Head formula is then
"<base href=\"http://" + Server_Name +@If (Server_Port = "80"; NULL; ":" +Server_Port) + "/" + DBPath + "/\" />" + @NewLine + "<link rel=\"stylesheet\" href=\"global.css\">" + "<Title>" + PageTitle + "</Title>"
Reply
Show the rest of this thread
Server Port
Hi Jake,
Sometimes (intranet) port settings are different for servers. Here is some code to check if a webserver is not using the default port 80:
Create a CFD field called Server_Port, value: Server_Port
change the base href formula in:
addServerPort := @If( Server_Port <> "80"; ":" + Server_Port; "" );
"<base href=\"http://" + Server_Name + addServerPort + "/" + DBPath + "\" />");
cheers,
Noel
Reply
Great tip
Great tip. I've a javascript based application that drawes graphs based upon some backend data from Domino with somewhere in excess of 2000 single pixel gifs (I know its dirty, but I love dirt). After implementing the <base> tag, the raw size of the page was reduced from 239 kb to 158 kb.
Reply
https and base href=
With an ssl secured database I was receiving the message " this database contains both secure and unsecure items". I added a computed field for cgi variable HTTPS and changed the code to <base href=\"http" + @If(HTTPS="ON";"s";"") + "://" + server_name + "/" + DBpath + "/\">";
It seems to work fine now.
Reply
What works for me
I found the newer @WebDbName formula also works great.
"/" + @WebDbName + "/"
Database Elements Example:
<img src=\"" + "/" + @webdbname + "/image.jpg" + "\">
Document Attachment Example:
<img src=\"" + "/" + @webdbname + "/" + @subset(@Viewtitle;-1) + "/" + @text(@DocumentUniqueID) + "/$FILE/" + "image.jpg" + "\">
Reply
Really great tip !
Your article helped me to save so much time ! ! !
Thanks so much ! !
Reply