Forum .LRN Q&A: Extended Version of Static Portlet

Collapse
Posted by Nima Mazloumi on

Hi everybody,

I extended the static portlet package by adding some useful parameters (maybe some arn't) to it as it is done in the bulk mail package.
The reason for that is that I am now using the static portlet to add a better plugin support to dotLRN. Thus any plugable application can be customized to it's needs (java applet, flash...).
I am sure that such a functionality is essentiell to extend OpenACS or to integrate external applications. As a proof of concept I will post 2 implementations for that purpose soon (A chat and a e-learning simulation). Also simple customized pages could be generated - like letter of recommendation (but limited since the gender of a person is not stored in OpenACS :) ).

It would be great if someone could look at the source and give some advice on how to make my code better since I am a newbie.

Some features essential but missing in my opinion are:

  • An administration page only accessible to the site-admin where he creates a variety of static portlets with this extended feature by passing html-fragments that contain needed parameters. Thus we can avoid security holes.
  • a user page where the class/community admin can either select from an existing predefined portlet or create a simple static portlet.

Here are some examples for the above idea:

A chat client based on flash

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" width="600" height="400" id="chat" align="middle">
<param name="allowScriptAccess" value="sameDomain" />
<param name="movie" value="http://server:port/chat.swf?user_id={user_id}&login_name={login}&first_name={first_name}&last_name={last_name}&screen_name={screen_name}&locale={locale}&session_id={session_id}&community_header_name={c_header_name}&page_name={page_name}" />
<param name="quality" value="high" />
<param name="bgcolor" value="#ffffff" />
<embed src="chat.swf" quality="high" bgcolor="#ffffff" width="600" height="400" name="chat" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" /></object>

A java applet that serves as a sophisticated gui to an accounting simulation Joker we developed

<APPLET NAME="InteractionApplet" CODEBASE="lib/" CODE="de.unimannheim.joker.client.prototype.InteractionApplet.class" ARCHIVE="eJoker.jar,jamato.jar,jboss-common-client.jar,jboss-j2ee.jar,jnp-client.jar" WIDTH="150" HEIGHT="30">
<PARAM NAME="ip" VALUE="localhost">
<PARAM NAME="port" VALUE="1099">
<PARAM NAME="user_id" VALUE="{user_id}">
<PARAM NAME="login_name" VALUE="{login_name}">
<PARAM NAME="first_name" VALUE="{first_name}">
<PARAM NAME="last_name" VALUE="{last_name}">
<PARAM NAME="screen_name" VALUE="{screen_name}">
<PARAM NAME="locale" VALUE="{locale}">
<PARAM NAME="session_id" VALUE="{session_id}">
</APPLET>

Any concerns, ideas, feedback is more than welcome. If you like the idea and as soon as the code is approved it would be nice to make this feature available to other dotLRN users as well.

Best wishes, Nima Mazloumi

Here are my additions

: I added a parameter.adp page that is included in the element-new.adp:

This is a list of parameters and a description.

  • {user_id} - A unique integer
  • {login} - Login name of the user
  • {first_name} - First name
  • {last_name} - Last name
  • {screen_name}- Screen name
  • {client_ip} - IP-Address of the client requesting the page
  • {account_status} - Status of the users account
  • {locale} - Language setting of the user
  • {is_connected} - Connection status of the user
  • {session_id} - Session Id of the current login
  • {community_id} - Community Id
  • {community_header_name} - Title of the community
  • {community_url} - Relative path to the community
  • {page_name} - Name of the current page
  • {page_url} - Relativ path to this page
  • {url_query} - Query passed by the client
  • {package_url} - Package URL
  • {package_id} - Package Id
  • {portal_id} - Portal Id
  • {dotlrn_url} - Relative path to .LRN
  • {node_id} - Node id
  • {object_id} - Object Id
  • {current_url} - Current URL

Extending static-portlet.tcl (kind of a hack I know)


##################################
#
# Added limited interpolation 
#
##################################

set service "";
# parameters that are available:
set user_id [ad_get_user_id]
#set current_user_id [ad_verify_and_get_user_id]
set community_id [dotlrn_community::get_community_id]
set dotlrn_url [dotlrn::get_url]
set portal_id [dotlrn::get_portal_id -user_id $user_id]
set package_id [ad_conn package_id]
set session_id [ad_conn session_id]
set page_name [ad_conn instance_name]
set page_url [ad_conn url]
set client_ip [ad_conn peeraddr]
set account_status [ad_conn account_status]
set locale [ad_conn locale]
set is_connected [ad_conn isconnected]
set package_url [ad_conn package_url]
set current_url [ad_conn extra_url]
set node_id [ad_conn node_id]
set url_query [ad_conn query]
set object_id [ad_conn object_id]
set first_name [db_string select_first_name {select first_names from cc_users where user_id = :user_id} -default ""]
set last_name [db_string select_last_name {select last_name from cc_users where user_id = :user_id} -default ""]
set screen_name [acs_user::ScreenName]
set subsite_url [subsite::get_element -element url]
set login [db_string select_user_name {select username from cc_users where user_id = :user_id} -default ""]

if {![empty_string_p $screen_name]} {
    set screen_name [acs_user::ScreenName]
} else {
    set screen_name "empty"
}

if {![empty_string_p $community_id]} {
    set community_header_name [dotlrn_community::get_community_header_name $community_id]
    set community_url [dotlrn_community::get_community_url $community_id]
} else {
    set community_header_name "empty"
    set community_url "empty"
}

set values [list]
            lappend values [list \{user_id\} $user_id]
            lappend values [list \{community_id\} $community_id]
            lappend values [list \{dotlrn_url\} $dotlrn_url]
            lappend values [list \{portal_id\} $portal_id]
            lappend values [list \{community_header_name\} $community_header_name]
            lappend values [list \{community_url\} $community_url]
            lappend values [list \{session_id\} $session_id]
            lappend values [list \{page_name\} $page_name] 
            lappend values [list \{page_url\} $page_url] 
            lappend values [list \{client_ip\} $client_ip] 
            lappend values [list \{account_status\} $account_status] 
            lappend values [list \{locale\} $locale] 
            lappend values [list \{is_connected\} $is_connected] 
            lappend values [list \{node_id\} $node_id] 
            lappend values [list \{url_query\} $url_query] 
            lappend values [list \{object_id\} $object_id]
            lappend values [list \{package_id\} $package_id]
            lappend values [list \{package_url\} $package_url]
            lappend values [list \{current_url\} $current_url]
            lappend values [list \{first_name\} $first_name]
            lappend values [list \{last_name\} $last_name]
            lappend values [list \{screen_name\} $screen_name]
            lappend values [list \{subsite_url\} $subsite_url]
            lappend values [list \{login\} $login]

    set fragment [db_string select_content {select content from static_portal_content where content_id = :content_id} -default ""]
    set content [static_portlet_content::interpolate -values $values -text $fragment]

Adding the static-interpolate-procs.tcl file

ad_library {

    Package allows limited parameter interpolation.

    @author Nima Mazloumi
    @creation-date 2003-11-05
    @version $Id: static-interpolate-procs.tcl,v 1.1.1.1 2003/11/05 00:14:46 mazloumi Exp $

}

namespace eval static_portlet_content {}

    ad_proc -public static_portlet_content::interpolate {
        {-values:required}
        {-text:required}
    } {
        Interpolates a set of values into a string.

        @param values a list of tuples, each one consisting of a target string
                      and the value it is to be replaced with.
        @param text the string that is to be interpolated

        @return the interpolated string
    } {
        foreach tuple $values {
            regsub -all [lindex $tuple 0] $text [lindex $tuple 1] text
        }

        return $text
    }

That's it. It works very well. But as I mentioned the extension to the static-portlet.tcl is not very nice. There should be a more cleaner and extensible way...either via XML or database or OpenACS parameters. What do you think?

Greetings

Nima Mazloumi
Collapse
Posted by Dirk Gomez on
Don'w we have a maintainer for Static Portlet? Certainly looks like we need to pick this up.