Mostrando entradas con la etiqueta xml. Mostrar todas las entradas
Mostrando entradas con la etiqueta xml. Mostrar todas las entradas

miércoles, 16 de enero de 2013

Importing tags with Groovy

In this post I use a Groovy script to import custom tags into Magnolia CMS. The script saves the tags in the Data module. You can use them to categorize pages, images and documents.

Clients often ask me how to import an existing collection of tags into Magnolia CMS. Local governments use tags such as taxestransportation or schools to categorize their content. Travel websites use geographical terms like londonparis and bangkok to tag places to visit. Such vocabularies grow large over time. Creating them from scratch is a lot of work.

I wrote a Groovy script that imports tags from XML. The example below finds any Flickr tags that are related to the given tag london. You can customize the script to import your own tags. I am not sure why I had not used Groovy much before. Once I tried it I loved it! You will too when you see how simple it is to implement a tag importer.



Requirements
  • Magnolia CMS 4.5.7 with Groovy module. It's in the add-ons folder in the bundle.
  • Flickr API key. Register for an API key in order to call the Flickr API.

Creating a Groovy script
  1. In Magnolia CMS, go to Tools > Scripts and add a new Groovy script.
  2. Paste the following code into your script.
  3. Check the Is a script? box.
tag = 'london'
hm = MgnlContext.getHierarchyManager('data')

// Create a folder in the Data module
flickrTags = ContentUtil.createPath(hm, "/categorization/${tag}", new ItemType("dataFolder"))
hm.save()
itemType = new ItemType('category')

// Connect to Flickr REST API
URL url = new URL("http://api.flickr.com/services/rest/?method=flickr.tags.getRelated&api_key=5f26c50b6e67110809b117da0f2bb94f&tag=${tag}")

HttpURLConnection conn = (HttpURLConnection) url.openConnection()
    conn.setRequestMethod("GET")
    conn.setRequestProperty("Accept", "application/xml")

 if (conn.getResponseCode() != 200) {
   throw new RuntimeException("Failed : HTTP error code : "
   + conn.getResponseCode())
 }

// Parse the response XML 
rsp = new XmlSlurper().parse(conn.getInputStream())
rsp.tags.tag.each{
      content = ContentUtil.createPath(hm, "/categorization/${tag}/${it.text()}", itemType)
      content.name = it.text()
}

flickrTags.save()
conn.disconnect()
return "done"

Here's what the script does:
  1. Create a new folder in the Data module with the parent tag name.
  2. Connect to the Flickr REST API and request all tags related to the parent tag.
  3. Parse the resulting XML.
  4. Create categories under the previously created data folder.

Now the tags are available for categorizing content.



Bear in mind is that there is no error handling in this code to keep it short. This solution has been developed and tested with Magnolia 4.5.7

jueves, 25 de febrero de 2010

From HTML to XML and beyond!

What happens if you need to deliver same content but in different format? Sure you don't want to duplicate content. Well Magnolia CMS provides a feature that with little work lets you deliver same content in any format you need, it could be xml, or even html but optimized for newsletters.

How to do this? You need to select a template definition and add sub templates like in the image below.



This sample is using Magnolia CMS version 3.6 (feature also available for 4.x) with just one sub template defined that will render as xml when I request the page as url.xml and rendered as html when requested as url.html.

Because at the moment, sub templates do not work for paragraphs, in the template file that generates the xml content we will have to iterate through the paragraphs.

In my sample I used jsp, so I iterated main collection within a scriplet, by first getting the active page and then its children:

Content actPage = Resource.getActivePage(request);
if(actPage.hasContent("mainColumnParagraphs")) {
//some code
}


When using freemarker there is no need to use java:

[#list content.main?children as para]
[#assign paragraphContent=para]
[#if para.metaData.template='mgnlTextBox']
[#include "textBox.ftl" ]
[/#if]
[/#list]


One of my use cases was to generate a newsletter template for the web and a simpler one that would be supported by the mail clients.