Notes: Hide-When Formel in Mails

16. Januar 2012 Posted by airwolf89

Heute hatte ich mal wieder eine meiner wilden Ideen. Ist es möglich in E-Mails Hide-When Formeln zu benutzen?

Die Antwort: Ja, ist es!

Es ist sogar ziemlich einfach. Man muss nur den gewünschten Text markieren, rechtsklicken und die Hide-When Formel, wie gewohnt, eintragen. Der Text wird dann entsprechend der Bedingung versteckt.

Dabei gibt es natürlich einiges zu beachten.

1. Die Formel wird vom Domino Server computed, d.h. das funktioniert auch bei externen Mails. Wenn z.B. ein Web.de Account die Mail bekommt und die Bedingung wird auf dem Server als True berechnet, so wird derjenige diesen versteckten Text nie zu Gesicht bekommen. Da die Formel auf dem Domino Server berechnet wird funktioniert das ganze in externen Mails nur begrenzt. Will man z.B. dass eine bestimmte Person den Text nicht sieht, so muss man aufpassen wie man die Bedingung formuliert, denn die Formel wird mit dem Namen des Servers berechnet, dementsprechend wird das extern nicht so funktionieren wie man das beabsichtigt hatte.

2. Bleibt die Mail innerhalb eines Lotus Notes Systems, so wird die Formel nur über den Text gelegt, wenn man sich das Body-Feld, beispielsweise mit dem DocViewer von Domiclipse, ansieht, so steht dort der Text über dem die Formel liegt.

3. Es ist möglich diese Formel auszuhebeln. Schreibt man beispielsweise folgenden Text in eine Mail:

Test 1
Test 2
Test 3

und versteckt Test 3, so kann man wenn man den Cursor hinter Test 2 platziert und ENTF drückt den versteckten Text eine Zeile höher nehmen, wobei die Hide-When Formel ungültig wird. Das allerdings nur bei internen Mails, weil der Text bei externen Mails niemals auf dem Zielserver ankommt.

 

Jetzt bleibt noch die Frage: Wozu das ganze eigentlich?

Bei uns in der Firma gibt es eine Regelung dass an interne Kollegen eine gekürzte Fassung unseres Mail-Footers gesendet werden soll und nur an externe Kunden der volle Mail-Footer mit dem ganzen rechtlichen Geraffel, einerseits um Speicherplatz auf den Mailservern zu sparen (Ich hab’s hochgerechnet, beläuft sich auf mehrere 100GiB pro Jahr) und andererseits um die armen Kollegen mit BlackBerry nicht zu überfordern (nur eine Vermutung von mir ).

Durch dieses kleine Feature ist es mit ein paar weiteren Tricks möglich das einzurichten, sodass der der arme, sowieso schon mmit Notes überforderte User nicht auch noch eine Signatur auswählen muss.

Dass man mit diesem Trick seinen Kollegen einen kleinen Streich spielen kann ist natürlich vollkommen ausgeschlossen, sowas würde auch niemand von uns tun, dazu sind Notes-Entwickler viel zu ehrlich =)

Ein viel interessanterer Zweck ist natürlich Code-Injection. Ich habe das bisher noch nicht testen können ob dies möglich ist und inwieweit das zwischen Notes-Servern unterschiedlicher Domains möglich ist und welche Spuren derjenige hinterlässt. Auf jeden Fall wäre das aus meiner Sicht technisch möglich wenn man Schad-Code in der Hide-When Formel versteckt. Ich werde das in den nächsten Tagen mal testen und ein Update schreiben. Hoffen wir das beste.

Bleibt ehrlich =)


Lotus Designer: IBM Support Assistent

16. Januar 2012 Posted by airwolf89

Heute habe ich mir mal ein paar Funktionen im Domino Designer angeschaut und dabei ein nettes verstecktes Feature gefunden: Den IBM Support Assistenten.

Man erreicht ihn über die Perspektiven im Designer:

Dann findet man ihn in der Liste:

Nun gelangt man zu einer Suchmaske auf der man in bestimmten Seiten nach Stichworten suchen kann:

So kann man während der Entwicklung bequem auf die IBM Ressourcen (& Google) zugreifen. Öffnet man einen der Links, so öffnet sich der Standard-Browser des Systems mit der angegebenen Ressource.

Weiterhin kann man über die erweiterte Suche noch die Art der Information einschränken die man haben möchte.

Ob, und wenn ja wie, man weitere Suchziele hinzufügen kann habe ich noch nicht herausgefunden, aber ich halte euch auf dem Laufenden.


Statusbericht

31. Dezember 2011 Posted by airwolf89

Tja Leute, nun hat’s mich dahingerafft. Die Sterne hatten Recht. Aber hier in der Hölle gibt es zum Glück auch schon Internet (die Telekom scheint überall zu sein… ) Habe gerade mit dem Boss gesprochen, ich wurde zur ewigen Arbeit mit XPages verdammt, also wirds auch weiterhin noch neue Artikel geben. Auf jeden Fall wünsche ich euch da oben ein frohes neues Jahr, vor allem Gesundheit. Bleibt so wie ihr seid.

 

Grüße aus der Hölle

Matthias


Ankündigung: Anstehendes Ende dieses Blogs…

30. Dezember 2011 Posted by airwolf89

Tja Leute. Ich habe heute mein Horoskop gelesen, und die Sterne lügen nicht.

Das große Postillon Horoskop für 2012

Leider bin ich vom Sternzeichen Löwe, das heißt… naja… ihr könnts ja nachlesen…

War auf jeden Fall schön diesen Blog zu schreiben. Aber vielleicht geht’s ja weiter. Eventuell gibt’s da oben (oder unten, wir werden sehen) ja auch mittlerweile Internetanschluss. Falls ja werde ich euch natürlich berichten was euch irgendwann mal dort erwarten wird. Falls es keinen Internetanschluss gibt…. Macht’s gut, und danke fürs lesen…

Euer Matze


Tools: Mozilla Aurora 11

28. Dezember 2011 Posted by airwolf89

Mozilla hat mit dem Aurora 11 eine, meiner Meinung nach, sehr schöne Version herausgebracht. Ich bin bisher noch nicht dazu gekommen ihn komplett zu testen, aber eine Funktion ist mir direkt ins Auge gefallen. Im Paket der Web-Developer Tools gibt es im Untersuchen-Werkzeug eine 3D-Funktion. Damit kann man sich seine Seite in 3D anschauen. Alle Elemente werden als Box gestapelt angezeigt. Dadurch kann man sehr intuitiv und einfach bestimmte Konstrukte und Elemente genauer anschauen, ohne sich durch Code durchwühlen zu müssen oder zu hoffen dass man mit der Maus das richtige Element erwischt, was besonders bei stark geschachtelten Konstrukten schwierig und zeitaufwändig sein kann. Natürlich beinhaltet das Paket nicht alle Funktionen die man mit dem Firebug oder den Web Development Tools (das Plugin) hat, aber als Ergänzung definitiv zu empfehlen.

Hier ein Screenshot als erster Eindruck von der Funktion:


Allgemein kann ich diese Version bisher sehr empfehlen, alle Plugins welche ich, privat oder auf der Arbeit, verwende, funktionieren problemlos in der neuen Version. Auch fällt die allgemeine Performance positiv auf. Das ist natürlich nur mein rein subjektiver Eindruck.

Bekommen kann man die Version hier.


XSnippet: ViewEntries ohne repeat-control in XPage durchloopen

20. Dezember 2011 Posted by airwolf89

Hallo,

ich hatte heute ein kleines Problem. Die Lösung habe ich als XSnippet veröffentlicht und werde ich hier etwas genauer erklären:

Problem war das folgende:

Ich hatte ein kleines Modul, welches die Bilder von diversen Mitgliedern einer Community anzeigen sollte. Das ganze sollte auch immer zufällig passieren, also dass ich an jeder Position immer andere Mitglieder sehen würde. Leider war es aufgrund der Struktur und des Aufbaus des Moduls nicht möglich ein repeat-control zu verwenden. Daher folgender Lösungsansatz:

Speichere einen Iterator im Hintergrund und greife an jeder benötigten Stelle mit iterator.next() darauf zu.

Ich habe das mal ausprobiert, und siehe da, es funktioniert und ist performanter als gedacht.

Im DataContext der XPage (so etwas wie eine lokale Variable einer XPage, auf welche ich einfach per SSJS zugreifen kann) compute ich meinen Iterator, so zum Beispiel:

var tempTreeMap:java.util.TreeMap = new java.util.TreeMap();
var tempColl:NotesViewEntryCollection = allActiveUsers.getAllEntries();
var tempEntry:NotesViewEntry = tempColl.getFirstEntry();
var tempCollection:java.util.Collection = null;

while (tempEntry != null) {
tempTreeMap.put(@Unique(), tempEntry.getDocument());
tempEntry = tempColl.getNextEntry(tempEntry);
}

tempCollection = tempTreeMap.values();
return tempCollection.iterator();

Somit liegt schonmal ein Iterator im Hintergrund. Nun kann ich in jedem verwendeten image-control mit iterator.next() darauf zugreifen und mir das Dokument holen, welches in der dazugehörigen TreeMap liegt um mir die URL des Bildes zu berechnen.

Natürlich muss abgefangen werden ob es noch ein nächtes Element im Iterator gibt auf welches ich zugreifen möchte, um diese kleinen hässlichen Null-Pointer Exceptions zu vermeiden.

Hier das Snippet:
XSnippets


Stolperfalle: view.getEntryCount()

16. Dezember 2011 Posted by airwolf89

Mal wieder eine kleine Stolperfalle.

Situation war folgende: In einer Anwendung gibt es so etwas wie eine Community, jeder kann Fragen einstellen, diese können kommentiert werden usw. Das ganze soll in verschiedenen Gruppen ablaufen. Nun kann man sich entscheiden ob man die Frage öffentlich (für alle Gruppen sichtbar) oder privat (nur für meine Gruppe sichtbar) einstellen will.

Dazu musste es eine Ansicht geben, wo ich hin und her schalten kann, welche Kategorie ich sehen will.

Dazu habe ich den Viewnamen meiner Datasource berechnen lassen, je nach URL-Parameter um entsprechend die View mit den öffentlichen Dokumenten oder die mit den privaten Dokumenten abzufragen.

Auch musste innerhalb meines Codes abgefragt werden ob sich ein Dokument in der View befindet was angezeigt werden kann, um hässliche Null-Pointer Exceptions zu vermeiden.
Die Lösung dafür war denkbar einfach: myView.getEntryCount()

Damit habe ich abgefragt ob die Anzahl der Einträge 0 ist oder nicht und habe entsprechend die jeweiligen Blöcke angezeigt.

Nun habe ich mir noch jemanden zu testen  , der leider eine Null-Pointer Exception an dieser Stelle bekommen hat. Mit ein paar Printouts fiel uns auf, dass getEntryCount() bei ihm nicht 0 zurückgibt, obwohl es das hätte tun müssen.

Lange Rede kurzer Sinn: getEntryCount() ignoriert sämtliche Lese- und Autorenfelder. Bzw. wird der Befehl wahrscheinlich mit den Rechten des Servers ausgeführt, welcher die Dokumente scheinbar sehen darf.

Die bessere Lösung ist es myView.getFirstDocument() == null abzufragen. Dort bekommt man nur die Dokumente auf die man zugreifen darf.

 

 


XPages: Stolperfalle Recycling

2. Dezember 2011 Posted by airwolf89

Gestern hatte ich mal wieder eine schönes „Feature“ gefunden.

Aufgefallen ist dass eine XPage mit einer Null-Pointer Exception abgestürzt ist. Scheinbar war eine View-Datasource, dessen erstes Dokument ich mir holen wollte, nicht vorhanden.

Einige print-outs ergaben dass der Code mehrmals durchlaufen wird, was bei XPages, welche Editable Areas (Callbacks) benutzen, häufiger zu beobachten ist. Allerdings war die View bei Durchlauf 1 bis 3 noch vorhanden, beim 4. Durchlauf hatte es dann geknallt.

Nach vielen Hin und Her testen stand dann die Ursache fest. Ich hatte in einem Custom Control etwas eingebaut, wo auf eine Funktion in einer SSJS-Scriptlibrary aufgerufen wurde. In dieser Funktion wurde eine View referenziert und später wieder recycled. Normalerweise wäre hier kaum ein Zusammenhang zu erkennen. Aber, die Methode und meine XPage benutzten die gleiche View. Scheinbar ist es so, dass Designelemente nicht mehrfach referenziert werden.

D.h. wenn ich an vollkommen unterschiedlichen Stellen z.b. die gleiche View referenziere und auch nur eine davon recycle, dann werden alle Referenzen auf dieses Designelement gelöscht und es regnet entsprechende Null-Pointer Exception.

Die Lösung dieses Problems war denkbar einfach: Wir nahmen einfach das recycling aus dem Code. Normalerweise muss man auch nicht recyclen, da Domino das im Grunde selbst kann. Lediglich bei großen Schleifen wo viele Dokumente durchgeloopt werden sollte man über recycling nachdenken. Auf jeden Fall muss man aber darauf achten wie ich Designelemente referenziere um mir nicht den Ast abzusägen auf dem ich sitze.


XSnippet – Sortierte Ergebnisliste aus Volltextsuche

25. November 2011 Posted by airwolf89

Hallo,

seit kurzem bin ich auch bei OpenNTF im Projekt der XSnippets aktiv.

XSnippets ist ein Projekt wo jeder zugelassene Entwickler kurze Code-Schnipsel hochladen kann um anderen XPages-Entwicklern das Leben ein wenig leichter zu machen.
Ich finde dies eine sehr schöne Idee, vor allem da man schnell mal ein Stück Code hochladen kann anstatt ganze Projekte zu veröffentlichen.

Auf jeden Fall hier mein erster Beitrag dazu:

Get sorted resultlist of fulltext search

Dieses kleine Snippet ist dazu da, um auf eine Datenbank eine Volltextsuche durchzuführen und die Ergebnisliste sortiert, nach einem Feld zurückzugeben. Das funktioniert natürlich nur, wenn alle Dokumente in der Ergebnisliste dieses Feld besitzen, bzw. der selben Form zugeordnet sind.

Erweiterungsvorschläge nehme ich gern entgegen, auch wenn es bei XSnippets leider noch keine Funktion zu geben scheint seine eigenen Snippets zu bearbeiten.

Anbei auch der Link zu einem anderen Snippet, dessen Inhalt ich bereits in diesem Beitrag gepostet hab.


XPages: Useability – Parameter mit Aliaswerten in Custom Controls

15. November 2011 Posted by airwolf89

Heute mal ein kleiner Tipp, welcher die Useability von Paremetern in selbst gebauten Custom Controls erhöhen kann.

Man kann für Custom Controls ja Parameter definieren, dies tut man in den Eigenschaften des Elements xp:view (root-Element des Controls) unter Property Definition.
Dort hat man die Möglichkeit für einen Parameter den Editor (die Art wie man bei der Einbindung den Parameter angibt) auf ComboBox zu setzen und dort mehrere Einträge mitzugeben, welche man dann bei der Einbindung in eine XPage oder ein anderes Custom Control auswählen könnte.

Natürlich möchte man es sich und anderen möglicht bequem machen und dort sprechende Vorgabewerte eintragen, damit man weiß was diese jeweils bedeuten. Dies ist auf der anderen Seite natürlich schlecht im Programmcode handlebar. Daher kann man einfach Aliaswerte benutzen.

Hier ein Beispiel:

Parameter 1 wird im Menü über eine ComboBox ausgewählt. Folgende Vorgabewerte werden angeboten:

0|Wert 1
1|Wert 2

Hier muss man mit dem Alias leider anders herum arbeiten als man es von Notes her gewohnt ist. Der Wert vor der Pipe („|“) ist der Wert der tatsächlich übergeben wird, den man dann auch mittels compositeData azurückgegeben bekommt. Der zweite Wert dahinter wird dem User im Menü angezeigt.
Achtung: Dies ist lediglich eine optische Geschichte, d.h. der Aliaswert wird nur im Menü verwendet. D.h., wenn man den Parameter mit Aliaswerten berechnen möchte, so muss man wieder den richtigen Wert, welcher vor der Pipe angegeben wurde benutzen und zurückliefern.

Lediglich eine kleine optische Spielerei, erhöht aber den Komfort beim Benutzen von eigenen Custom Controls.


Notes: Attachments in Subforms

14. November 2011 Posted by airwolf89

Mal wieder trieb mich Notes in den Wahnsinn, diesmal mit Attachments in RichText-Feldern.

Das Problem war, ich hatte einige Forms, welche im Grunde exakt gleich ausgesehen haben, daher mussten Subforms her.
Ich hatte in jeder Form eine Subform, welche das Layout abbildete und dann noch jeweils eine Subform für den Datenteil der jeweiligen Form und noch eine für die Attachments. Da die Attachments nicht in jeder Form auftauchen sollten, war die entsprechend computed.

Da war dann das Phänomen dass ständig unterhalb der Form noch die Attachments sichtbar waren, also nochmal separat aufgelistet wurden. Sehr nervig.
Normalerweise tritt dieses Phänoment nur auf, wenn das Dokument Attachments enthält, aber das Feld wo es drin liegt, ausgeblendet ist. Das war aber gar nicht der Fall.

Nach einigem hin und her probieren stand dann die Ursache fest. Das Problem war einfach, dass die Subform computed war. Scheinbar wird Notes intern erst dieser Mechanismus durchlaufen, also prüfen ob das RichText Feld da ist, wenn ja dann zeige es dort an, wenn nicht, dann zeig es unterhalb der Form an. Erst danach werden dann die Subforms berechnet. Von daher ist es vollkommen egal ob das Feld angezeigt wird oder nicht, Notes geht erstmal davon aus dass das Feld potentiell nicht angezeigt werden könnte und packt sie zur Sicherheit nochmal unter die Form. Wenn man die Subform so wie sie ist direkt einbaut funktioniert alles wie es soll. Statt der computed subform habe ich dann entsprechend Hide-When Formeln benutzt, dort tritt das Problem seltsamerweise nicht auf, die werden scheinbar vor dem Attachment Mechanismus berechnet.


Notes: Ein- und Ausblenden von View-Actions

9. November 2011 Posted by airwolf89

Heute mal ein kleiner Tipp für Standard-Notesclient Anwendungen.

Ich hatte die Anforderung bekommen dass in einer kategorisierten View die Actions ein- und ausgeblendet werden sollen, je nachdem ob ich eine Kategorie oder ein Dokument ausgewählt habe. Langes Suchen brachte nichts und auch ein Kollege war der Meinung es geht nicht. Ein anderer Kollege brachte dann aber doch die Lösung:

In den View-Einstellungen gibt es eine Option namens „Evaluate actions for every document change“. Das funktioniert deshalb weil auch ein Wechsel der Selektion als Change aufgefasst wird.
Schlussendlich muss man in der Hide-When Formel nur noch auf die Form abfragen. Wenn sie leer ist verstecke den Button, wenn nicht dann zeige ihn an, denn Kategorien haben keine Form.

Darüber hinaus kann man so natürlich noch sehr flexibel entsprechende Actions anzeigen, beispielsweise wenn man in der View mehrere Forms hat.


XPages: Zeitzonen anzeigen

8. November 2011 Posted by airwolf89

Einer geht noch:

Mittel Serverside Javascript kann man relativ bequem die jeweilige Zeitzone anzeigen lassen. Das ganze geht mit dem Befehl:

context.getTimeZone().getDisplayName();

Wenn man nun wie ich in Deutschland lebt, so kommt man in den Genuss der Sommer- und Winterzeit, oder wie es im englischen heißt, die Daylight-saving-time.

Ich hatte die Funktion benutzt und alles hatte auch super funktioniert, bis dann die Zeitumstellung kam und die Zeitzone nicht von CEST auf CET umgestellt wurde.

Die Lösung ist denkbar einfach. Es gibt einen Parameter, welcher steuert ob Sommer- oder Winterzeit angezeigt wird, dies ist der erste (den ich wohl leider übersehen hatte). True bedeutet wir haben Sommerzeit, False bedeutet dass wir Winterzeit haben.

Wie kann man nun überprüfen ob wir Sommer- oder Winterzeit haben? Ganz einfach, mit der Methode isDST des NotesDateTime Objekts. Das liefert schon einen boolean Wert zurück, welchen man dann in die Funktion einsetzen kann.


XPages: Header setzen

8. November 2011 Posted by airwolf89

Weil heute Dienstag ist gibt’s gleich noch einen kleinen Tipp hinterher.

Es gibt ja die Möglichkeit meta-header zu setzen. Um dies zu tun hat man 2 Möglichkeiten.
1. Über die Properties der XPage eine Ressource vom Typ metaData setzen (siehe Bild)
2. Im BeforeRenderResponse-Event ein paar Zeilen Code einfügen, welche in etwa so aussehen:

try {
   var response = facesContext.getExternalContext().getResponse();
   response.setHeader("Expires", -1);
   response.setHeader("Cache-Control", "no-cache");
   response.setHeader("IE=EmulateIE7", "X-UA-Compatible");
} catch (e) {}

Normalerweise würde man denken, wo man es setzt ist doch. Leider ist es das nicht…

Manche Header können nicht über die erste Variante gesetzt werden. Ich weiß nicht genau zu welchem Zeitpunkt er über die konfigurative Möglichkeit die Header einfügen möchte, auf jeden Fall sind sie schon da!

D.h. wenn ich beispielsweise einen Header IE=EmulateIE7 setzen möchte, wie in einem früheren Post von mir als Workaround beschrieben, dann sollte man das über Variante 2, also im BeforeRenderResponse lösen, da ansonsten vom Browser die Warnung angezeigt wird, dass dieser Header ignoriert wird weil der Doctype schon gesetzt wurde. Fügt man ihn im Event ein, so wird keine Meldung angezeigt.

Im übrigen, wer schnell mal nachschaut, ja, der Header steht trotzdem im Quellcode, er wird scheinbar nur ignoriert weil er zu spät gesetzt wurde.


XPages: FileUpload Control – Filenamen ersetzen

8. November 2011 Posted by airwolf89

Heute nur ein kleiner Tipp.

Ich hatte das Problem dass bei einer Anwendung ab und an die Uploads fehlgeschlagen sind. Benutzt habe ich die Standard FileUpload Controls.

Leider war der Fehler nicht zu 100% nachvollziehbar, von daher musste ich ein wenig herum experimentieren.

Eine mögliche Ursache für die Fehler waren Umlaute im Dateinamen.

Den kann man über eine Standardfunktion des Controls, nämlich „Replace file name of uploaded file with the following name“
Dort kann man auch per Javascript einen namen mitgeben. Das würde mit folgendem Code funktionieren:

var path:com.ibm.xsp.http.UploadedFile = getComponent("fd_file").value;
var newPath:string = path.getClientFileName();

newPath = newPath.replace("Ä", "ae");
newPath = newPath.replace("Ö", "oe");
newPath = newPath.replace("Ü", "ue");
newPath = newPath.replace("ä", "ae");
newPath = newPath.replace("ö", "oe");
newPath = newPath.replace("ü", "ue");

return newPath;

Besonders ist hier nur die Klasse com.ibm.xsp.http.UploadedFile. Die ist natürlich, in guter IBM-Manier, nicht dokumentiert. Sie bietet einem schöne Zugriffsmöglichkeiten auf das soeben hochgeladene File.

Hier ein weiterer Artikel zu diesem Thema: XPagesWiki