portals-jetspeed-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From <paulspen...@mindspring.com>
Subject Re: Jetspeed Proposal: iframe portlet control
Date Tue, 05 Mar 2002 16:09:15 GMT
Glen,
How does this compare to the IframePortlet in the cvs?
http://cvs.apache.org/viewcvs.cgi/jakarta-jetspeed/src/java/org/apache/jetspeed/portal/portlets/IFramePortlet.java

Paul Spencer

Jetspeed Developers List <jetspeed-dev@jakarta.apache.org> wrote:
> Here is a proposal for Jetspeed.  We (the CHEF team at U of M) need this in
our Jetspeed, and I'd like to develop it for Jetspeed proper.  I'd like to
get your feedback, comments, and suggestions, and to find out if we can put
this into the product.
 
* * *
 
1.0 Goals:
 
To select any portlet to be placed into an iframe in the portal page.  This
allows the portlet:
 
1.1  page size control with scrolling
 
Users would be able to specify the size of the portlet on the page, probably
just the height, as the layout figures the width.  If the portlet content is
larger than the footprint, scroll bars would appear to allow the portlet to
be scrolled independently of the rest of the portal page.
 
1.2  independent updating, scriptable
 
Each portlet in an iframe could have its contents refreshed without having
the rest of the page refreshed.  This would happen if the user pressed a
link or a form submit within the portlet content, or if javascript in the
portal page caused the iframe to refresh (usually by changing the src=
attribute of the iframe).  Nothing else on the page would change when a
portlet refreshes.  Multiple portlets in iframes on the same portal page
could refresh concurrently, independently.
 
1.3  directed form processing
 
When a form from an iframe'ed portlet is submitted, it is sent to a URL
which causes just the portlet to be displayed back into the iframe.  For
Velocity portlets, this means that just that one addressed portlet would get
a change to process the form data.  This focuses the submit to the one
portlet, which is usually what we want.
 
When an AbstractPortlet is placed in an iframe, it would be using real
Turbine actions encoded into the form submit, which are already focused on
the portlet's action class.
 
* * *
 
2.0  Details
 
2.1  Title Bar in Portal, Portlet in iframe
 
When a portlet is placed into an iframe, the portlet title bar and controls
are left in the portal page, with the iframe just below and sized to fit the
width of the portlet's footprint on the screen.
 
2.2  User's select, Mix and match
 
Users would be able to mix portlets on a portal page that are directly on
the page with those that are in iframes.  Any portlet can be placed into an
iframe.
 
2.3  Portlet Content URL
 
To support the iframe's addressing of a single portlet, a special URL if
formed to address the portlet content.
 
* * *
 
3.0  Implementation
 
3.1  Portlet Content
 
I distinguish between the portlet's full display, including the
PortletControl, and just the display from the portlet itself, calling the
later the portlet content.  To get a display of just the portlet content, a
new screen is added to Jetspeed called "Content".  This consists of a screen
template, Content.vm, and a page layout template, also called Content.vm.
 
3.1.1  The layout template achieves the goal of delivering just the screen
without any navigation:
 

  
    
     
  
  
    $screen_placeholder
  


3.1.2  The screen template achieves the goal of delivering just the portlet
content, not the whole page, not the portlet control:
 
#if ($data.Portlet)
 $jetspeed.getPortletContent($data.Portlet)
#else
 Portlet missing
#end

Notice that there is a new method added to the JetspeedTool:
getPortletContent().  This is just like getPortlet(), except that when the
named portlet is found, getPortlet() points at the control, and
getPortletContent() points at the portlet within the control.
 
3.1.3  Here's the code to add to JetspeedTool:
 
    /** 
     * Return the content of a named portlet, without the controller. This
portlet is sought in 
     * the current PSML resource.
     *
     * @param name the name of the portlet to render
     * @return the rendered content of the portlet
     */
    public ConcreteElement getPortletContent(String name)
    {
        ConcreteElement result = null;
        Portlet found = null;
        Stack sets = new Stack();
        sets.push(rundata.getProfile().getRootSet());
        
        while ((sets.size() > 0) && (found==null))
        {
            PortletSet set = (PortletSet)sets.pop();
            
            if (set.getName().equals(name))
            {
                found = set;
            }
            else
            {
                Enumeration en = set.getPortlets();
                while((found==null) && en.hasMoreElements())
                {
                    Portlet p = (Portlet)en.nextElement();
                        
                    // unstack the controls to find the real PortletSets
                    Portlet real = p;
                    while (real instanceof PortletControl)
                    {
                        real = ((PortletControl)p).getPortlet();
                    }
                        
                    if (real instanceof PortletSet)
                    {
                        // we'll explore this set afterwards
                        sets.push(real);
                    }
                    else if (p.getName().equals(name))
                    {                        
                        found = real;
                    }
                }
            }
        }
        
        if (found!=null)
        {
            result = found.getContent(rundata);
        }
        
        if (result==null)
        {
            //the customizer already streamed its content, return a stub
            result = new ConcreteElement();
        }
 
        return result;
    }

3.1.4  An action called Content is available to select the new content
screen for a request: 
 
public class Content extends Action
{
    public void doPerform(RunData data)
    {
        // pick the "Content" screen, and matching page layout
        jdata.setScreenTemplate("Content");
    }
}

3.1.5  URLs
 
To invoke this new screen, the URL looks like this:
 
/jetspeed/portal/template/Content/portlet/
 
or
 
/jetspeed/portal/template/Content?portlet=
 
or, using the action:
 
/jetspeed/portal?action=Content&portlet=
 
 
3.1.6  Portlet Identifier
 
The portlet name is used to find the portlet, much as it is used in the
jetspeed tool's getPortlet.  I see that this is being extended with
"&container=".  Whatever we decide on to uniquely identify and find a
portlet within a portal page, we need to use here as well, and the above
URL's would be extended, extending the portlet= with the additional
information.
 
3.1.7  Form Action
 
Portlets in an iframe need to specify a different form action, to make sure
that when the form is submitted, only the portlet content comes back.  The
action url is the same as those in 3.1.5 above.  In a velocity template,
this can be achieved with:
 
$jlink.setPortlet("$!data.Portlet")
 
giving us the url of the form:
 
/jetspeed/portal/template/Content/portlet/
 
Note, if additional information is needed to identify the portlet, this
additional information needs to be placed into $data so it can be used in
the link, or, better yet, a new method could be added to $jlink (or
setPortlet() updated?) to handle the properly id a portlet.

If the portlet is in the portal page directly, not in an iframe, the above
link works, with the /portlet/ being ignored.  Actually, the url becomes
 
/jetspeed/portal/template/Home/portlet/null.
 
We could enhance the JetspeedTemplateLink.setPortlet() call to do nothing if
the portlet is null.
 
Note that if the portlet is in an iframe, the form submit request will be
given only to that portlet, achieving our direct form processing goal.
 
3.2  Portlet Control
 
To place a portlet into an iframe, we can set a new portlet control for the
portlet.  This new control, the iFramePortletControl, takes care of placing
the portlet into the iframe.  Only portlets with this control would be
placed into iframes; other portlets would be placed directly into the portal
page.
 
Another option would be to have an optional parameter to any portlet, the
"iframe" boolean, which all the portlet controls would look for.  In this
case.  This may be easier to implement in the customizer, and give more
flexibility.  For this proposal, I describe the iFramePortletControl
approach.
 
3.2.1  iFramePortletControl
 
This is a velocity based portlet control, using an extension of the
VelocityPortletControl to provide more context.  The iframe.vm file is a
copy of the jetspeed.vm file, with one change:  Instead of placing the
portlet content with:
 
$!portlet.getContent($data)
 
It places the iframe, in the same place, with:
 
                
                

Note: rather than making a copy of jetspeed.vm as iframe.vm and modifying
it, I'd like to use the one jetspeed.vm, enhanced to know to place iframe or
not.  This plays into the other approach that makes all the controls iframe
aware.
 
The $iframeSrc is made much like the actions in VelocityPortletControl by
the extended class (see section 3.2.3).
 
3.2.2  iFramePortletControl registry entry
 
The entry for the new portlet control is:
 
    
        umich.chef.util.VelocityPortletIFrameControl
        
        
            iFramePortletControl
        
        
        
    

Note: the class is currently in my "umich.chef.util" package, but we would
want to place it into a jetspeed package.
 
3.2.3  VelocityPortletIFrameControl
 
The extension to VelocityPortletControl to add the $iframeSrc to the context
is:
 
public class VelocityPortletIFrameControl extends VelocityPortletControl
{
    /**
     * This method allows subclasses of the VelocityPortletControl
     * to populate the context of this control before rendering by
     * the template engine.
     *
     * @param rundata the RunData object for this request
     * @param context the Context used by the template
     */
    public void buildContext( RunData rundata, Context context )
    {
        Portlet portlet = getPortlet();
 
        String container = "na";
        if ( portlet.getPortletConfig().getPortletSet() != null)
        {
             container =
portlet.getPortletConfig().getPortletSet().getName();
        }
 
        String iframeSrc = new RelativeDynamicURI( rundata )
                            .addQueryData("action", "Content" )
                            .addQueryData("portlet", portlet.getName() )
                            .addQueryData("container", container )
                            .toString();
        context.put("iframeSrc", iframeSrc);
    }
}

Note: This continues the container work, and would need to be updated to
whatever methods we are using to id a portlet.
 
3.3  Customization
 
The customizers need to be modified to allow the user the choice of the
control for the portlet.  Or, if we take the other approach, the user needs
to be able to indicate iframe or not, and some iframe parameters (such as
height).  I have not done this, nor do I know much about how this works
(yet).
 
For now, to make a portlet be in an iframe, the .psml needs to be hand
edited:
 
 
  
 

4.0  Summary and Conclusion
 
I'd like to incorporate this work into the 1.3a3 jetspeed.  This would
involve:
 
-update to the JetspeedTool (getPortletContent())
-addition of the Content screen and layout templates
-addition of the Content action, placed into the jetspeed package
org.apache.jetspeed.modules.actions.controls
-(possible) update to $jlink.setPortlet() to have it take care of the
current portlet unique naming scheme, or (possibly) a new entry
-addition of the iFramePortletControl to the controls.xreg
-addition of the iframe.vm
-addition of the VelocityPortletIFrameControl class, placed in the package
org.apache.jetspeed.portal.controls
-or- some changes to the set of controls to recognize a common set of
portlet parameters for iframe
 
 
4.1  Decisions
 
Do we want this in Jetspeed?
 
Are there improvements to these details that better fit the jetspeed code
and intentions?
 
Do we want a single portlet control, or updates to them all?
 
How are we going to identify a portlet within a portal page?  What code will
support forming this id and finding?
 
How to change the customizers to support portlet control choice?
 
Should we surface more iframe control to the user, such as height?
 
Should we make the iframe parameters different (bigger height) when the
portlet is maximized?
 
* * *
 
I have preliminary versions of this coded and working.  I am happy to make
changes based on the group's feedback and decisions.  I can then email files
ready for checkin to a committer who would work with me on this.
 
Thanks for your time and attention.
 
- Glenn
 
--------------------------------------------
Glenn R. Golden, Systems Research Programmer
University of Michigan School of Information
  ggolden@umich.edu               734-615-1419
 
http://www-personal.si.umich.edu/~ggolden/
--------------------------------------------

 


--
To unsubscribe, e-mail:   <mailto:jetspeed-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:jetspeed-dev-help@jakarta.apache.org>


Mime
View raw message