Index: openacs-4/contrib/packages/portal/sql/postgresql/datasource-package-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/portal/sql/postgresql/datasource-package-create.sql,v diff -u -r1.4 -r1.5 --- openacs-4/contrib/packages/portal/sql/postgresql/datasource-package-create.sql 15 Jan 2004 02:58:52 -0000 1.4 +++ openacs-4/contrib/packages/portal/sql/postgresql/datasource-package-create.sql 22 Jan 2004 02:50:11 -0000 1.5 @@ -23,48 +23,33 @@ -- @version $Id$ -- -select define_function_args('portal_datasource__new', 'name,shadeable_p;t,hideable_p;t,description'); +select define_function_args('portal_datasource__new', 'name,pretty_name,application,owner,template,shadeable_p;t,hideable_p;t,description'); -create or replace function portal_datasource__new (varchar, varchar, varchar, varchar) +create or replace function portal_datasource__new (varchar, varchar, varchar, varchar, varchar, varchar, varchar, varchar) returns integer as ' declare p_name alias for $1; - p_shadeable_p alias for $2; - p_hideable_p alias for $3; - p_description alias for $4; + p_pretty_name alias for $2; + p_application alias for $3; + p_owner alias for $4; + p_template alias for $5; + p_shadeable_p alias for $6; + p_hideable_p alias for $7; + p_description alias for $8; v_datasource_id portal_datasources.datasource_id%TYPE; begin v_datasource_id := nextval(''portal_seq''); insert into portal_datasources - (datasource_id, name, shadeable_p, hideable_p, description) + (datasource_id, name, pretty_name, application, owner, template, shadeable_p, hideable_p, description) values - (v_datasource_id, p_name, p_shadeable_p, p_hideable_p, p_description); + (v_datasource_id, p_name, p_pretty_name, p_application, p_owner, p_template, p_shadeable_p, p_hideable_p, p_description); return v_datasource_id; end;' language 'plpgsql'; -create or replace function portal_datasource__new (varchar, varchar) -returns integer as ' -declare - p_name alias for $1; - p_description alias for $2; - v_datasource_id portal_datasources.datasource_id%TYPE; -begin - - v_datasource_id := portal_datasource__new( - p_name, - ''t'', - ''t'', - p_description - ); - - return v_datasource_id; - -end;' language 'plpgsql'; - select define_function_args('portal_datasource__del', 'datasource_id'); create or replace function portal_datasource__del (integer) Index: openacs-4/contrib/packages/portal/sql/postgresql/portal-core-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/portal/sql/postgresql/portal-core-create.sql,v diff -u -r1.3 -r1.4 --- openacs-4/contrib/packages/portal/sql/postgresql/portal-core-create.sql 3 Jan 2004 01:42:57 -0000 1.3 +++ openacs-4/contrib/packages/portal/sql/postgresql/portal-core-create.sql 22 Jan 2004 02:50:11 -0000 1.4 @@ -32,6 +32,24 @@ name varchar(200) constraint p_datasources_name_nn not null, + pretty_name varchar(200) + constraint p_datasources_pretty_name_nn + not null, + application varchar(100) + constraint p_datasources_application_fk + references apm_package_types (package_key) + on delete cascade + constraint p_datasources_application_nn + not null, + owner varchar(100) + constraint p_datasources_owner_fk + references apm_package_types (package_key) + on delete cascade + constraint p_datasources_owner_nn + not null, + template varchar(200) + constraint p_datasources_template_nn + not null, shadeable_p char(1) default 't' constraint p_datasources_shadeable_p_nn @@ -47,11 +65,41 @@ description varchar(200) ); +-- indexes for referential integrity checking + +create index p_datasources_application_idx on portal_datasources(application); +create index p_datasources_owner_idx on portal_datasources(owner); + comment on table portal_datasources is ' a portal datasource is the package of code that generates the content of a portal element. the foo-portlet packages create datasources. '; +comment on column portal_datasources.name is ' + The name of this portal datasource. We can''t arbitrarily use portlet_key because many + portlet packages will support at least two portlets, one user portlet and one admin + portlet. +'; + +comment on column portal_datasources.pretty_name is ' + The default pretty name to use for an instance of this portlet. This should be a + message key for internationalized portlets. +'; + +comment on column portal_datasources.application is ' + The package key of the application that this portlet works with. For instance the + forums portlet works with the forums package. +'; + +comment on column portal_datasources.owner is ' + The package key of the package that implements this portlet. +'; + +comment on column portal_datasources.template is ' + The name of template that displays the portlet content. Note this is not a full + path, portlet templates go in the standard package template library directory. +'; + create table portal_datasource_parameters ( datasource_id integer constraint p_ds_params_datasource_id_fk @@ -319,6 +367,18 @@ not null constraint p_elements_hideable_p_ck check (hideable_p in ('t', 'f')), + application_id integer + constraint p_elements_application_id_fk + references apm_packages (package_id) + on delete cascade + constraint p_elements_application_id_nn + not null, + bound_object_id integer + constraint p_elements_b_o_id_fk + references acs_objects (object_id) + on delete cascade + constraint p_elements_b_o_id_nn + not null, constraint p_elements_page_id_name_un unique (page_id, name) ); @@ -338,6 +398,15 @@ different behaviors based on a given elements state '; +comment on column portal_elements.application_id is ' + The package_id of the OpenACS application package instance this element interacts + with. +'; + +comment on column portal_elements.bound_object_id is ' + The object_id of the object bound to this element, often the same as the application_id. +'; + create table portal_element_parameters ( parameter_id integer constraint portal_element_parameters_pk Index: openacs-4/contrib/packages/portal/tcl/datasource-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/portal/tcl/datasource-procs.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/contrib/packages/portal/tcl/datasource-procs.tcl 3 Jan 2004 01:42:57 -0000 1.2 +++ openacs-4/contrib/packages/portal/tcl/datasource-procs.tcl 22 Jan 2004 02:50:12 -0000 1.3 @@ -43,11 +43,16 @@ The specification is a list of name-value pairs. Possible names are - name The name of the new datasource - owner The package that owns this portlet (defaults to name) - description A human-readable description (defaults to name) - params A list of param key/attributes and their values - aliases Service contract aliases clause for acs_sc::impl::new_from_spec + name The name of the new datasource + pretty_name The pretty name (or message key) of the datasource + owner The package that owns this portlet + application The package the portlet works with + template The template the displays the portlet content + shadeable_p If true the user can shade (i.e. close) the portlet + hideable_p If true, the user can hide the portlet entirely + description A human-readable description (defaults to name) + params A list of portlet-specific param key/attributes and their values + aliases Service contract aliases clause for acs_sc::impl::new_from_spec Each parameter key can be followed by a comma-separated list of attributes in the familiar style of ad_page_contract or ad_form. Do not include spaces @@ -65,15 +70,20 @@ set datasource(description) $datasource(name) } - # Default datasource owner to its name - if { ![info exists datasource(owner)] } { - set datasource(owner) $datasource(name) - } - db_transaction { - set datasource_id [new -name $datasource(name) -description $datasource(description)] + set var_list [list \ + [list name $datasource(name)] \ + [list pretty_name $datasource(pretty_name)] \ + [list owner $datasource(owner)] \ + [list application $datasource(application)] \ + [list template $datasource(template)] \ + [list shadeable_p $datasource(shadeable_p)] \ + [list hideable_p $datasource(hideable_p)] \ + [list description $datasource(description)]] + set datasource_id [package_exec_plsql -var_list $var_list portal_datasource new] + foreach {param value} $datasource(params) { if { ![regexp {^([^ \t:]+)(?::([a-zA-Z0-9_,(|)]*))} \ @@ -112,22 +122,6 @@ } } - ad_proc -private new { - {-name:required} - {-description:required} - } { - - @author Simon Carstensen (simon@bcuni.net) - - } { - - set var_list [list \ - [list name $name] \ - [list description $description]] - - return [package_exec_plsql -var_list $var_list portal_datasource new] - } - ad_proc -private set_def_param { {-datasource_id:required} {-config_required_p:required} Index: openacs-4/contrib/packages/portal/tcl/element-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/portal/tcl/element-procs-oracle.xql,v diff -u -r1.2 -r1.3 --- openacs-4/contrib/packages/portal/tcl/element-procs-oracle.xql 8 Jan 2004 02:12:19 -0000 1.2 +++ openacs-4/contrib/packages/portal/tcl/element-procs-oracle.xql 22 Jan 2004 02:50:12 -0000 1.3 @@ -6,10 +6,13 @@ insert into portal_elements - (element_id, datasource_id, name, page_id, region, sort_key, shadeable_p, hideable_p) + (element_id, datasource_id, name, application_id, bound_object_id, + page_id, region, sort_key, shadeable_p, hideable_p) select :element_id, :datasource_id, :name, + :application_id, + :bound_object_id, :page_id, :region, nvl((select max(portal_elements.sort_key) + 1 Index: openacs-4/contrib/packages/portal/tcl/element-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/portal/tcl/element-procs-postgresql.xql,v diff -u -r1.2 -r1.3 --- openacs-4/contrib/packages/portal/tcl/element-procs-postgresql.xql 8 Jan 2004 02:12:19 -0000 1.2 +++ openacs-4/contrib/packages/portal/tcl/element-procs-postgresql.xql 22 Jan 2004 02:50:12 -0000 1.3 @@ -6,10 +6,13 @@ insert into portal_elements - (element_id, datasource_id, name, page_id, region, sort_key, shadeable_p, hideable_p) + (element_id, datasource_id, name, application_id, bound_object_id, + page_id, region, sort_key, shadeable_p, hideable_p) select :element_id, :datasource_id, :name, + :application_id, + :bound_object_id, :page_id, :region, coalesce((select max(portal_elements.sort_key) + 1 Index: openacs-4/contrib/packages/portal/tcl/element-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/portal/tcl/element-procs.tcl,v diff -u -r1.5 -r1.6 --- openacs-4/contrib/packages/portal/tcl/element-procs.tcl 10 Jan 2004 02:30:51 -0000 1.5 +++ openacs-4/contrib/packages/portal/tcl/element-procs.tcl 22 Jan 2004 02:50:12 -0000 1.6 @@ -28,21 +28,34 @@ namespace eval portal::element { ad_proc -public new { - {-page_id:required} - {-region:required} + {-portal_id:required} + {-page_name ""} + {-pretty_name ""} + {-region ""} {-datasource_name:required} + {-application_id:required} + {-bound_object_id ""} {-name ""} } { - create a new portal element of type portlet_name on the given page and - region + Create a new portal element of type datasource_name on the given portal. } { + set page_id [portal::page::get_id -portal_id $portal_id -page_name $page_name] + + if {[string equal "" $region]} { + set region [choose_region -page_id $page_id] + } + set datasource_id [portal::datasource::get_id -name $datasource_name] - if {[empty_string_p $name]} { + if {[string match "" $name]} { set name $datasource_name } + if {[string match "" $bound_object_id]} { + set bound_object_id $application_id + } + set element_id [db_nextval portal_seq] if {[db_0or1row select_template_element_id {}]} { @@ -369,109 +382,58 @@ } - ad_proc -private render { + ad_proc -private render_data { {-element_id:required} {-edit_p f} } { - render a portal element + Return all the good stuff a render template needs to render an element. + + @element_id The element in question + @edit_p If true the render template should show the shade and hide widgets + } { array set element [get -element_id $element_id] + + if {!$edit_p} { + set element(shadeable_p) f + set element(hideable_p) f + } + set element(shaded_p) [ad_decode $element(state) shaded t f] + array set theme [portal::theme::get \ -theme_id [portal::get_theme_id \ -portal_id [portal::page::get_portal_id -page_id $element(page_id)] \ ] \ ] - array set config [list \ - shaded_p [ad_decode $element(state) shaded t f] \ + set config [list \ + shaded_p $element(shaded_p) \ shadeable_p $element(shadeable_p) \ hideable_p $element(hideable_p) \ + application_id $element(application_id) \ + bound_object_id $element(bound_object_id) \ ] - array set config [portal::element::parameter::get_all -element_id $element_id] + + set config [concat $config [portal::element::parameter::get_all -element_id $element_id]] - if {!$edit_p} { - array set config {shadeable_p f hideable_p f} - } + array set datasource [portal::datasource::get -datasource_id $element(datasource_id)] - set datasource_name [portal::datasource::get_name \ - -datasource_id $element(datasource_id) \ - ] - - # if the element's name is the same as its datasource's, then we call - # the datasource's GetPrettyName operation - if {[string equal $element(name) $datasource_name]} { - set element(name) [portal::datasource::call \ - -name $datasource_name \ - -op GetPrettyName \ - ] + # if the element's name is the same as its datasource's, then we use + # the datasource's pretty_name value + if {[string equal $element(name) $datasource(name)]} { + set element(name) $datasource(pretty_name) } - # generate the content of this portal element - with_catch errmsg { - set element(content) [portal::datasource::call \ - -name $datasource_name \ - -op Show \ - -list_args [list [array get config]] \ - ] - } { - ns_log error "portal::element::render show callback error!\n\n$errmsg\n\n" - set element(content) "application error" - } - - set element(content) [string trim $element(content)] - set element(shadeable_p) $config(shadeable_p) - set element(hideable_p) $config(hideable_p) - set element(shaded_p) $config(shaded_p) + set element(template_path) "/packages/$datasource(owner)/www/$datasource(template)" + set element(config) $config set element(filename) "[portal::www_path]/$theme(filename)" set element(resource_dir) "/resources/portal/$theme(resource_dir)" return [array get element] } - ad_proc -private render_raw { - {-element_id:required} - } { - just call the "show" event for this element - } { - - array set element [get -element_id $element_id] - - array set config [list \ - shaded_p [util_decode $element(state) shaded t f] \ - shadeable_p $element(shadeable_p) \ - hideable_p $element(hideable_p) \ - ] - array set config [portal::element::parameter::get_all -element_id $element_id] - - set datasource_name [portal::datasource::get_name \ - -datasource_id $element(datasource_id) \ - ] - - set element(name) [portal::datasource::call \ - -name $datasource_name \ - -op GetPrettyName \ - ] - - with_catch errmsg { - portal::datasource::call \ - -name $datasource_name \ - -op Show \ - -list_args [list [array get config]] - } { - ns_log error "portal::element::render_raw show callback error!\n\n$errmsg\n\n" - set element(content) "application error" - } - - set element(content) [string trim $element(content)] - array set element {shadeable_p f shaded_p f hideable_p f} - set element(filename) "[portal::www_path]/themes/raw-theme" - - return [array get element] - - } - ad_proc -public configure { {-element_id:required} {-op:required} @@ -504,6 +466,8 @@ } +# DRB: this goes away entirely ... need to do the parameter stuff though, through a +# sevice contract call to set the bound_object_id and portlet-specific parameters. ad_proc -public add_parameters { {-portal_id:required} {-portlet_name:required} @@ -536,19 +500,18 @@ if {[llength $element_id_list] == 0} { - set page_id [portal::page::get_id -portal_id $portal_id -page_name $page_name] - - if {[string equal "" $force_region]} { - set force_region [choose_region -page_id $page_id] - } - db_transaction { # Tell portal to add this element to the page + + # DRB: short-term hack for the application id ... doesn't handle bound_object_id + # either. + set element_id [new \ -page_id $page_id \ -region $force_region \ -datasource_name $portlet_name \ + -application_id $value \ -name $pretty_name] portal::element::parameter::set_value -element_id $element_id -key $key -value $value Index: openacs-4/contrib/packages/portal/tcl/element-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/portal/tcl/element-procs.xql,v diff -u -r1.3 -r1.4 --- openacs-4/contrib/packages/portal/tcl/element-procs.xql 13 Jan 2004 02:23:05 -0000 1.3 +++ openacs-4/contrib/packages/portal/tcl/element-procs.xql 22 Jan 2004 02:50:12 -0000 1.4 @@ -67,6 +67,17 @@ + + + select count(*) as count + from portal_elements pe, + portal_pages pp + where pp.page_id = :page_id + and pe.region = :region + and pp.page_id = pe.page_id + + + select portal_elements.element_id Index: openacs-4/contrib/packages/portal/tcl/portal-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/portal/tcl/portal-procs.tcl,v diff -u -r1.7 -r1.8 --- openacs-4/contrib/packages/portal/tcl/portal-procs.tcl 15 Jan 2004 00:16:41 -0000 1.7 +++ openacs-4/contrib/packages/portal/tcl/portal-procs.tcl 22 Jan 2004 02:50:12 -0000 1.8 @@ -857,37 +857,6 @@ return "[lindex [ns_conn urlv] [expr [ns_conn urlc] - 1]]-2" } - ad_proc -public show_proc_helper { - {-template_src ""} - {-package_key:required} - {-config_list:required} - } { - hides ugly templating calls for portlet "show" procs - } { - - if { $template_src == ""} { - set template_src $package_key - } - - # some stupid upvar tricks to get them set right - upvar __ts ts - set ts $template_src - - upvar __pk pk - set pk $package_key - - upvar __cflist cflist - set cflist $config_list - - uplevel 1 { - set template "" - set __adp_stub "[get_server_root]/packages/$__pk/www/." - set code [template::adp_compile -string $template] - set output [template::adp_eval code] - return $output - } - } - ad_proc dimensional { {-no_header:boolean} {-no_bars:boolean} Index: openacs-4/contrib/packages/portal/www/render-styles/all-in-one/render-element.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/portal/www/render-styles/all-in-one/Attic/render-element.adp,v diff -u -r1.3 -r1.4 --- openacs-4/contrib/packages/portal/www/render-styles/all-in-one/render-element.adp 10 Jan 2004 01:01:01 -0000 1.3 +++ openacs-4/contrib/packages/portal/www/render-styles/all-in-one/render-element.adp 22 Jan 2004 02:50:12 -0000 1.4 @@ -19,7 +19,11 @@ %> + + + @element.name;noquote@ +@element.resource_dir;noquote@ @element.element_id;noquote@ @element.shadeable_p;noquote@ @element.shaded_p;noquote@ Index: openacs-4/contrib/packages/portal/www/render-styles/all-in-one/render-element.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/portal/www/render-styles/all-in-one/Attic/render-element.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/contrib/packages/portal/www/render-styles/all-in-one/render-element.tcl 25 Oct 2002 21:29:17 -0000 1.1 +++ openacs-4/contrib/packages/portal/www/render-styles/all-in-one/render-element.tcl 22 Jan 2004 02:50:12 -0000 1.2 @@ -15,25 +15,34 @@ # # www/render-element.tcl + ad_page_contract { Render an element. - @author Ben Adida + @author Don Baccus (dhogaza@pacifier.com) @creation-date @cvs_id $Id$ } -properties { element_id:onevalue region:onevalue } -if {[catch {set element_data [portal::element::render_raw -element_id $element_id]} errmsg]} { - # An uncaught error happened when trying to evaluate the element. - # If the error is in the element's "show" proc, the error will - # be shown in the content of the portlet. This is for errors other - # than with the "show" proc. - ns_log error "\n\n *** Error in portal/www/render-styles/all-in-one/render-element.tcl \n Uncaught exception when calling portal::element::render \n with element_id $element_id\n\n" - ad_return -code error -} else { - # all is ok - array set element $element_data +# we get element_id, action_string, theme_id, region, portal_id, +# edit_p, return_url, page_id, and layout_id from the layout_template + +# Get all the good stuff we need to render this sucker +array set element [portal::element::render_data -element_id $element_id] + +# We call the template engine directly to render the element rather than use an "include" +# statement in render-element.adp so we can catch the error and display a pretty +# error message. + +set include "" + +with_catch errmsg { + set code [template::adp_compile -string $include] + set element(content) [string trim [template::adp_eval code]] +} { + ns_log error "portal::element::render error!\n\n$errmsg\n\n" + set element(content) "application error" } Index: openacs-4/contrib/packages/portal/www/render-styles/individual/render-element.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/portal/www/render-styles/individual/Attic/render-element.adp,v diff -u -r1.4 -r1.5 --- openacs-4/contrib/packages/portal/www/render-styles/individual/render-element.adp 10 Jan 2004 02:30:51 -0000 1.4 +++ openacs-4/contrib/packages/portal/www/render-styles/individual/render-element.adp 22 Jan 2004 02:50:12 -0000 1.5 @@ -18,7 +18,6 @@ %> - @@ -31,4 +30,3 @@ @element.hideable_p;noquote@ @element.content;noquote@ - Index: openacs-4/contrib/packages/portal/www/render-styles/individual/render-element.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/portal/www/render-styles/individual/Attic/render-element.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/contrib/packages/portal/www/render-styles/individual/render-element.tcl 10 Jan 2004 01:01:01 -0000 1.2 +++ openacs-4/contrib/packages/portal/www/render-styles/individual/render-element.tcl 22 Jan 2004 02:50:12 -0000 1.3 @@ -16,11 +16,13 @@ # www/render-element.tcl ad_page_contract { - Render an element. - @author + Render a portal element. + + @author Don Baccus (dhogaza@pacifier.com) @creation-date @cvs_id $Id$ + } -properties { element_id:onevalue region:onevalue @@ -29,24 +31,19 @@ # we get element_id, action_string, theme_id, region, portal_id, # edit_p, return_url, page_id, and layout_id from the layout_template -if {[catch {set element_data [portal::element::render -element_id $element_id -edit_p $edit_p]} errmsg]} { - # An uncaught error happened when trying to evaluate the element. - # If the error is in the element's "show" proc, the error will - # be shown in the content of the portlet. This is for errors other - # than with the "show" proc. It hides the entire PE - ns_log error "\n\n *** Error in portal/www/render_styles_/individual/render-element.tcl \n Uncaught exception when calling portal::element::render \n with element_id $element_id\nError message: $errmsg\n\n" - array set element {content {}} +# Get all the good stuff we need to render this sucker +array set element [portal::element::render_data -element_id $element_id -edit_p $edit_p] -} else { - # all is ok - array set element $element_data -} +# We call the template engine directly to render the element rather than use an "include" +# statement in render-element.adp so we can catch the error and display a pretty +# error message. -# Added by Ben to bypass rendering if there's nada" -if {[empty_string_p $element(content)]} { - ns_log Notice "BMA-debug: empty!" - set empty_p 1 -} else { - set empty_p 0 -} +set include "" +with_catch errmsg { + set code [template::adp_compile -string $include] + set element(content) [string trim [template::adp_eval code]] +} { + ns_log error "portal::element::render error!\n\n$errmsg\n\n" + set element(content) "application error" +}