Friday, July 12, 2013

Pagelet Wizard - format dates

To format the dates you can use the PSFORMAT tag.

The tricky bit is working out where to apply the new tag, as the documentation (here and here) is unclear.

Look for the bit that says this. This is where it reads the results of the Query.
<xsl:template match="/queryresult/queryrows/row">

Then it will start to do the columns for each one and reference the xsl value-of command. e.g.
So if your date column is the fourth one in the query look for the 4th TD tag.
Surrounding the value of use the PSFORMAT tag. For example
      <td>
        <xsl:variable name="style4">
          <xsl:call-template name="cellthreshold">
            <xsl:with-param name="column_id" select="querydata[position()=4]/@fieldname"/>
            <xsl:with-param name="thisvalue" select="querydata[position()=4]/text"/>
            <xsl:with-param name="rowstyle" select="$rowstyle"/>
            <xsl:with-param name="rowstylepos" select="$rowstylepos"/>
          </xsl:call-template>
        </xsl:variable>
        <xsl:if test="not(starts-with($style4,';'))">
          <xsl:attribute name="style">
            <xsl:value-of select="$style4"/>
          </xsl:attribute>
        </xsl:if>
        <PSFORMAT TYPE="DATE" FORMAT="dd/MM/y" FORMAT_DEU="dd.MM.y">
          <xsl:value-of select="querydata[position()=4]/text"/>
        </PSFORMAT>
      </td>

I am pretty sure that the "position()=n" refers to the actual column in the query, so if the query columns are different to the pagelet wizard columns amend the number..

Tuesday, June 25, 2013

Pagelet wizard - use an Image as a URL

Normally you cannot embed links into URLs with the Pagelet Wizard, and although you can create custom XSL, the PTTP_PAGELET:Pagelet application class expects certain attributes to be treated in certain ways. To get this to work I combined the Image and URL types.

There are several sections where the tags are processed in the Execute method, e.g.


/* Process Image Objects */
&imageNodes = &TransformedDoc.DocumentElement.GetElementsByTagName("PSIMG");


1. So I created a query which just retrieves one row, i.e. on PSOPTIONS.
2. Create a Pagelet using PS Query as a data source.
3. Use custom XSL, so generate normally and then click customise.
4. Modify the XSL to use the new tag, e.g. CASEY.

<xsl:choose>
 <xsl:when test="querydata[position()=2]/text!=''">
  <CASEY target="%PAGELETID">
    <xsl:attribute name="PORTAL">EMPLOYEE</xsl:attribute>
    <xsl:attribute name="CREF">EP_RECV_PO</xsl:attribute>
    <xsl:attribute name="ID">PS_APPROVE_ICN</xsl:attribute>
    <xsl:attribute name="APPEND">?Page=RECV_WPO&Action=U&TargetFrameName=None</xsl:attribute>
  </CASEY>
 </xsl:when>
 <xsl:otherwise> </xsl:otherwise>
</xsl:choose>


4. Modify the Pagelet code to use the new tag, e.g. CASEY.
 
                  /* An error occurred during the formatting process - so just use the NodeValue */
                  &FormattedNodeValue = &NodeValue;
               end-try;
               
            End-For;
         End-If;
         
         /* Casey - Start */
         &linkNodes = &TransformedDoc.DocumentElement.GetElementsByTagName("CASEY");
         If &linkNodes.Len > 0 Then
            For &i = 1 To &linkNodes.Len
               &ParentNode = &linkNodes [&i].ParentNode;
               &removedNode = &linkNodes [&i];
               
               &crefurl = "";
               
               &PortalName = &removedNode.GetAttributeValue("PORTAL");
               &CREFName = &removedNode.GetAttributeValue("CREF");
               
               &imageID = &removedNode.GetAttributeValue("ID");
               &newImageURL = %Response.GetImageURL(@"Image." | &imageID);
               
               If &CREFName <> "" Then
                  If &PortalName <> "" Then
                     &Portal = %Session.GetPortalRegistry();
                     If Not &Portal.Open(&PortalName) Then
                        &Portal = PortalOpen();
                     End-If;
                  Else
                     &Portal = PortalOpen();
                  End-If;
                  &cref = &Portal.FindCREFByName(&CREFName);
                  If &cref <> Null Then
                     Evaluate %This.PSGeneratedLinkType
                     When = %This.PSGENERATEDLINKTYPE_PSP_ABSOLUTE
                        &crefurl = &cref.AbsolutePortalURL;
                        Break;
                     When = %This.PSGENERATEDLINKTYPE_PSC_ABSOLUTE
                        &crefurl = &cref.AbsoluteContentURL;
                        Break;
                     When-Other
                        &crefurl = &cref.RelativeURL;
                     End-Evaluate;
                  End-If;
               End-If;
               
               If &crefurl <> "" Then
                  &s_append = &removedNode.GetAttributeValue("APPEND");
                  
                  /* if the url already has a ?, change a leading ? in the appendstring to an & */
                  If Find("?", &crefurl) > 0 Then
                     If Find("?", &s_append) = 1 Then
                        &s_append = Replace(&s_append, 1, 1, "&");
                     End-If;
                  End-If;
                  
                  &crefurl = &crefurl | &s_append;
                  
                  &replacePosition = &linkNodes [&i].Index;
                  &removedNode = &ParentNode.RemoveChildNode(&linkNodes [&i]);
                  If &ParentNode.ChildNodeCount = 0 Or
                        &ParentNode.ChildNodeCount <= &replacePosition Then
                     &newlinknode = &ParentNode.AddElement("A");
                  Else
                     &newlinknode = &ParentNode.InsertElement("A", &replacePosition);
                  End-If;
                  
                  If &removedNode.GetAttributeValue("target") <> "" Then
                     /* Going to a new target window... */
                     If &removedNode.GetAttributeValue("target") = "%PAGELETID" Then
                        &newlinknode.AddAttribute("target", &ID);
                     Else
                        &newlinknode.AddAttribute("target", &removedNode.GetAttributeValue("target"));
                     End-If;
                     
                     /* Reconstruct the target url to include the _newwin */
                     &crefurl = PSURLToNewWin(&crefurl);
                     
                  Else
                     /* No target specified on link, so take the target property (if exists) */
                     If %This.PSGeneratedLinkTarget <> "" Then
                        &newlinknode.AddAttribute("target", %This.PSGeneratedLinkTarget);
                     End-If;
                     
                  End-If;
                  
                  If &removedNode.GetAttributeValue("class") <> "" Then
                     /* Copy over the class attribute */
                     &newlinknode.AddAttribute("class", &removedNode.GetAttributeValue("class"));
                  End-If;
                  &newlinknode.AddAttribute("href", &crefurl);
                  
                  &newlinknode.AddAttribute("title", &removedNode.NodeValue);
                  &newlinktextnode = &newlinknode.AddText(&removedNode.NodeValue);
                  
                  &newImageNode = &newlinknode.AddElement("IMG");
                  &newImageNode.AddAttribute("src", &newImageURL);
                  &newImageNode.AddAttribute("border", "0");
               Else
                  /* CREF was not found - just write in the text */
                  rem &newlinknode = &ParentNode.AddText(&removedNode.NodeValue);
                  
                  &replacePosition = &linkNodes [&i].Index;
                  &removedNode = &ParentNode.RemoveChildNode(&linkNodes [&i]);
                  If &ParentNode.ChildNodeCount = 0 Or
                        &ParentNode.ChildNodeCount <= &replacePosition Then
                     &newlinknode = &ParentNode.AddText(&removedNode.NodeValue);
                  Else
                     &newlinknode = &ParentNode.InsertText(&removedNode.NodeValue, &replacePosition);
                  End-If;
                  
                  
               End-If;
            End-For;
         End-If;
         
         /* Casey - End */
         
         
         /* Process Registered Links */
         &linkNodes = &TransformedDoc.DocumentElement.GetElementsByTagName("PSREGISTEREDLINK");

Pagelets wizard - view attachments

To allow attachments to be shown via a Pagelet generated by the pagelet wizard
1. Create an IScript, e.g. IScript_GetBISDocs, and register it to a hidden portal content reference.
2. Have a query which identifies the information needed. For example, the PS_BIS_DOCS table stores a Source, e.g. PO, and an Doc Key, contains BU, PO number etc.
3. Create a Pagelet using PS Query as a data source, and define a link for one of the columns, e.g. PO ID, which links to the Content Reference created in step 1.
  • Pass in additional parameters as required, e.g. Business Unit and PO ID.

Here is a link to the document in Skydrive with screen shots of the Pagelet, Query etc.
SkyDrive Doc



Here is the PeopleCode from the IScript.

Function IScript_Get_Docs();
   Local string &strBU = %Request.GetParameter("BUSINESS_UNIT");
   Local string &strPO = %Request.GetParameter("PO_ID");
   Local string &DocSys, &DocName, &strPath, &strFile;
   Local integer &intRtrnCd;
   SetTracePC(0);
   SetTraceSQL(0);
   
   rem Fetch the attachments;
   Get_PO_Docs(&strBU | &strPO, 9999, &DocSys, &DocName);
   
   rem SQLExec("SELECT COMMENTS FROM PSURLDEFN WHERE URL_ID=:1", URL.MY_URL, &strPath);
   If Right(GetEnv("PS_FILEDIR"), 1) <> "\" Then;
      &strPath = GetEnv("PS_FILEDIR") | "\";
   Else;
      &strPath = GetEnv("PS_FILEDIR");
   End-If;
   &strFile = &strPath | &DocName;
   &intRtrnCd = GetAttachment(URL.BIS_GL_BUD_FILE_ATTACH, &DocSys, &strFile);
   
   If FileExists(&strFile, %FilePath_Absolute) Then;
      &intRtrnCd = PutAttachment(URL.FILEDB, &DocName, &strFile);
   End-If;
   
   Local Rowset &attachrs;
   Local integer &row_count;
   Local string &attachrec_name = Record.PSFILE_ATTDET;
   Local string &content_type;
   Local string &attachfile_name = &DocName;
   
   
   &attachrs = CreateRowset(@("Record." | Upper(&attachrec_name)));
   &attachrs.Fill("WHERE ATTACHSYSFILENAME = :1 ORDER BY FILE_SEQ", &attachfile_name);
   
   /*Read the file BLOB from database record and write to response*/
   For &row_count = 1 To &attachrs.ActiveRowCount;
      try
         %Response.WriteBinary(&attachrs(&row_count).GetRecord(@("Record." | Upper(&attachrec_name))).FILE_DATA.Value);
      catch Exception &ex
         %Response.SetContentType("text/plain");
         %Response.Write(MsgGetText(137, 182, "Exception in writing binary file data from database" | " " | &ex.ToString()));
      end-try;
   End-For;
   
   /*%Response.SetHeader("Content-Disposition", "attachment;filename=" | EncodeURL(&attachfile_name));*/
   %Response.SetContentType("application/pdf");
   
   SetTracePC(0);
   SetTraceSQL(0);
   
End-Function;