Making a Global Resources DB
Chances are you have worked on at least one intranet by now. Chances are that this was as part of a team of developers. How did you find this? Personally I like it. Never is there a better chance to share knowledge and ideas. Saying that though, there are also the downsides.
The problem:
The problem comes when your team starts to use Style Sheets (CSS) to control the feel of the intranet, JavaScript to program it and images for the look. It's not long before each separate database that makes up the intranet has numerous different versions of these resources because everybody has their own version of everything. Managing these can be a nightmare as everybody has their preferred method of storing this information.
Let's look at what often happens when using CSS. The idea with using CSS is simple: keep all the style separate from the design and you only need to change it once in order to update the whole site. This doesn't work when everybody has their own version of the stylesheet in each of their databases. The person in charge of the look will have to tell them all about the change to the CSS and get them all to update each of their databases. This is when the advantages of using CSS are almost lost.
The solution:
Whenever I join a team that is not doing what I'm about to describe I try my best to convince them they should be. This normally starts with me saying:
Would it not be better if you had one central database that was just there to store the things like stylesheets that get used all over the place? This way we can manage the look of the whole intranet from one place!
This doesn't always go down well. Most often I suspect because people don't like change....
When the idea gets received with open arms I would start adding a Global Resources database to the intranet. Here's how.
Creating the Resources DB:
The first thing to do is create an empty database. No need to use a template as this DB is going to be used simply to add design elements to. Call it something like Global Resources. The file's name is irrelevant as you shall see later.
With this new database open in Domino Designer you can start adding all the things to it that are generic to all the databases that make up your intranet.
- Add all images to the Image Resources section
- Add the contents of all the CSS and JavaScript files in to Page design elements that are Treated as HTML (give them names that end in .css and .js)
- Add anything else like Java Applets as required
- Set up the ACL as you deem necessary to ensure that the look of the site is safe
We now need to alter all databases so that they point to this new Resources area when they want to load these global elements. To do this we need to know the Replica ID of the Global Resources DB. Easiest way to do this is through a Design Synopsis:
On the second tab click on "Replication" and click "OK". Toward the top of the next page you see there will be the Replica ID of the database. Copy this and put it somewhere safe for the time being.
In any DBs where you want to use these resources you now need to create a Shared Field that is Computed For Display and called ResourcesRepID. Add the above Replica ID you found as this field's Value after removing the colon (:) from the middle.
Hopefully, if you've listened to anything I've said over the past year, your database will have CommonFields Subform that exists on EVERY form. This is where you should add the new Shared Field.
Now, when you want to link to anything in the Resources DB you would create a URLs in your formulas like:
"<script type=\"text/javascript\" src=\"/" + ResourcesRepID + "/CommonScripts.js\"></script>"
"<link rel=\"stylesheet\" href=\"/" + ResourcesRepID + "/global.css\">"
"<img src=\"/" + ResourcesRepID + "/companyLogo?OpenImageResource\" />"
The idea of using the Replica ID rather than the DB's file path is simple. The Replica ID is less likely to change that the path. You can also replicate this database to other servers where it may have different file paths.
Just one remark...
Hi Jake,
As a conservative "centralizer", I greatly share your thoughts here. I have used this technique a lot and I am really happy about it when you need to change things like a CSS. Change once, see it everywhere ;-)
The only drawback with image resources is that you cannot centralize them when creating forms/pages for the notes client. You can only insert image resources from the db you are working in (this limit is gone in R6, thanks Iris !).
Therefore, one enhancement I used when applying this technique (when still using R5) and creating new db's, was to combine it with templates. Create a template with the image resources and copy/paste them in the new db. A dialog box will appear and ask you if you want future changes to be propagated to the new db.
I only apply this technique for centralized image resource db's. That way, they are actually stored in each db and can therefore be used for notes client purposes while you are still able to manage them centrally in the template db.
As for CSS and JS libraries, I use your technique as described in your article, since these are only used for the web and not for the notes client.
So, everyone that has read your article and doesn't apply the technique yet, should start doing so right now. It greatly enhances efficiency when working when working on larger projects. So, Jake, once again, great article ! I just wanted to add my 2 pennies...
Also, these tips are to be discarded when using R6, since Lotus/Iris/IBM now provide us with native support to share resources across db's, which is an excellent feature in R6. Great job, Iris !
Best regards, Jurgen Van de Moere
Reply
Re: Just one remark...
As a step further, it may make sense to assign each resource to a database or databases, and distribute each element to their assigned database(s) with an script when a new element is added or modified. It would approve performance under certain circumstances. By the way does anyone know how to add images to the repository though the web.
Reply
Show the rest of this thread
Re: Just one remark...Templates
I actually prefer not to have images spread across my db's, even if they do inherit from a template. Instead I just use computed text to load the image from the central resources database, the location of which is stored in a profile db i.e.
db:=resdb; view:="vimg"; src:="rhtop-brown.jpg"; type:=@BrowserInfo( "BrowserType" ); prefix:=@If(type="Netscape";"/";"\\"); "{<IMG SRC=\"" + prefix + db + "/" + view + "/" + src +"/$FILE/" + src + "\" border=0>}"
Ed's note: replace {}s with []s
Reply
Talking from experience
Dear mr Howlett, I enjoyed greatly reading your artice on the subject of a Global Resources DB. I have also been in a similar problem on the last project I worked on. It does seem that no matter what you do, people always want you to work the way that they are working, and this can cause many issues.
A central resource such as this can be most usefull, but it also has to be policed correctly, maybe by a 'stylesheet police' person, to make sure that no one is abusing the system.
Thanks for a gr8 article.
Reply
Re: Talking from experience
My recommandation would be to put stylesheet, image, etc... in the html directory and access them directly. It's faster and so much easier when you need to build the url of the ressource. It's true that when you have multiple web server when you need to have your data, it's a little more complicated and you loose the replication advantage but it's always possible to build a "deploy ressource DB" where you would attach the file and then run an agent which would detach the file in the html directory.
The good thing is that RNext will have the option on every ressource to deploy it automaticaly.
Reply
Local override/compliment of CSS
We use Jake's excellent method but also create a local version of the style sheet. Because it loads after the central style sheet and we give the page the same name, anything on the local page will overide the central style. We find this extremely useful. eg: "<link rel=\"stylesheet\" href=\"/" + ResourcesRepID + "/global.css\">" + @NewLine + "<link rel=STYLESHEET HREF=\"/" + DBPath +"/global.css\">";
Reply
Re: Local override/compliment of CSS
Thanks for that James. Something I forgot to mention in the article. The C of CSS is of course "Cascading", meaning that the styles that are applied cascade from the top to the bottom. Those at the bottom being the more important.
Something else worth noting is the use of the "!important" notifier on a class to let the browser know that this is to take precendence over all those defined after it: [<span class="css">] body{ font-size: 16pt !important; } [</span>]
So, even if the body class gets redifined further down it still has this font size...
Jake "CodeMaster" Howlett
Reply
Replica ID
Hi Jake,
another cracking article, again. "you are spoiling us.":)
My query regards the use of the replica id. I would consider this a piece of data and would not like to hard code it.
I think maybe a custom data base profile form/document would be of use for this data with a field for rep id. Your shared field could compute on that value instead. That way if the replica id changed then it would not call for a design change (which gives version,upgrade and admin headaches) But all that required would be to edit a document, making admin of the db easier.
What do you think ? Regards ant.
Reply
Re: Replica ID
What's that they say about great minds thinking alike?
Great idea. This is the way I usually do it. All databases I create have a form called "Application Setting" that create document that hold anything like this. Then there is a view for looking up there settings. My ReplicaID field uses a lookup as I too hate to hard code.
I left it out of the article as it would have been even more long-winded....
Thanks for the feedback, Jake
Reply
Show the rest of this thread
simpler way? (untested) Re: Replica ID
I think I have a simpler solution, although I haven't tried this yet. It's just off the top of my head, so forgive me if it's hairbrained...
Why couldn't you put the shared field "ResourcesRepID" in the resources.nsf, and set resources.nsf to be a template, and then let all the other dbs inherit the changes of the shared "ResourcesRepID" field. I assume the resources.nsf db could calculate it's own replica ID?
Because design elements refer to templates by name (without any path), every database would get the shared field, which would have the correct replica id all the time, even if you replicated or copied all the databases to a new server or whatever.
(as far as an .nSf being a template, I'm quite sure I've done this without any problem.)
Please tell me if I'm mistaken about this working...
Reply
question: shared resources for object properties
Thanks for the cool article! My question is: is there any way to use such shared resources database to set objects properties (for example: table cell background image, form background, outline bullets,...). Would appreciate any hint how to master this problem in v. 6. I used the trick to declare all the resources directly in properties over folder button to a distinct database and then made replications of resource Db to all the needed locations and servers. But it demands that the resource database keeps its ID same forever. If it goes down the drain I have to declare all of the resources again....and that's baaaad! If anyone has any cool sugestions, please, up there is my addy. Regards from Slovenia, Boyzl
Reply