Index: openacs-4/packages/dotlrn/dotlrn.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn/dotlrn.info,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn/dotlrn.info 20 Sep 2001 18:29:35 -0000 1.1 @@ -0,0 +1,58 @@ + + + + + dotLRN + dotLRN + f + f + + + + oracle + postgresql + + OpenForce dotLRN + An Education Management tool + 2001-10-01 + OpenForce + Class Management + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: openacs-4/packages/dotlrn/sql/oracle/dotlrn-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn/sql/oracle/dotlrn-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn/sql/oracle/dotlrn-create.sql 20 Sep 2001 18:29:35 -0000 1.1 @@ -0,0 +1,50 @@ + +-- +-- The DotLRN basic system +-- copyright 2001, OpenForce, Inc. +-- distributed under the GNU GPL v2 +-- +-- for Oracle 8/8i. (We're guessing 9i works, too). +-- +-- ben@openforce.net +-- started August 18th, 2001 +-- + +-- Since a lot of stuff needs to happen to set up a group type, +-- this isn't going to be done at the data model level, it's going to +-- be done in Tcl. Woohoo. + + +-- We do need some basic data model to represent classes, class instances +-- and the associated information there + +create table dotlrn_classes ( + class_key constraint dotlrn_class_class_key_fk + references group_types(group_type) + constraint dotlrn_class_class_key_pk + primary key, + node_id constraint dotlrn_class_node_id_fk + references site_nodes (node_id) +); + +create table dotlrn_class_instances ( + class_instance_id constraint dotlrn_class_i_id_fk + references groups(group_id) + constraint dotlrn_class_i_id_pk + primary key, + class_instance_key varchar(100) not null + constraint dotlrn_class_i_key_un unique, + class_key constraint dotlrn_class_i_class_key_fk + references dotlrn_classes(class_key), + node_id constraint dotlrn_class_i_node_id_fk + references site_nodes(node_id) +); + +create table dotlrn_class_inst_applets ( + class_instance_id constraint dotlrn_class_i_app_inst_fk + references dotlrn_class_instances(class_instance_id), + applet varchar(200) not null, + constraint dotlrn_class_inst_app_pk primary key (class_instance_id, applet), + node_id constraint dotlrn_c_i_app_node_id_fk + references site_nodes(node_id) +); Index: openacs-4/packages/dotlrn/sql/postgresql/dotlrn-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn/sql/postgresql/dotlrn-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn/sql/postgresql/dotlrn-create.sql 20 Sep 2001 18:29:35 -0000 1.1 @@ -0,0 +1,59 @@ + +-- +-- The DotLRN basic system +-- copyright 2001, OpenForce, Inc. +-- distributed under the GNU GPL v2 +-- +-- ben@openforce.net +-- for PostgreSQL 7.1.2 and above +-- +-- started August 18th, 2001 +-- + + + +-- Since a lot of stuff needs to happen to set up a group type, +-- this isn't going to be done at the data model level, it's going to +-- be done in Tcl. Woohoo. + + +-- We do need some basic data model to represent classes, class instances +-- and the associated information there + +create table dotlrn_classes ( + class_key varchar(100) not null + constraint dotlrn_class_class_key_fk + references group_types(group_type) + constraint dotlrn_class_class_key_pk + primary key, + node_id integer not null + constraint dotlrn_class_node_id_fk + references site_nodes (node_id) +); + +create table dotlrn_class_instances ( + class_instance_id integer not null + constraint dotlrn_class_inst_id_fk + references groups(group_id) + constraint dotlrn_class_inst_id_pk + primary key, + class_instance_key varchar(100) not null + constraint dotlrn_class_inst_key_un unique, + class_key varchar(100) not null + constraint dotlrn_class_inst_class_key_fk + references dotlrn_classes(class_key), + node_id integer not null + constraint dotlrn_class_inst_node_id_fk + references site_nodes(node_id) +); + +create table dotlrn_class_inst_applets ( + class_instance_id integer not null + constraint dotlrn_class_inst_app_inst_fk + references dotlrn_class_instances(class_instance_id), + applet varchar(200) not null, + constraint dotlrn_class_inst_app_pk primary key (class_instance_id, applet), + node_id integer not null + constraint dotlrn_class_inst_app_node_id_fk + references site_nodes(node_id) +); Index: openacs-4/packages/dotlrn/tcl/class-applets-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn/tcl/class-applets-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn/tcl/class-applets-procs.tcl 20 Sep 2001 18:29:35 -0000 1.1 @@ -0,0 +1,77 @@ + +# +# Procs for DOTLRN Class Management, Applets +# Copyright 2001 OpenForce, inc. +# Distributed under the GNU GPL v2 +# +# August 18th, 2001 +# + +ad_library { + + Procs to manage DOTLRN Classes + + @author ben@openforce.net + @creation-date 2001-08-18 + +} + +namespace eval dotlrn_class_applets { + + ad_proc -public register_applet { + name + pretty_name + description + list_of_callbacks + } { + Registers an applet that is available for DOTLRN to manage + + This registers a list of callbacks, in the following form: + {{NEW_CLASS_INSTANCE dotlrn_bboard::new_class_instance} + {GET_PORTLET_CONTENT dotlrn_bboard::get_portlet_content}} + } { + if {[nsv_exists DOTLRN_APPLETS $name]} { + deregister_applet $name + } + + # register things in the global array + nsv_set DOTLRN_APPLETS $name [list $pretty_name $description $list_of_callbacks] + } + + ad_proc -public deregister_applet { + name + } { + Deregisters an applet for DOTLRN + } { + set applet [nsv_get DOTLRN_APPLETS $name] + + # Perform the callback to clean things up before deregistration + call_callback $applet DEREGISTER + + nsv_unset DOTLRN_APPLETS $name + } + + ad_proc -public get_available_applets { + } { + returns the list of available "applets" for DOTLRN. This will usually include + bboard, file-storage, FAQ, etc... + } { + return [nsv_names DOTLRN_APPLETS] + } + + ad_proc call_callback { + applet + callback_name + args + } { + Perform the callback on a particular method for a particular applet + } { + set list_of_callbacks [lindex $applet 2] + + foreach callback $list_of_callbacks { + if {[string equal [lindex $callback 0] $callback_name]} { + eval [lindex $callback 1] $args + } + } + } +} Index: openacs-4/packages/dotlrn/tcl/class-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn/tcl/class-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn/tcl/class-procs.tcl 20 Sep 2001 18:29:35 -0000 1.1 @@ -0,0 +1,133 @@ + +# +# Procs for DOTLRN Class Management +# Copyright 2001 OpenForce, inc. +# Distributed under the GNU GPL v2 +# +# August 18th, 2001 +# + +ad_library { + + Procs to manage DOTLRN Classes + + @author ben@openforce.net + @creation-date 2001-08-18 + +} + +namespace eval dotlrn_class { + + ad_proc -public new { + name + pretty_name + } { + Creates a new class, like "Structure and Interpretation of Computer Programs." + The return value is the short class name, a key that works in SQL, and that uniquely + identifies the class. + + This class can then be instantiated for a particular semester. + } { + set top_group_type [dotlrn::class_group_type_key] + + set parent_node_id [ad_conn -get node_id] + + set group_type_name "DOTLRN_CLASS_$name" + + db_transaction { + # Create a new group type for that class + set one_class_group_type_key [group_type::new -group_type $group_type_name -supertype $top_group_type $pretty_name $pretty_name] + + # Instantiate the DOTLRN Class Manager package at that node + set result [site_node_mount_application -return "package_id,node_id" $parent_node_id $name [package_key] $name] + set package_id [lindex $result 0] + set node_id [lindex $result 1] + + # Set some parameters + ad_parameter -package_id $package_id -set 0 dotlrn_level_p + ad_parameter -package_id $package_id -set 1 class_level_p + ad_parameter -package_id $package_id -set 0 class_instance_level_p + + # insert the class into the DB + db_dml insert_class {} + } + } + + + ad_proc -public new_instance { + class_name + term + year + } { + Creates a new instance of a class for a particular term and year, + and returns the class instance key. + } { + set parent_node_id [db_string select_parent_node_id {}] + set class_inst_key "$class_name-$term-$year" + + # Create a group of the right group type + template::form create add_group + template::element create add_group group_name -value $class_inst_key + template::element create add_group term -value $term + template::element create add_group year -value $year + + set group_id [group::new -form_id add_group $class_name] + + # Instantiate the right package at that site node, probably portals + set result [site_node_mount_application -return "package_id,node_id" $parent_node_id $class_inst_key [one_class_package_key] $class_inst_key] + set package_id [lindex $result 0] + set node_id [lindex $result 1] + + # Set the right parameters + ad_parameter -package_id $package_id -set 0 dotlrn_level_p + ad_parameter -package_id $package_id -set 0 class_level_p + ad_parameter -package_id $package_id -set 1 class_instance_level_p + + # Insert the class instance + db_dml insert_class_instance {} + + # Assign proper permissions to the site node + # NOT CERTAIN what to do here yet + + } + + ad_proc -public assign_role { + class_instance_name + rel_type + user_id + } { + Assigns a user to a particular role for that class. Roles in DOTLRN can be student, prof, ta, admin + } { + # Get the group_id + set group_id [db_string select_group_id {}] + + # Do the right relationship mapping to assigne the role + relation_add $rel_type $group_id $user_id + } + + ad_proc -public add_applet { + class_instance_name + applet_name + } { + Adds an applet for a particular class + } { + # Create the site node for that applet + + # Instantiate the right package at the site node + } + + ad_proc -public package_key { + } { + Returns the package key for this package + } { + return "dotlrn" + } + + ad_proc -public one_class_package_key { + } { + Returns the package key for this package + } { + return "dotlrn" + } + +} \ No newline at end of file Index: openacs-4/packages/dotlrn/tcl/class-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn/tcl/class-procs.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn/tcl/class-procs.xql 20 Sep 2001 18:29:35 -0000 1.1 @@ -0,0 +1,32 @@ + + + + + + +insert into dotlrn_classes (class_key, node_id) values (:one_class_group_type_key, :node_id) + + + + + +select node_id from dotlrn_classes where class_key=:class_name + + + + + +insert into dotlrn_class_instances + (class_instance_id, class_instance_key, class_key, node_id) +values + (:group_id, :class_inst_key, :class_name, :node_id) + + + + + +select class_instance_id from dotlrn_class_instances where class_instance_key= :class_instance_name + + + + Index: openacs-4/packages/dotlrn/tcl/dotlrn-filter.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn/tcl/dotlrn-filter.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn/tcl/dotlrn-filter.tcl 20 Sep 2001 18:29:35 -0000 1.1 @@ -0,0 +1,31 @@ + +# +# Procs for DOTLRN filters +# Copyright 2001 OpenForce, inc. +# Distributed under the GNU GPL v2 +# +# August 20th, 2001 +# + +ad_library { + + Procs for basic dotLRN filters + + @author ben@openforce.net + @creation-date 2001-08-20 + +} + +ad_proc -private dotlrn_filter {conn arg why} { + A filter for dotLRN +} { + ns_log Notice "dotLRN filter activated!!! Data as follows: +package_id: [ad_conn package_id] +url: [ad_conn url] +node_id: [ad_conn node_id] +package_key: [ad_conn package_key] +path_info: [ad_conn path_info] +" + +return filter_ok +} Index: openacs-4/packages/dotlrn/tcl/dotlrn-init.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn/tcl/dotlrn-init.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn/tcl/dotlrn-init.tcl 20 Sep 2001 18:29:35 -0000 1.1 @@ -0,0 +1,21 @@ + + +# +# Procs for initializing DOTLRN basic system +# Copyright 2001 OpenForce, inc. +# Distributed under the GNU GPL v2 +# +# August 20th, 2001 +# + +ad_library { + + Procs for initializing basic dotLRN + + @author ben@openforce.net + @creation-date 2001-08-18 + +} + +ad_register_filter preauth GET /* dotlrn_filter + Index: openacs-4/packages/dotlrn/tcl/dotlrn-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn/tcl/Attic/dotlrn-procs-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn/tcl/dotlrn-procs-oracle.xql 20 Sep 2001 18:29:35 -0000 1.1 @@ -0,0 +1,12 @@ + + + +oracle8.1.6 + + + +begin acs_rel_type.create_role(role => :role, pretty_name => :pretty_name, pretty_plural => :pretty_plural); end; + + + + Index: openacs-4/packages/dotlrn/tcl/dotlrn-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn/tcl/Attic/dotlrn-procs-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn/tcl/dotlrn-procs-postgresql.xql 20 Sep 2001 18:29:35 -0000 1.1 @@ -0,0 +1,12 @@ + + + +postgresql7.1 + + + +select acs_rel_type__create_role(:role_key, :pretty_name, :pretty_plural) + + + + Index: openacs-4/packages/dotlrn/tcl/dotlrn-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn/tcl/dotlrn-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn/tcl/dotlrn-procs.tcl 20 Sep 2001 18:29:35 -0000 1.1 @@ -0,0 +1,134 @@ + +# +# Procs for DOTLRN basic system +# Copyright 2001 OpenForce, inc. +# Distributed under the GNU GPL v2 +# +# August 18th, 2001 +# + +ad_library { + + Procs for basic dotLRN + + @author ben@openforce.net + @creation-date 2001-08-18 + +} + +namespace eval dotlrn { + + ad_proc install { + } { + This installs the DOTLRN Class System. There is a lot of stuff that needs to + be set up to do this correctly, so it must be done at the Tcl Level. + + This proc can be called multiple times, it will do the right thing. + + It will error out in case of impossible to solve issues. + } { + + # If we've already set things up, bail + set group_type_key [ad_parameter class_group_type_key] + if {![empty_string_p $group_type_key]} { + if {[db_string check_group_type_exist {}] == 1} { + return + } + } + + # If lower levels, no install + if {[ad_parameter class_level_p] == 1 || [ad_parameter class_instance_level_p] == 1} { + return + } + + # Make sure we don't call this proc multiple times simultaneously + ## We should really add a critical section here + + # Set up the Class group type + set group_type_key [group_type::new -group_type "dotlrn_class" "dotLRN Class" "dotLRN Classes"] + + # Store the group_type_key somewhere for future reference + ad_parameter -set $group_type_key class_group_type_key + ad_parameter -set 1 dotlrn_level_p + ad_parameter -set 0 class_level_p + ad_parameter -set 0 class_instance_level_p + + # Set up the attributes + set term_attr_id [attribute::add -min_n_values 1 -max_n_values 1 $group_type_key enumeration Term Terms] + set year_attr_id [attribute::add -min_n_values 1 -max_n_values 1 $group_type_key integer Year Years] + + # Add years 2001-2020 as capabilities in system + for {set year 2001} {$year < 2020} {incr year} { + attribute::value_add $year_attr_id $year $year + } + + # Set up some relationship types and permissible relationships + + # Set up some roles + set roles { + {instructor Instructor Instructors} + {ta "Teaching Assistant" "Teaching Assistants"} + {student Student Students} + {admin Administrator Administrators} + } + + foreach role $roles { + set role_key [lindex $role 0] + set pretty_name [lindex $role 1] + set pretty_plural [lindex $role 2] + + db_exec_plsql add_role {} + } + + # The Instructor relationship comes from membership_rel + rel_types::new -supertype "membership_rel" -role_two instructor \ + instruction_rel Instruction Instructions \ + $group_type_key 0 "" \ + person 0 "" + + # The Assistant relationship comes from membership_rel, too + rel_types::new -supertype "membership_rel" -role_two ta \ + assistance_rel Assistance Assistance \ + $group_type_key 0 "" \ + person 0 "" + + # The Student relationship comes from membership_rel, too + rel_types::new -supertype "membership_rel" -role_two student \ + student_rel Student Students \ + $group_type_key 0 "" \ + person 0 "" + + # The Admin relationship, same thing. + rel_types::new -supertype "membership_rel" -role_two admin \ + administration_rel Administration Administrations \ + $group_type_key 0 "" \ + person 0 "" + + # Add permissible relationships + rel_types::add_permissible $group_type_key instruction_rel + rel_types::add_permissible $group_type_key assistance_rel + rel_types::add_permissible $group_type_key student_rel + rel_types::add_permissible $group_type_key administration_rel + + # Remove the default permissible rels + rel_types::remove_permissible $group_type_key membership_rel + rel_types::remove_permissible $group_type_key composition_rel + + } + + ad_proc -public class_group_type_key { + } { + Returns the group_type key that is being used for class management + } { + return [ad_parameter class_group_type_key] + } + + ad_proc -public node_id { + {-package_id ""} + } { + Returns the node ID of the current dotLRN package + } { + ## TOTAL HACK (BEN!!) + return 0 + } +} Index: openacs-4/packages/dotlrn/tcl/dotlrn-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn/tcl/dotlrn-procs.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn/tcl/dotlrn-procs.xql 20 Sep 2001 18:29:35 -0000 1.1 @@ -0,0 +1,11 @@ + + + + + + +select count(*) from acs_object_types where object_type=:group_type_key + + + + Index: openacs-4/packages/dotlrn/www/class-new-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn/www/Attic/class-new-2.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn/www/class-new-2.tcl 20 Sep 2001 18:29:35 -0000 1.1 @@ -0,0 +1,15 @@ + +ad_page_contract { + Create a New Class - processing + + @author Ben Adida (ben@openforce.net) + @creation-date 2001-08-20 +} { + class_key:trim + class_pretty_name:trim +} + +set class_key [dotlrn_class::new $class_key $class_pretty_name] + +ns_returnredirect ./ + Index: openacs-4/packages/dotlrn/www/class-new.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn/www/Attic/class-new.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn/www/class-new.adp 20 Sep 2001 18:29:35 -0000 1.1 @@ -0,0 +1,16 @@ + +dotLRN New Class + +
+ + + + + + + + + +
Class Key (a short name, no spaces):
Class Pretty Name:
+ +
\ No newline at end of file Index: openacs-4/packages/dotlrn/www/class-new.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn/www/Attic/class-new.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn/www/class-new.tcl 20 Sep 2001 18:29:35 -0000 1.1 @@ -0,0 +1,12 @@ + +ad_page_contract { + Create a New Class - input form + + @author Ben Adida (ben@openforce.net) + @creation-date 2001-08-20 +} { +} + + +ad_return_template + Index: openacs-4/packages/dotlrn/www/index-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn/www/Attic/index-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn/www/index-oracle.xql 20 Sep 2001 18:29:35 -0000 1.1 @@ -0,0 +1,12 @@ + + + +oracle8.1.6 + + + +select class_key, node_id, site_node.url(node_id) as url from dotlrn_classes order by class_key + + + + Index: openacs-4/packages/dotlrn/www/index-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn/www/Attic/index-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn/www/index-postgresql.xql 20 Sep 2001 18:29:35 -0000 1.1 @@ -0,0 +1,12 @@ + + + +postgresql7.1 + + + +select class_key, node_id, site_node__url(node_id) as url from dotlrn_classes order by class_key + + + + Index: openacs-4/packages/dotlrn/www/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn/www/index.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn/www/index.adp 20 Sep 2001 18:29:35 -0000 1.1 @@ -0,0 +1,19 @@ + +dotLRN + + +There are no classes available.

+ + + +

+ + +

+

Index: openacs-4/packages/dotlrn/www/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn/www/index.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn/www/index.tcl 20 Sep 2001 18:29:35 -0000 1.1 @@ -0,0 +1,18 @@ + +ad_page_contract { + Displays a list of Classes on the site + + @author Ben Adida (ben@openforce.net) + @creation-date 2001-08-20 +} { +} -properties { + classes:multirow +} + +# Temporary Hack to make sure things are installed +dotlrn::install + +# Select the classes that exist +db_multirow classes select_classes {} + +ad_return_template Index: openacs-4/packages/dotlrn/www/index.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn/www/Attic/index.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn/www/index.xql 20 Sep 2001 18:29:35 -0000 1.1 @@ -0,0 +1,11 @@ + + + + + + +select class_key, node_id, site_node.url(node_id) from dotlrn_classes order by class_key + + + + Index: openacs-4/packages/dotlrn/www/master.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn/www/Attic/master.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn/www/master.adp 20 Sep 2001 18:29:35 -0000 1.1 @@ -0,0 +1,9 @@ + +@title@ + +

@title@

+ + <%= [eval ad_context_bar $context_bar] %> + +
+