1 building portals with infoglue silicon valley code camp 2007 freeman jackson innovation feed inc
TRANSCRIPT
11
Building Portals with Building Portals with InfoGlueInfoGlue
Silicon Valley Code Camp 2007Silicon Valley Code Camp 2007
Freeman JacksonFreeman Jackson
INNOVATION FEED INC.INNOVATION FEED INC.
22
What is InfoGlue?What is InfoGlue?
InfoGlue is a Content Management InfoGlue is a Content Management System. System.
How to manage a company’s or How to manage a company’s or organization’s information internally and organization’s information internally and externally. externally.
InfoGlue helps organizations manage their InfoGlue helps organizations manage their information mainly targeted for the Web information mainly targeted for the Web both internally, in intranets etc., and both internally, in intranets etc., and externally in public websites and externally in public websites and extranets.extranets.
33
What are the parts?What are the parts?
InfoGlue is a pure Java platform. InfoGlue is a pure Java platform. The management tool and the public sites The management tool and the public sites
are using information from a database. are using information from a database. Two main types of applications and they Two main types of applications and they
are the administrative tool and the are the administrative tool and the delivery engine.delivery engine.
The administrative tools are where you The administrative tools are where you manage all aspects of your site. manage all aspects of your site.
The delivery engines are specialized in The delivery engines are specialized in presenting sites to users based on the presenting sites to users based on the data managed by the tools. data managed by the tools.
44
Delivery EnginesDelivery Engines
By default InfoGlue installs By default InfoGlue installs 33 delivery delivery engines.engines.
The first is the working version which The first is the working version which presents the working version of the site. presents the working version of the site.
There is also a version called staging or There is also a version called staging or preview which shows the site in a preview preview which shows the site in a preview mode so the publisher can check that the mode so the publisher can check that the site will look good after publication. site will look good after publication.
The last delivery engine is the one that The last delivery engine is the one that shows the live site to visitors. shows the live site to visitors.
55
Sample Medium SetupSample Medium Setup
66
How does it workHow does it work InfoGlue can be text, image, word-files, InfoGlue can be text, image, word-files,
animations or anything else of informational animations or anything else of informational value. There are no format limitations.value. There are no format limitations.
The presentation/site structure part of the The presentation/site structure part of the InfoGlue system is what handles buildingInfoGlue system is what handles building
specific websites and it is called the “Structure specific websites and it is called the “Structure tool”. tool”.
With this tool you manage the site structure and With this tool you manage the site structure and chose which information to put on which pages chose which information to put on which pages and with which layout etc.and with which layout etc.
You can also define links between pages among You can also define links between pages among many other things.many other things.
77
Behind the curtainBehind the curtain
A very important thing to understand A very important thing to understand in InfoGlue later on is how a page in InfoGlue later on is how a page gets delivered to the user upon gets delivered to the user upon request. request.
88
99
A simple page componentA simple page component
1010
Page ComponentsPage Components
A page has at least one component. A page has at least one component. This component is called the This component is called the base base componentcomponent..
The second component used is for The second component used is for layout: header, left, middle, right and layout: header, left, middle, right and footer.footer.
The third layer is for the presentation The third layer is for the presentation components & bindings.components & bindings.
1111
What is a binding?What is a binding?
A binding is what connects a source A binding is what connects a source of information with a component so of information with a component so that the component can use it for that the component can use it for presentation or other purposes. presentation or other purposes.
1212
Development processDevelopment process
Site/Page analysisSite/Page analysis Content typesContent types Template/Component-listTemplate/Component-list
1313
Site/Page analysisSite/Page analysis What types of information are there and how we What types of information are there and how we
can generalize this into information types.can generalize this into information types. What parts of the pages are there, how can we What parts of the pages are there, how can we
create a layout system which is both simple and create a layout system which is both simple and easy to maintain and still dynamic and extendable easy to maintain and still dynamic and extendable for users who want that. for users who want that.
What components do we have to build to make it What components do we have to build to make it happen?happen?
What complex functionalities are there, how we What complex functionalities are there, how we solve it?solve it?
Are there some external systems that should be Are there some external systems that should be integrated somehow and if so – how is this best integrated somehow and if so – how is this best done.done.
Do we need to create new page types other than Do we need to create new page types other than the default? the default?
1414
ToolsTools Built in toolsBuilt in tools You can work with InfoGlue without any external tools at all. All templates/components and You can work with InfoGlue without any external tools at all. All templates/components and
everything is there as pure text editable though the normal browser text-editor.everything is there as pure text editable though the normal browser text-editor.
HTML-editorsHTML-editors When creating templates/components there is a lot of HTML-coding developers use an external When creating templates/components there is a lot of HTML-coding developers use an external
editor like Macromedia Dream Weaver to create the HTML and then transfer it to the tool by editor like Macromedia Dream Weaver to create the HTML and then transfer it to the tool by copy/paste and then continue working with it there.copy/paste and then continue working with it there.
Velocity editorVelocity editor For editing the templates and adding velocity-code some developers like to have an editor that can For editing the templates and adding velocity-code some developers like to have an editor that can
validate their velocity code for them. There are several ones that support this, among them Edit validate their velocity code for them. There are several ones that support this, among them Edit Plus and Eclipse if you use a plug-in.Plus and Eclipse if you use a plug-in.
Easy EditEasy Edit One of the developers of the platform (Stefan Sik) has developed an applet based tool which lets One of the developers of the platform (Stefan Sik) has developed an applet based tool which lets
you work in any editor you want and have the applet sync the text/images to the server when you you work in any editor you want and have the applet sync the text/images to the server when you save. This suits some people and the tool is found on the marketplace.save. This suits some people and the tool is found on the marketplace.
1515
Basics about Page typesBasics about Page types
1616
Management Tool/Type DefinitionsManagement Tool/Type Definitions
1717
Fields & Site Node Type DefinitionFields & Site Node Type Definition
1818
The Site Node view & BindingsThe Site Node view & Bindings
1919
ComponentsComponents
Composite patternComposite pattern Creating a componentCreating a component SlotsSlots Properties & bindingsProperties & bindings Component cachingComponent caching
2020
Composite patternComposite pattern
InfoGlue implements the composite InfoGlue implements the composite pattern which means that a page can be pattern which means that a page can be built up of small fragments. The composite built up of small fragments. The composite pattern is implemented so that a pattern is implemented so that a component can have so called “Slots” in it.component can have so called “Slots” in it.
It can have any number of slots and in It can have any number of slots and in each slot you can then put 0..n other each slot you can then put 0..n other components. You can have any number of components. You can have any number of compositions which means there is no compositions which means there is no limits to what you may do.limits to what you may do.
2121
Creating a componentCreating a component
You create a new component just by You create a new component just by creating a new content in the content creating a new content in the content tool with the content type tool with the content type “HTMLTemplate”. “HTMLTemplate”.
The old templates from the old way The old templates from the old way of building are actually just as good of building are actually just as good components as new ones except that components as new ones except that they don’t operate on component-they don’t operate on component-bindings but only on page-bindings if bindings but only on page-bindings if you don’t modify their logic.you don’t modify their logic.
2222
SlotsSlots A slot is as previously stated a place holder for A slot is as previously stated a place holder for
other components. You don’t need to do much to other components. You don’t need to do much to create a slot. Just add the tag create a slot. Just add the tag <ig:slot <ig:slot id=”slotname”></ig:slot> id=”slotname”></ig:slot> to the component to the component html at the position you choose. There are a couple html at the position you choose. There are a couple of optional attributes to the slot-tag: of optional attributes to the slot-tag: inherit, inherit, disallowedComponentNames disallowedComponentNames and and aallowedComponentNamesllowedComponentNames..
Inherit is used to state if the slot should be Inherit is used to state if the slot should be inherited to pages below (if not overridden) or not. inherited to pages below (if not overridden) or not. The allowedComponentNames and The allowedComponentNames and disallowedComponentNames attribute allows you disallowedComponentNames attribute allows you to specify a list of component names that are to specify a list of component names that are allowed not allowed in this slot. allowed not allowed in this slot.
2323
SlotsSlots
Here is a full example:Here is a full example:
<ig:slot id="rightColumn" <ig:slot id="rightColumn" inherit="false" inherit="false" allowedComponentNames="PuffImagallowedComponentNames="PuffImage,RelatedInfo,Searchform">e,RelatedInfo,Searchform">
</ig:slot></ig:slot>
2424
Properties & bindingsProperties & bindings One of the main benefits of components is that One of the main benefits of components is that
they can have properties.they can have properties. This means that an This means that an instance of the component on one page can have instance of the component on one page can have different settings than the same component located different settings than the same component located on another page. This enables developers to write on another page. This enables developers to write very dynamic and reusable components if needed. very dynamic and reusable components if needed. The users can configure their sites rather than The users can configure their sites rather than having developers helping them all the time.having developers helping them all the time.
You define properties in the attribute field You define properties in the attribute field “ComponentProperties” in the HTMLTemplatecontent “ComponentProperties” in the HTMLTemplatecontent you create for each component and the format is you create for each component and the format is XML. Don’t worry – there is a property editor built in XML. Don’t worry – there is a property editor built in so you don’t have to hack away but it has to be so you don’t have to hack away but it has to be turned on.turned on.
2525
Properties & bindingsProperties & bindings
For each property you want to define For each property you want to define you have an element like this:you have an element like this:
<property name="TargetPage" <property name="TargetPage" type="binding" entity="SiteNode"/>type="binding" entity="SiteNode"/>
2626
Properties & bindingsProperties & bindings The “name” is what you reference in you code The “name” is what you reference in you code
later to get the property value. The type can be later to get the property value. The type can be one of the following:one of the following:• bindingbinding – means you want to assign a resource from – means you want to assign a resource from
somewhere. This type requires an extra attribute “entity” somewhere. This type requires an extra attribute “entity” which defines what kind of resource it is you wish to bind. which defines what kind of resource it is you wish to bind. Types of bindings:Types of bindings:
SiteNode SiteNode means you wish to bind one or many pages – means you wish to bind one or many pages – probably for navigation purposes.probably for navigation purposes.
Content bindingsContent bindings are most often because that is how the are most often because that is how the component knows what information to display on a certain component knows what information to display on a certain page.page.
• textfield textfield – lets you have short strings assigned to a – lets you have short strings assigned to a component. Could be used to state the width of the component. Could be used to state the width of the component or something else you want to be able to component or something else you want to be able to define dynamically.define dynamically.
2727
Properties & bindingsProperties & bindings
<?xml version="1.0" encoding="UTF-8"?><?xml version="1.0" encoding="UTF-8"?><properties><properties>
<property name="OrderedPages" type="binding" <property name="OrderedPages" type="binding" entity="SiteNode" multiple="true"/>entity="SiteNode" multiple="true"/><property name="TargetPage" type="binding" <property name="TargetPage" type="binding" entity="SiteNode"/>entity="SiteNode"/><property name="Image" type="binding" entity="Content"<property name="Image" type="binding" entity="Content"
allowedContentTypeNames="Image,Asset"/>allowedContentTypeNames="Image,Asset"/><property name="OrderedImages" type="binding" <property name="OrderedImages" type="binding" entity="Content"/ multiple="true">entity="Content"/ multiple="true"><property name="Width" type="textfield" /><property name="Width" type="textfield" /><property name="Height" type="textfield" /><property name="Height" type="textfield" /><property name="AltText" type="textfield" /><property name="AltText" type="textfield" />
</properties></properties>
2828
Component caching (Menu e.g.)Component caching (Menu e.g.)PropertyName: PropertyName: CacheResultCacheResultType: Type: Textfield or dropboxTextfield or dropboxPossible values: Possible values: "true" / "false""true" / "false"Description: Description: If you set this to "true" the component will be cached If you set this to "true" the component will be cached
until either it expires or a new publication is made. until either it expires or a new publication is made. Subcomponents will also be cached with it.Subcomponents will also be cached with it.
PropertyName: PropertyName: UpdateIntervalUpdateIntervalType: Type: TextfieldTextfieldPossible values: Possible values: -1 and up.-1 and up.Description: Description: If you have the CacheResult property set to true and If you have the CacheResult property set to true and
you set this to a positive number the components result will be you set this to a positive number the components result will be cached for as many milliseconds.cached for as many milliseconds.
PropertyName: PropertyName: CacheKeyCacheKeyType: Type: TextfieldTextfieldPossible values: Possible values: Works like the page cache key and defaults to the Works like the page cache key and defaults to the
same key. Use this with caution. It's optional.same key. Use this with caution. It's optional.
2929
New content with HTMLTemplate.New content with HTMLTemplate.
3030
Looks like thisLooks like this
3131
The lowest field The lowest field
3232
Component descriptionComponent description
3333
APIAPI The component example shown above is JSP-based. The component example shown above is JSP-based. You can develop components in JSP, Velocity or Freemarker.You can develop components in JSP, Velocity or Freemarker. The system recognizes JSP-templates on its own and let’s tomcat The system recognizes JSP-templates on its own and let’s tomcat
compile them. compile them. You can of course write scriptlets which uses the You can of course write scriptlets which uses the
BasicTemplateController as you do in velocity but an even more BasicTemplateController as you do in velocity but an even more elegant solution is to use the many taglibs supplied with InfoGlue. elegant solution is to use the many taglibs supplied with InfoGlue.
When it comes to Velocity and its close relative Freemarker there When it comes to Velocity and its close relative Freemarker there are two APIs to be aware of when it comes to components. are two APIs to be aware of when it comes to components.
You will want to use the $templateLogic-object a lot probably as it You will want to use the $templateLogic-object a lot probably as it contain many good utility methods. Also you want to look into the contain many good utility methods. Also you want to look into the new templateLogic.componentLogic-object as that contains most new templateLogic.componentLogic-object as that contains most of the methods you need for the component specific stuff.of the methods you need for the component specific stuff.
3434
IntegrationIntegration
Simple integration via IframesSimple integration via Iframes Simple integration via embeddingSimple integration via embedding
<html><html><head><title>Embedded</title></head><head><title>Embedded</title></head><body><body>#set($remoteContent = #set($remoteContent =
$templateLogic.getUrlContent(“http://www.w3c$templateLogic.getUrlContent(“http://www.w3c.org”)).org”))
Here is the W3C content: $remoteContentHere is the W3C content: $remoteContent</body></body></html></html>
3535
Advanced integration via Advanced integration via custom classes in velocitycustom classes in velocity
If you wish to do embedding of external resources If you wish to do embedding of external resources in a more advanced way you will probably want in a more advanced way you will probably want to integrate by using pre made or custom to integrate by using pre made or custom backend logic. A very common situation is when backend logic. A very common situation is when you have some internal or external web service or you have some internal or external web service or database you wish to fetch information from but database you wish to fetch information from but you just want to fetch the data and still let you just want to fetch the data and still let InfoGlue handle the presentation.InfoGlue handle the presentation.
The solution is to write custom classes. In The solution is to write custom classes. In InfoGlue this is very simple. As long as you have InfoGlue this is very simple. As long as you have an empty constructor in your Java class and put it an empty constructor in your Java class and put it in the InfoGlue class path it will be usable from in the InfoGlue class path it will be usable from any template in your site.any template in your site.
3636
Advanced integration via Advanced integration via custom classes in velocitycustom classes in velocity
import java.util.List;import java.util.List;public class MyClasspublic class MyClass{{
public MyClass() { }public MyClass() { }public String getHelloWorld()public String getHelloWorld()
{ { return “Hello World”;return “Hello World”;
}}public List getOrders(String customerNumber)public List getOrders(String customerNumber){{
//Here we could connect to the order database with jdbc //Here we could connect to the order database with jdbc and query it // insteadand query it // insteadreturn null;return null;
}}}}
3737
Advanced integration via Advanced integration via custom classes in velocitycustom classes in velocity
<html><html><head><title>Embedded</title></head><head><title>Embedded</title></head><body><body>
#set($myClass = #set($myClass = $templateLogic.getObjectWithName(“MyCl$templateLogic.getObjectWithName(“MyClass”))ass”))The class says $myClass.getHelloWorld() The class says $myClass.getHelloWorld() to us.to us.
</body></body></html></html>
3838
Portlet developmentPortlet development
This section will guide you through This section will guide you through creating a simple Hello World portlet creating a simple Hello World portlet and deploying it in InfoGlue. It will and deploying it in InfoGlue. It will not show you how to build portlets not show you how to build portlets with more sophisticated frameworks with more sophisticated frameworks like Struts or Webwork as that is not like Struts or Webwork as that is not a question for InfoGlue.a question for InfoGlue.
3939
Step 1 – Hello World PortletStep 1 – Hello World Portletimport java.io.PrintWriter;import java.io.PrintWriter;import java.io.IOException;import java.io.IOException;import javax.portlet.GenericPortlet;import javax.portlet.GenericPortlet;import javax.portlet.PortletException;import javax.portlet.PortletException;import javax.portlet.RenderRequest;import javax.portlet.RenderRequest;import javax.portlet.RenderResponse;import javax.portlet.RenderResponse;/**/*** HelloWorld Portlet* HelloWorld Portlet*/*/public class HelloPortlet extends GenericPortletpublic class HelloPortlet extends GenericPortlet{{
public void doView(RenderRequest req, RenderResponse res) throwspublic void doView(RenderRequest req, RenderResponse res) throwsPortletException, IOExceptionPortletException, IOException{{
res.setContentType("text/html");res.setContentType("text/html");PrintWriter out = res.getWriter();PrintWriter out = res.getWriter();out.println("<h1>Hello World</h1>");out.println("<h1>Hello World</h1>");
}}}}The code needs portlet-api-1.0.jar in its class path to compile.The code needs portlet-api-1.0.jar in its class path to compile.
4040
Step 2 - Create a portlet.xmlStep 2 - Create a portlet.xml<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
version="1.0"version="1.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsdxsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsdhttp://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd">http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd">
<portlet><portlet><description>Hello Portlet</description><description>Hello Portlet</description><portlet-name>HelloPortlet</portlet-name><portlet-name>HelloPortlet</portlet-name><display-name>Hello Portlet</display-name><display-name>Hello Portlet</display-name><portlet-class>org.infoglue.portlets.HelloPortlet</portlet-class><portlet-class>org.infoglue.portlets.HelloPortlet</portlet-class><expiration-cache>-1</expiration-cache><expiration-cache>-1</expiration-cache><supports><supports>
<mime-type>text/html</mime-type><mime-type>text/html</mime-type><portlet-mode>VIEW</portlet-mode><portlet-mode>VIEW</portlet-mode>
</supports></supports><portlet-info><portlet-info>
<title>Hello Portlet</title><title>Hello Portlet</title><short-title>Hello Portlet</short-title><short-title>Hello Portlet</short-title><keywords>Hello,Portlet</keywords><keywords>Hello,Portlet</keywords>
</portlet-info></portlet-info></portlet></portlet></portlet-app></portlet-app>
4141
Step 3 - Create a web.xmlStep 3 - Create a web.xml<?xml version="1.0" encoding="UTF-8"?><?xml version="1.0" encoding="UTF-8"?><!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd">"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app><web-app><display-name>Hello Portlet</display-name><display-name>Hello Portlet</display-name><servlet><servlet>
<servlet-name>HelloPortlet</servlet-name><servlet-name>HelloPortlet</servlet-name><display-name>HelloPortlet Wrapper</display-name><display-name>HelloPortlet Wrapper</display-name><description>Hello Portlet Wrapper</description><description>Hello Portlet Wrapper</description><servlet-class>org.apache.pluto.core.PortletServlet</servlet-class><servlet-class>org.apache.pluto.core.PortletServlet</servlet-class><init-param><init-param>
<param-name>portlet-guid</param-name><param-name>portlet-guid</param-name><param-value>Hello.HelloPortlet</param-value><param-value>Hello.HelloPortlet</param-value>
</init-param></init-param><init-param><init-param>
<param-name>portlet-class</param-name><param-name>portlet-class</param-name><param-value>org.infoglue.portlets.HelloPortlet</param-value><param-value>org.infoglue.portlets.HelloPortlet</param-value>
</init-param></init-param></servlet></servlet><servlet-mapping><servlet-mapping>
<servlet-name>HelloPortlet</servlet-name><servlet-name>HelloPortlet</servlet-name><url-pattern>/HelloPortlet/*</url-pattern><url-pattern>/HelloPortlet/*</url-pattern>
</servlet-mapping></servlet-mapping></web-app></web-app>
4242
Step 4 – Package the portletStep 4 – Package the portlet Create a war-file with the following contents.Create a war-file with the following contents. HelloPortlet.warHelloPortlet.war -- web.xml-- web.xml -- portlet.xml-- portlet.xml -- WEB-INF-- WEB-INF -- classes-- classes -- org-- org -- infoglue-- infoglue -- portlets-- portlets -- HelloPortlet.class-- HelloPortlet.class
4343
Step 5 – Deploy the portlet in Step 5 – Deploy the portlet in InfoGlueInfoGlue
4444
Step 5 – Deploy the portlet in Step 5 – Deploy the portlet in InfoGlueInfoGlue
4545
Step 6 – Use the portlet on a Step 6 – Use the portlet on a page though a component.page though a component.
#set($portletName = "HelloPortlet.HelloPortlet")#set($portletName = "HelloPortlet.HelloPortlet")#set($calendarPortlet = #set($calendarPortlet =
$portalLogic.getPortletWindow($portletName,$portalLogic.getPortletWindow($portletName,"p$templateLogic.componentLogic.infoGlueComponent.id"))"p$templateLogic.componentLogic.infoGlueComponent.id"))$calendarPortlet.setAttribute("componentId",$calendarPortlet.setAttribute("componentId",$templateLogic.componentLogic.infoGlueComponent.id)$templateLogic.componentLogic.infoGlueComponent.id)$calendarPortlet.setAttribute("languageCode", $calendarPortlet.setAttribute("languageCode",
$templateLogic.locale.language)$templateLogic.locale.language)$calendarPortlet.setAttribute("siteNodeId", $calendarPortlet.setAttribute("siteNodeId",
$templateLogic.siteNodeId)$templateLogic.siteNodeId)$calendarPortlet.render()$calendarPortlet.render()
Restart tomcatRestart tomcat
4646
The EndThe EndFreeman JacksonFreeman Jackson
InnovationFeed.comInnovationFeed.com
1230 Market Street, #2521230 Market Street, #252
San Francisco, CA 94102San Francisco, CA 94102
510-575-4124510-575-4124
[email protected]@innovationfeed.comm