Domino Upgrade

VersionSupport end
5.0
6.0
6.5
7.0
Upgrade to 8.5x now!
(see the full Lotus lifcyle) To make your upgrade a success use the Upgrade Cheat Sheet. Contemplating to replace Notes? You have to read this!

Search

Reference

1. Learn XPages online
2. Communicate with IBMers and Lotus Experts using Sametime

About Me

I am the "IBM Collaboration & Productivity Advisor" for IBM Asia Pacific. I'm based in Singapore.
Reach out to me via:
Follow notessensei on Twitter
(posts)
Skype
Sametime
IBM
Facebook
LinkedIn
XING
Amazon Store
Amazon Kindle

Mobile tag

Twitter

Languages

Other languages on request.

Visitors

Useful Tools

Get Firefox
Use OpenDNS
The support for Windows XP is coming to an end and has . Time to consider an alternative to move on. sounds like a lot of time, but, like an object in a mirror, it is closer than you think.

« Countries (re)visited | Main| Domino Design Code Injection - Part 2 »

Domino Design Code Injection

QuickImage In an earlier entry I discussed how to maintain custom system databases. It works well when you add design elements or change them wholesale. However it doesn't work very well when you tweak design elements. Something like: adding one action in a form or using a different subform for a specific task. Once an updated system template is available, you have to go back and recreate all your changes in your template.
This entry discusses how to automate these little fixes. There are a number of moving parts involved:
  1. Export the design element using DXL. (You might need to set NotesDXLExporter.RichTextOption = RICHTEXTOPTION_RAW to make sure the fidelity of forms is maintained)
  2. Locate the entry/replace point. The best mechanism for that is XPath
  3. Locate the new code. This could be as easy as provide a string with the XML Snippet to pointing to an existing design element elsewhere. (We would use XPath again)
  4. Perform the insertion/replacement. We will have the option: before/after/replace
  5. Write back your changes and test it
What type of code injections come to my mind:
  • Add an action to a form/view
  • Add a subform to a form
  • Replace a validation formula in a field
  • Insert a script library and a custom class into a form
  • Add a field at the top or bottom of a form (our favorite hidden fields $$Return anyone
Understanding DXL and XPath is key to make this work. As a Domino developer (and you are one? Otherwise all this might sound Greek and Latin to you) you have seen DXL and its description in the help file. XPath might be less familiar. In a nutshell: XPath is to XML what SQL is to relational data. When you develop XML Stylesheets (a.k.a. XSLT) you use XPath selectors to define your template matches. XPath is a set language, so you better remember your kindergarden days (give me all shapes that are blue, triangle and big). It is easy to get an overview and to get started and can get as complex as you can take it. One little caveat (you see Latin is creeping it): XPath is case sensitive
Some simple examples:
  • * selects ANY element.
  • / selects the root element, basically before any tags in the XML
  • /database/form/actionbar selects the actionbar elements in all forms in our XML
  • /database/form[1]/actionbar selects the actionbar element in the first form in our XML
  • /database/form[@name='Message']/actionbar selects the actionbar element in the form Message in our XML
  • /database/form[@name='Message'] //field[@name='Subject'] /code[@event='defaultvalue'] /formula Select the default value formula for the field "Subject". Please note the double slashes in front of the field. They are intentional. One slash says: a child, two slashes says any decendant down the document. Also: no spaces before/after the slashes. They are here for readablitity only.
  • //field[code/@event='inputvalidation'] Any field that has an input validation formula
You get the idea. You want to have a good XML editor.
First you need a routine that can pull out a design element and write it back. Here is the example for a form:
Sub InjectCodeIntoForm(formName As String, xPath As String, codeSnippet As String) 'Errorhandling omitted for clarity Dim s As New NotesSession Dim db As NotesDatabase Dim f As NotesForm Dim out As NotesStream Dim ex As NotesDXLExporter Dim importer As NotesDXLImporter Dim col As NotesNoteCollection 'The strings holding the DXL Dim rawDXL As String Dim resultDXL As String Set db = s.CurrentDatabase 'Create a Note collection and add the form Set col = db.CreateNoteCollection(False) Set f = db.GetForm(formName) col.BuildCollection Call col.Add(f) 'Create the exporter and run the stuff out Set ex = s.CreateDXLExporter Set out = s.CreateStream ex.RichTextOption = RICHTEXTOPTION_RAW 'This is to get rawitems for untranslatable stuff ex.ValidationStyle = VALIDATIONSTYLE_NONE 'To make sure we don't generate a schema reference Call ex.setinput(col) Call ex.setOutput(out) ex.process 'Reset the stream and manipulate the DXL out.Position = 0 rawDXL = out.ReadText resultDXL= injectCode(rawDXL, xPath, codeSnippet) 'Write it back out.Truncate Call out.WriteText(resultDXL) out.Position = 0 Set importer = s.CreateDXLImporter 'Having the right importer options is important importer.CompileLotusScript = True importer.ReplaceDBProperties = False importer.ReplicaRequiredForReplaceOrUpdate = True importer.ACLImportOption = DXLIMPORTOPTION_IGNORE importer.DesignImportOption = DXLIMPORTOPTION_REPLACE_ELSE_IGNORE 'We only want to update the current form importer.DocumentImportOption = DXLIMPORTOPTION_IGNORE 'This is for design only importer.ExitOnFirstFatalError = False 'Standard import execution Call importer.setInput(out) Call importer.setOutput(db) On Error Resume Next Call importer.Import Msgbox importer.log End Sub
This LotusScript was converted to HTML using the ls2html routine,
provided by Julian Robichaux at nsftools.com.
Now we need a pice of code that can do the transformation of the DXL. Unfortunately the LotusScript XML Parser is lacking, so we use some Java code to perform this step. After creating the class (without parameters, for LS2J comfort, we need to set the DXL as Document and then call injectCode with 3 parameters: xPath expression, codeSnippet to insert (must be an XML fragment) and insertion type (before/after/replace). See Part 2 for the Java code.

Comments

Gravatar Image1 - Thanks! I once had problems with XPath and found a couple of video tutorials on the issue. When the problem with XPath was settled, I could go futher learning in detail your articleEmoticon

Gravatar Image2 - Thanks! Great article, but i have one problem. I need to change design of mail\username.nsf file which located on the server. So i cant change UI for it (Under admin account it works). May be it because of my access level? Anyone knows how to solve this problem?
Or what permission needed for such action?

Post A Comment

Please note: Comments without a valid and working eMail address will be removed. This is my site, so I decide what stays here and what goes.

:-D:-o:-p:-x:-(:-):-\:angry::cool::cry::emb::grin::huh::laugh::rolleyes:;-)

Disclaimer

This site is in no way affiliated, endorsed, sanctioned, supported, nor enlightened by Lotus Software nor IBM Corporation. I may be an employee, but the opinions, theories, facts, etc. presented here are my own and are in now way given in any official capacity. In short, these are my words and this is my site, not IBM's - and don't even begin to think otherwise. (Disclaimer shamelessly plugged from Rocky Oliver)
© 2003 - 2012 Stephan H. Wissel - all rights reserved as listed here: Creative Commons License
Unless otherwise labeled by its originating author, the content found on this site is made available under the terms of an Attribution/NonCommercial/ShareAlike Creative Commons License, with the exception that no rights are granted -- since they are not mine to grant -- in any logo, graphic design, trademarks or trade names of any type.