Wednesday, April 30, 2014

Liferay : Advance Web Content Structures and Templates

The post details about the functionality to have multiple views for a web content article.

Currently only one view can be rendered for a article, but in real word scenarios there are occasions when different view are needed for the same content on same or different pages in Liferay.
Below are the steps with detailed code to achieve the above feature:

Step 1:
Create a new structure

<?xml version="1.0"?>

<root>
 <dynamic-element name="Name" type="text" index-type="" repeatable="false">
  <meta-data>
   <entry name="displayAsTooltip"><![CDATA[true]]></entry>
   <entry name="required"><![CDATA[true]]></entry>
   <entry name="instructions"><![CDATA[]]></entry>
   <entry name="label"><![CDATA[Name]]></entry>
   <entry name="predefinedValue"><![CDATA[]]></entry>
  </meta-data>
 </dynamic-element>
 <dynamic-element name="Address" type="text" index-type="" repeatable="false">
  <meta-data>
   <entry name="displayAsTooltip"><![CDATA[false]]></entry>
   <entry name="required"><![CDATA[true]]></entry>
   <entry name="instructions"><![CDATA[]]></entry>
   <entry name="label"><![CDATA[Address]]></entry>
   <entry name="predefinedValue"><![CDATA[]]></entry>
  </meta-data>
 </dynamic-element>
</root>



Step 2:
Create a new template


<p>
 <span style="font-size: 12px; ">
  <em><strong>Name: </strong>${Name.getData()}</em>
 </span>
</p>
<p>
 <span style="font-size: 12px; ">
  <em><strong>Address:</strong>${Address.getData()}</em>
 </span>
</p>




Step 3:
Create a web content based on structure and template created in step 1 and step 2. Populate some data in the web content.

Now our focus will be to create a new view for the content created in above in step 3

Step 4:
Thus create a new structure which will be dummy structure and fields here will not be relevant
<?xml version="1.0"?>

<root>
 <dynamic-element name="Dummy" type="text" index-type="" repeatable="false">
  <meta-data>
   <entry name="displayAsTooltip"><![CDATA[true]]></entry>
   <entry name="required"><![CDATA[true]]></entry>
   <entry name="instructions"><![CDATA[]]></entry>
   <entry name="label"><![CDATA[Dummy]]></entry>
   <entry name="predefinedValue"><![CDATA[]]></entry>
  </meta-data>
 </dynamic-element>

</root>





Step 5:
Create a new template, based upon structure creates in step 4, and will be considered as second view of the content created in step 3:

#set ($articleId = "10813")

#set ($renderUrl  = $request.render-url)
#set ($namespace = $request.portlet-namespace)
#set ($groupId = $getterUtil.getLong($groupId))

##
## Getting services
##
#set ($journalArticleService = 
 $serviceLocator.findService('com.liferay.portlet.journal.service.JournalArticleLocalService'))


#set ($article = $journalArticleService.getLatestArticle($groupId,$articleId))

<h3>Details</h3>
<br />
<table class="taglib-search-iterator">
 <tr class="results-header">
  <th class="col-1">Name</th>
  <th class="col-1">Address</th>
 </tr>
  
       #set ($document = $saxReaderUtil.read($article.content))
       #set ($root = $document.getRootElement())
       
       #set ($nameD = 
         $root.selectSingleNode(
           "dynamic-element[@name='Name']/dynamic-content"))
           
       #set ($addressD = 
         $root.selectSingleNode(
           "dynamic-element[@name='Address']/dynamic-content"))


   
      <tr class="results-row first">
       <td class="align-left col-1 valign-left">
       ${nameD.text}
       </td>

            <td class="align-left col-2 valign-middle">
           ${addressD.text}
       </td>

      </tr>
                   
</table>



Here $articleId is the article id of the content created in step 3.

Step 6:
Create a web content based on structure and template created in step 4 and step 5. The purpose of this content will be to display the data from the content created in step 3.


Liferay: Selecting multiple categories in Search portlet and Category Navigation portlet

Below is the original post which helps you to modify search and category navigation portlet and as a result user will be able to select multiple categories.

For more details go to:
http://liferaythought.wordpress.com/2013/04/30/selecting-multiple-categories/

Friday, April 18, 2014

RSA Encryption/Decryption - Part 2

My previous post on RSA details about basics of RSA and how to generate public and private key in java.


Encryption in Java



         public static byte[] encrypt(String text, PublicKey key) {
  byte[] cipherText = null;
  try {
   // get an RSA cipher object and print the provider
   final Cipher cipher = Cipher.getInstance(ALGORITHM);
   // encrypt the plain text using the public key
   cipher.init(Cipher.ENCRYPT_MODE, key);
   cipherText = cipher.doFinal(text.getBytes());

  } catch (Exception e) {
   e.printStackTrace();
  }
  return cipherText;
 }




Decryption in Java



         public static String decrypt(byte[] text, PrivateKey key) {
  byte[] decryptedText = null;
  try {
   // get an RSA cipher object and print the provider
   final Cipher cipher = Cipher.getInstance(ALGORITHM);

   // decrypt the text using the private key
   cipher.init(Cipher.DECRYPT_MODE, key);
   decryptedText = cipher.doFinal(text);

  } catch (Exception ex) {
   ex.printStackTrace();
  }

  return new String(decryptedText);
 }


RSA Encryption/Decryption - Part 1


What is Cryptography?

Cryptography is the practice or techniques for securing a communication in the presence of others. It is about constructing and analyzing protocols that overcome the influence of adversaries and are related to various aspects in information security such as data confidentiality, data integrity, authentication.

What is Encryption?

Encryption is one of the ways to achieve data security by translation of data into secret code or unreadable format called cipher text.

What is Decryption?

Decryption is the reverse of encryption that is converting cipher text to its original message, i.e. plain or readable text.

What is RSA?

RSA is one of the widely used public key cryptography for secure data communication. RSA stands for Ron Rivest, Adi Shamir and Leonard Adleman, who first publicly described it in 1978. Public key cryptohraphy is also called Asymmetric cryptography which requires two separate keys, one which is private key (secret key) and another which is public key. the public key is used to encrypt text while private key is used to decrypt text.

How to generate public/private key in java?




public static void generateKey(String private_key, String public_key) {
  try {
   final KeyPairGenerator keyGen = KeyPairGenerator
     .getInstance(ALGORITHM);
   keyGen.initialize(512);
   final KeyPair key = keyGen.generateKeyPair();

   File privateKeyFile = new File(private_key);
   File publicKeyFile = new File(public_key);

   // Create files to store public and private key
   if (privateKeyFile.getParentFile() != null) {
    privateKeyFile.getParentFile().mkdirs();
   }
   privateKeyFile.createNewFile();

   if (publicKeyFile.getParentFile() != null) {
    publicKeyFile.getParentFile().mkdirs();
   }
   publicKeyFile.createNewFile();

   // Saving the Public key in a file
   ObjectOutputStream publicKeyOS = new ObjectOutputStream(
     new FileOutputStream(publicKeyFile));
   publicKeyOS.writeObject(key.getPublic());
   publicKeyOS.close();

   // Saving the Private key in a file
   ObjectOutputStream privateKeyOS = new ObjectOutputStream(
     new FileOutputStream(privateKeyFile));
   privateKeyOS.writeObject(key.getPrivate());
   privateKeyOS.close();
  } catch (Exception e) {
   e.printStackTrace();
  }

 }

To call

generateKey("c:/rsa/key/public.key", "c:/rsa/key/private.key");
My next post on RSA details about how to encrypt and decrypt in java using  public and private key generated above.

Thursday, January 16, 2014

Liferay: Custom 404 Page for plugins

Liferay portal runs and is configured as ROOT application with in tomcat sever.
By default, if tried to request a plugin in Liferay (say we have a theme plugin named as "error-theme"), a 404 Error is raised and the user is served Tomcat's default 404 error page as below:


To make your 404 page a bit more presentable, provide the user with a link back into your site, as well as hide the Tomcat version in use, you can easily add a custom 404 error page.

Step 1:

Create a jsp name it 404.jsp, with below content:


The requested resource is not available. Please provide the correct URL or try again later.
<br/>
<a href="#" onclick="javascript:history.go(-1);">Go back to main site.</a>

Step 2:

Now create a new directory as error-theme/docroot/errors in Lifeay IDE and copy the above created 404.jsp to it.

Step 3:

Last step is to add the below code to the web deployment descriptor (web.xml) of the plugin:

         <error-page>
  <error-code>404</error-code>
  <location>/errors/404.jsp</location>
 </error-page>

Now, when someone goes to the plugin link that does not exist, they get the custom 404 page we created.





Tuesday, January 14, 2014

JQuery : Declare a function



Method 1: The Javascript way

The simple way to declare a  function in javascript:


function callMe (count) {
     return (count+5);
}

console.log(callMe(13));
//output: 18

Disadvantage: If you wanted a quick function to test something then maybe that’s the only occasion you would use this. It’s not good coding and doesn’t promote code reuse.


Method 2: Creating your JQuery function

The simple way to declare a  function in javascript:


<div id="mydiv">i am here</div>

jQuery.fn.extend({
    mytext: function () {
        var text = $(this).text();
        var mytexts = '';
        var toggle = true; //lower/uppper toggle
            $.each(text, function(i, nome) {
                mytexts += (toggle) ? nome.toUpperCase() : nome.toLowerCase();
                toggle = (toggle) ? false : true;
            });
    return mytexts;
    }
});

console.log($('#mydiv').zigzag());
//output: #1 i aM HeRe

//chained example
console.log($('#mydiv').zigzag().toLowerCase());
//output: #1 i am here


Method 1: Functions in custom namespaces

If your writing functions in a custom namespace you must declare them in this way. Extra functions can be added to the namespace you just need to add a comma after each one (except the last one!).


JQUERY4U = {
    callme: function(count) {
        return (count + 5);
    }
}
//function call
JQUERY4U.callme(13);

Reference post: Full credit goes to the original post, which made the topic so easy to understand (visit for more details).