You can subscribe to this list here.
| 2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(381) |
Nov
(176) |
Dec
(310) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2002 |
Jan
(334) |
Feb
(96) |
Mar
(149) |
Apr
(214) |
May
(120) |
Jun
(56) |
Jul
(10) |
Aug
(273) |
Sep
(182) |
Oct
(56) |
Nov
(125) |
Dec
(22) |
| 2003 |
Jan
(63) |
Feb
(181) |
Mar
(498) |
Apr
(433) |
May
(39) |
Jun
(512) |
Jul
(276) |
Aug
(156) |
Sep
(101) |
Oct
(66) |
Nov
(24) |
Dec
(161) |
| 2004 |
Jan
(1) |
Feb
(377) |
Mar
(68) |
Apr
(26) |
May
(107) |
Jun
(333) |
Jul
(13) |
Aug
|
Sep
(76) |
Oct
(88) |
Nov
(170) |
Dec
(91) |
| 2005 |
Jan
(52) |
Feb
(239) |
Mar
(402) |
Apr
(15) |
May
(2) |
Jun
(1) |
Jul
(13) |
Aug
|
Sep
(71) |
Oct
(34) |
Nov
|
Dec
|
| 2006 |
Jan
(5) |
Feb
(5) |
Mar
(2) |
Apr
|
May
|
Jun
|
Jul
|
Aug
(3) |
Sep
(7) |
Oct
(2) |
Nov
|
Dec
|
| 2007 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
Update of /cvsroot/openinteract/SPOPS/doc/examples
In directory usw-pr-cvs1:/tmp/cvs-serv23731
Added Files:
object_example_allthemes object_example_misc
object_example_users object_fieldalter_asrule
object_fieldalter_config object_fieldalter_inmethod
object_fieldmap_config object_fieldmap_usage
object_lazyload_config object_lazyload_fetch
object_lazyload_usage object_multivalue_config
object_multivalue_usage object_simple_cgi_create
object_simple_cgi_display object_simple_cgi_fetchgroup
object_simple_cgi_related object_strictfield_define
object_strictfield_errormsg security_get_users_groups
serial_storable_user
Log Message:
added new examples from docs
--- NEW FILE: object_example_allthemes ---
# Retrieve all themes and print a description
my $themes = eval { $theme_class->fetch_group( { order => 'title' } ) };
if ( $@ ) { ... report error ... }
else {
foreach my $thm ( @{ $themes } ) {
print "Theme: $thm->{title}\n",
"Description: $thm->{description}\n";
}
}
--- NEW FILE: object_example_misc ---
# Create a new object with initial values, set another value and save
my $data = MyClass->new({ field1 => 'value1',
field2 => 'value2' });
print "The value for field2 is: $data->{field2}\n";
$data->{field3} = 'value3';
eval { $data->save };
if ( $@ ) { ... report error ... }
# Remove the object permanently
eval { $data->remove };
if ( $@ ) { ... report error ... }
# Call arbitrary object methods to get other objects
my $other_obj = eval { $data->call_to_get_other_object() };
if ( $@ ) { ... report error ... }
# Clone the object with an overridden value and save
my $new_data = $data->clone({ field1 => 'new value' });
eval { $new_data->save };
if ( $@ ) { ... report error ... }
# $new_data is now its own hashref of data --
# explore the fields/values in it
while ( my ( $k, $v ) = each %{ $new_data } ) {
print "$k == $v\n";
}
# Retrieve saved data
my $saved_data = eval { MyClass->fetch( $id ) };
if ( $@ ) { ... report error ... }
else {
while ( my ( $k, $v ) = each %{ $saved_data } ) {
print "Value for $k with ID $id is $v\n";
}
}
# Retrieve lots of objects, display a value and call a
# method on each
my $data_list = eval { MyClass->fetch_group({
where => "last_name like 'winter%'" }) };
if ( $@ ) { ... report error ... }
else {
foreach my $obj ( @{ $data_list } ) {
print "Username: $obj->{username}\n";
$obj->increment_login();
}
}
--- NEW FILE: object_example_users ---
# Create a new user, set some values and save
my $user = $user_class->new;
$user->{email} = 'my...@us...';
$user->{first_name} = 'My';
$user->{last_name} = 'User';
my $user_id = eval { $user->save };
if ( $@ ) {
print "There was an error: $SPOPS::Error::system_msg\n"
}
# Retrieve that same user from the database
my $user_id = $cgi->param( 'user_id' );
my $user = eval { $user_class->fetch( $user_id ) };
if ( $@ ) { ... report error ... }
else {
print "The user's first name is: $user->{first_name}\n";
}
--- NEW FILE: object_fieldalter_asrule ---
sub ruleset_add {
my ( $class, $rs_table ) = @_;
push @{ $rs_table->{post_fetch_action} }, \&manipulate_date;
return ref $class || $class;
}
sub manipulate_date {
my ( $self, $p ) = @_;
return 1 unless ( $self->{start_date} );
my $start_date_object = Class::Date->new( $self->{start_date} );
local $Class::Date::DATE_FORMAT = '%Y/%m/%d %I:%M %p';
$self->{start_date} = "$start_date_object";
}
--- NEW FILE: object_fieldalter_config ---
my $config = {
myobject => {
class => 'My::SPOPS',
field => [ qw/ my_id my_name my_date / ],
field_alter => { my_date => "DATE_FORMAT( my_date, '%Y/%m/%d %I:%i %p' )" },
...,
},
};
--- NEW FILE: object_fieldalter_inmethod ---
my $alter = { my_date => "DATE_FORMAT( my_date, '%Y/%m/%d %I:%i %p' )" };
my $object = My::SPOPS->fetch( $object_id, { field_alter => $alter } );
--- NEW FILE: object_fieldmap_config ---
field_map => { 'last_name' => 'sn',
'first_name' => 'givenname',
'password' => 'userpassword',
'login_name' => 'uid',
'email' => 'mail',
'user_id' => 'cn' }
--- NEW FILE: object_fieldmap_usage ---
sub display_user_data {
my ( $user ) = @_;
return <<INFO;
ID: $user->{user_id}
Name: $user->{first_name} $user->{last_name}
Login: $user->{login_name}
Email: $user->{email}
INFO
}
print display_user_data( $my_ldap_user );
print display_user_data( $my_dbi_user );
--- NEW FILE: object_lazyload_config ---
$spops = {
html_page => {
class => 'My::HTMLPage',
isa => [ qw/ SPOPS::DBI::Pg SPOPS::DBI / ],
field => [ qw/ page_id location title author content / ],
column_group => { listing => [ qw/ location title author / ] },
...
},
};
--- NEW FILE: object_lazyload_fetch ---
my $page_list = My::HTMLPage->fetch_group({ order => 'location',
column_group => 'listing' });
--- NEW FILE: object_lazyload_usage ---
foreach my $page ( @{ $page_list } ) {
# These properties are in the fetched object and are not
# lazy-loaded
print "Title: $page->{title}\n",
"Author: $page->{author}\n";
# When we access lazy-loaded properties like 'content', SPOPS goes
# and retrieves the value for each object property as it's
# requested.
if ( $title =~ /^OpenInteract/ ) {
print "Content\n\n$page->{content}\n";
}
}
--- NEW FILE: object_multivalue_config ---
multivalue => [ 'field1', 'field2' ]
--- NEW FILE: object_multivalue_usage ---
my $object = My::Object->new;
# Set field1 to [ 'a', 'b' ]
$object->{field1} = [ 'a', 'b' ];
# Replace the value of 'a' with 'z'
$object->{field1} = { replace => { a => 'z' } };
# Add the value 'c'
$object->{field1} = 'c';
# Find only the ones I want
my @ones = grep { that_i_want( $_ ) } @{ $object->{field1} };
--- NEW FILE: object_simple_cgi_create ---
my $q = new CGI;
my $obj = MyUserClass->new();
foreach my $field ( qw( f_name l_name birthdate ) ) {
$obj->{ $field } = $q->param( $field );
}
my $object_id = eval { $obj->save };
if ( $@ ) {
... report error information ...
}
else {
warn " Object saved with ID: $obj->{object_id}\n";
}
--- NEW FILE: object_simple_cgi_display ---
my $q = new CGI;
my $object_id = $q->param( 'object_id' );
my $obj = MyUserClass->fetch( $object_id );
print "First Name: $obj->{f_name}\n",
"Last Name: $obj->{l_name}\n",
"Birthday: $obj->{birthdate}\n";
--- NEW FILE: object_simple_cgi_fetchgroup ---
my $q = new CGI;
my $last_name = $q->param( 'last_name' );
my $user_list = MyUserClass->fetch_group({ where => 'l_name LIKE ?',
value => [ "%$last_name%" ],
order => 'birthdate' });
print "Users with last name having: $last_name\n";
foreach my $user ( @{ $user_list } ) {
print " $user->{f_name} $user->{l_name} -- $user->{birthdate}\n";
}
--- NEW FILE: object_simple_cgi_related ---
my $user_group = $obj->group;
print "Group Name: $user_group->{name}\n";
--- NEW FILE: object_strictfield_define ---
$spops = {
user => {
class => 'My::User',
isa => [ qw/ SPOPS::DBI::Pg SPOPS::DBI / ],
field => [ qw/ first_name last_name login / ],
strict_field => 1,
...
},
};
...
my $user = My::User->new;
$user->{firstname} = 'Chucky';
--- NEW FILE: object_strictfield_errormsg ---
Error setting value for field (firstname): it is not a valid field
at my_tie.pl line 9
--- NEW FILE: security_get_users_groups ---
# Note that 'login_name' is not required as a parameter; this is just
# an example
my $user_members = eval { $group->user };
foreach my $user ( @{ $user_members } ) {
print "Username is $user->{login_name}\n";
}
# Note that 'name' is not required as a parameter; this is just an
# example
my $groups = eval { $user->group };
foreach my $group ( @{ $groups } ) {
print "Group name is $group->{name}\n";
}
--- NEW FILE: serial_storable_user ---
# Fetch the user object and if retrieved, store it in the session
my $session = $session_class->create;
my $login_name = read_login_name();
my $user = eval { $user_class->fetch_by_login_name( $login_name ) };
if ( $@ ) { ... }
$session->{user_object} = $user->store;
# ... time passes ...
my $session = $session_class->fetch( $session_id );
my ( $user );
if ( $session->{user_object} ) {
$user = $user_class->retrieve( $session->{user_object} );
}
else {
my $login_name = read_login_name();
my $user = eval { $user_class->fetch_by_login_name( $login_name ) };
...
}
|
Update of /cvsroot/openinteract/SPOPS/doc/Manual
In directory usw-pr-cvs1:/tmp/cvs-serv23215/doc/Manual
Modified Files:
Configuration.pod Datasource.pod Error.pod Intro.pod
Object.pod ObjectRules.pod Relationships.pod Security.pod
Serialization.pod
Log Message:
lots of doc updates (some just intro to the manual section, some
beefup and moving examples to examples/ dir)
Index: Configuration.pod
===================================================================
RCS file: /cvsroot/openinteract/SPOPS/doc/Manual/Configuration.pod,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** Configuration.pod 2001/10/12 05:39:13 1.5
--- Configuration.pod 2001/10/12 19:39:07 1.6
***************
*** 3,6 ****
--- 3,31 ----
SPOPS::Manual::Configuration - Description of variables used in the SPOPS configuration process
+ =head1 DESCRIPTION
+
+ This document aims to answer the questions:
+
+ =over 4
+
+ =item *
+
+ What configuration options are available for SPOPS objects?
+
+ =item *
+
+ How do I modify configuration options?
+
+ =item *
+
+ How can I get to the configuration items once the object class is
+ operational?
+
+ =item *
+
+ How can I add new configuration items?
+
+ =back
+
=head1 GENERAL CONFIGURATION
***************
*** 151,154 ****
--- 176,183 ----
=head1 SPOPS::DBI CONFIGURATION
+ This section describes configuration keys that are used differently by
+ L<SPOPS::DBI|SPOPS::DBI> than the default, as well as new
+ configuration keys used only by L<SPOPS::DBI|SPOPS::DBI>.
+
=head2 General Configuration Fields
***************
*** 235,240 ****
base_dn => 'ou=Equipment,dc=MyCompany,dc=com'
! Note that L<SPOPS::LDAP::MultiDatasource> allows you to specify a
! partial DN on a per-datasource basis.
B<ldap_object_class> (\@)
--- 264,269 ----
base_dn => 'ou=Equipment,dc=MyCompany,dc=com'
! Note that L<SPOPS::LDAP::MultiDatasource|SPOPS::LDAP::MultiDatasource>
! allows you to specify a partial DN on a per-datasource basis.
B<ldap_object_class> (\@)
Index: Datasource.pod
===================================================================
RCS file: /cvsroot/openinteract/SPOPS/doc/Manual/Datasource.pod,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** Datasource.pod 2001/10/12 05:39:13 1.3
--- Datasource.pod 2001/10/12 19:39:07 1.4
***************
*** 5,8 ****
--- 5,26 ----
=head1 DESCRIPTION
+ This document aims to answer the questions:
+
+ =over 4
+
+ =item *
+
+ What is a datastore?
+
+ =item *
+
+ How do SPOPS objects access the datastore?
+
+ =item *
+
+ How do I implement a datastore connection manager?
+
+ =back
+
=head1 COPYRIGHT
Index: Error.pod
===================================================================
RCS file: /cvsroot/openinteract/SPOPS/doc/Manual/Error.pod,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** Error.pod 2001/10/12 05:39:13 1.4
--- Error.pod 2001/10/12 19:39:07 1.5
***************
*** 73,77 ****
=head1 EXAMPLES
! [% INCLUDE examples/error_fetch %]
=head1 COPYRIGHT
--- 73,77 ----
=head1 EXAMPLES
! [% INCLUDE examples/error_fetch | linenum %]
=head1 COPYRIGHT
Index: Intro.pod
===================================================================
RCS file: /cvsroot/openinteract/SPOPS/doc/Manual/Intro.pod,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** Intro.pod 2001/10/12 05:39:13 1.3
--- Intro.pod 2001/10/12 19:39:07 1.4
***************
*** 5,10 ****
=head1 DESCRIPTION
! =head2 Class Hierarchy
SPOPS (Simple Perl Object Persistence with Security) provides a
framework to make your application objects persistent (meaning, you
--- 5,28 ----
=head1 DESCRIPTION
! This document aims to answer the questions:
!
! =over 4
!
! =item *
!
! What needs does SPOPS fill?
!
! =item *
!
! Why would I use SPOPS?
!
! =item *
+ How does everything broadly fit together?
+
+ =back
+
+ =head1 CLASS HIERARCHY
+
SPOPS (Simple Perl Object Persistence with Security) provides a
framework to make your application objects persistent (meaning, you
***************
*** 79,83 ****
=item *
! Persistency State
=back
--- 97,101 ----
=item *
! Persistent State
=back
***************
*** 87,112 ****
the L<tie|tie> mechanism.
! In Persistency State, the object exists in some persistent form, that
! is, it is stored in a database, or written out to a file.
You can control what happens to the object when it gets written to its
persistent form, or when it is deleted, or fetched from its storage
! form, by implementing a simple API: fetch(), save(), remove().
! ------------- save, remove -----------------
! |Runtime State| -------------------> |Persistency State|
! ------------- <------------------ -----------------
fetch
! Around the fetch(), save(), and remove() calls, you can execute helper
! functions (rules in one or more of the following stages: pre_fetch,
! post_fetch, pre_save, post_save, pre_remove, post_remove), in case you
! need to prepare anything or clean up something, according to needs of
! your storage technology. These are pushed on a queue based on a
! search of C<@ISA>, and executed front to end of the queue. If any of
! the calls in a given queue returns a false value, the whole action
! (save, remove, fetch) is short-circuited (that is, a failing method
! bombs out of the action). More information on this is in L<Data
! Manipulation Callbacks: Rulesets> below.
=head1 COPYRIGHT
--- 105,132 ----
the L<tie|tie> mechanism.
! In Persistent State, the object exists in some more permanent form --
! saved in a database, in the filesystem, in a directory, etc.
You can control what happens to the object when it gets written to its
persistent form, or when it is deleted, or fetched from its storage
! form, by implementing a simple API: C<fetch()>, C<save()>,
! C<remove()>.
! ------------- save, remove ----------------
! |Runtime State| -------------------> |Persistent State|
! ------------- <------------------ ----------------
fetch
! Around the C<fetch()>, C<save()>, and C<remove()> calls, you can
! execute helper functions (rules in one or more of the following
! stages: pre_fetch, post_fetch, pre_save, post_save, pre_remove,
! post_remove), in case you need to prepare anything or clean up
! something, according to needs of your storage technology. These are
! pushed on a queue based on a search of C<@ISA>, and executed front to
! end of the queue. If any of the calls in a given queue returns a false
! value, the whole action (save, remove, fetch) is short-circuited (that
! is, a failing method bombs out of the action). See
! L<SPOPS::Manual::ObjectRules|SPOPS::Manual::ObjectRules> for details
! on the process and how to implement your own.
=head1 COPYRIGHT
Index: Object.pod
===================================================================
RCS file: /cvsroot/openinteract/SPOPS/doc/Manual/Object.pod,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** Object.pod 2001/10/12 05:39:13 1.5
--- Object.pod 2001/10/12 19:39:07 1.6
***************
*** 18,61 ****
CGI.pm, set the values into a new SPOPS object and save it:
! my $q = new CGI;
! my $obj = MyUserClass->new();
! foreach my $field ( qw( f_name l_name birthdate ) ) {
! $obj->{ $field } = $q->param( $field );
! }
! my $object_id = eval { $obj->save };
! if ( $@ ) {
! ... report error information ...
! }
! else {
! warn " Object saved with ID: $obj->{object_id}\n";
! }
You can then display this object's information from a later request:
! my $q = new CGI;
! my $object_id = $q->param( 'object_id' );
! my $obj = MyUserClass->fetch( $object_id );
! print "First Name: $obj->{f_name}\n",
! "Last Name: $obj->{l_name}\n",
! "Birthday: $obj->{birthdate}\n";
To display other information from the same object, like related
objects:
! my $user_group = $obj->group;
! print "Group Name: $user_group->{name}\n";
And you can fetch batches of objects at once based on arbitrary
criteria:
! my $q = new CGI;
! my $last_name = $q->param( 'last_name' );
! my $user_list = MyUserClass->fetch_group({ where => 'l_name LIKE ?',
! value => [ "%$last_name%" ],
! order => 'birthdate' });
! print "Users with last name having: $last_name\n";
! foreach my $user ( @{ $user_list } ) {
! print " $user->{f_name} $user->{l_name} -- $user->{birthdate}\n";
! }
=head2 Tie Interface
--- 18,36 ----
CGI.pm, set the values into a new SPOPS object and save it:
! [% INCLUDE examples/object_simple_cgi_create | linenum %]
You can then display this object's information from a later request:
! [% INCLUDE examples/object_simple_cgi_display | linenum %]
To display other information from the same object, like related
objects:
! [% INCLUDE examples/object_simple_cgi_related | linenum %]
And you can fetch batches of objects at once based on arbitrary
criteria:
! [% INCLUDE examples/object_simple_cgi_fetchgroup | linenum %]
=head2 Tie Interface
***************
*** 63,67 ****
This version of SPOPS uses a L<tie|tie> interface to get and set the
individual data values. You can also use the more traditional OO
! I<get> and I<set> operators, but most people will likely find the
hashref interface easier to deal with. It also means you can
interpolate data into strings: bonus!
--- 38,42 ----
This version of SPOPS uses a L<tie|tie> interface to get and set the
individual data values. You can also use the more traditional OO
! C<get> and C<set> operators, but most people will likely find the
hashref interface easier to deal with. It also means you can
interpolate data into strings: bonus!
***************
*** 80,84 ****
--- 55,81 ----
was created or fetched. Property values can also be lazy-loaded.
+ =head2 Automatically Created Accessors
+
+ In addition to getting the data for an object through the hashref
+ method, you can also get to the data with accessors named after the
+ fields.
+
+ For example, given the fields:
+
+ $user->{f_name}
+ $user->{l_name}
+ $user->{birthday}
+
+ You can call to retrieve the data:
+ $user->f_name();
+ $user->l_name();
+ $user->birthday();
+
+ Note that this is only to read the data, not to change it. The system
+ does this using AUTOLOAD, and after the first call it automatically
+ creates a subroutine in the namespace of your class which handles
+ future calls so there is no need for AUTOLOAD on the second or future
+ calls.
=head2 Tracking State Changes
***************
*** 114,141 ****
been any modification, the system will save it, otherwise it will not.
- B<Automatically Created Accessors>
-
- In addition to getting the data for an object through the hashref
- method, you can also get to the data with accessors named after the
- fields.
-
- For example, given the fields:
-
- $user->{f_name}
- $user->{l_name}
- $user->{birthday}
-
- You can call to retrieve the data:
-
- $user->f_name();
- $user->l_name();
- $user->birthday();
-
- Note that this is only to read the data, not to change it. The system
- does this using AUTOLOAD, and after the first call it automatically
- creates a subroutine in the namespace of your class which handles
- future calls so there is no need for AUTOLOAD on the second or future
- calls.
-
=head2 Lazy Loading
--- 111,114 ----
***************
*** 157,177 ****
So when we define our object, we define a column group called
! 'listing' which contains the fields we display when listing the objects:
! $spops = {
! html_page => {
! class => 'My::HTMLPage',
! isa => [ qw/ SPOPS::DBI::Pg SPOPS::DBI / ],
! field => [ qw/ page_id location title author content / ],
! column_group => { listing => [ qw/ location title author / ] },
! ...
! },
! };
And when we retrieve the objects for listing, we pass the column group
name we want to use:
! my $page_list = My::HTMLPage->fetch_group({ order => 'location',
! column_group => 'listing' });
Now each object in C<\@page_list> has the fields 'page_id',
--- 130,142 ----
So when we define our object, we define a column group called
! 'listing' which contains the fields we display when listing the
! objects:
! [% INCLUDE examples/object_lazyload_config | linenum %]
And when we retrieve the objects for listing, we pass the column group
name we want to use:
! [% INCLUDE examples/object_lazyload_fetch | linenum %]
Now each object in C<\@page_list> has the fields 'page_id',
***************
*** 180,200 ****
we try to retrieve the 'content' field, SPOPS will load the value for
that field into the object behind the scenes.
-
- foreach my $page ( @{ $page_list } ) {
! # These properties are in the fetched object and are not
! # lazy-loaded
!
! print "Title: $page->{title}\n",
! "Author: $page->{author}\n";
!
! # When we access lazy-loaded properties like 'content', SPOPS goes
! # and retrieves the value for each object property as it's
! # requested.
!
! if ( $title =~ /^OpenInteract/ ) {
! print "Content\n\n$page->{content}\n";
! }
! }
Obviously, you want to make sure you use this wisely, otherwise you
--- 145,150 ----
we try to retrieve the 'content' field, SPOPS will load the value for
that field into the object behind the scenes.
! [% INCLUDE examples/object_lazyload_usage | linenum %]
Obviously, you want to make sure you use this wisely, otherwise you
***************
*** 222,247 ****
could say:
! field_map => { 'last_name' => 'sn',
! 'first_name' => 'givenname',
! 'password' => 'userpassword',
! 'login_name' => 'uid',
! 'email' => 'mail',
! 'user_id' => 'cn', }
So, despite having entirely different schemas, the following would
print out equivalent information:
! sub display_user_data {
! my ( $user ) = @_;
! return <<INFO;
! ID: $user->{user_id}
! Name: $user->{first_name} $user->{last_name}
! Login: $user->{login_name}
! Email: $user->{email}
! INFO
! }
!
! print display_user_data( $my_ldap_user );
! print display_user_data( $my_dbi_user );
Another use might be to represent properties in a different language.
--- 172,181 ----
could say:
! [% INCLUDE examples/object_fieldmap_config | linenum %]
So, despite having entirely different schemas, the following would
print out equivalent information:
! [% INCLUDE examples/object_fieldmap_usage | linenum %]
Another use might be to represent properties in a different language.
***************
*** 264,280 ****
First, you can specify the information in your object configuration:
! my $config = {
! myobject => {
! class => 'My::SPOPS',
! field => [ qw/ my_id my_name my_date / ],
! field_alter => { my_date => "DATE_FORMAT( my_date, '%Y/%m/%d %I:%i %p' )" },
! ...,
! },
! };
Second, you can pass the information in on a per-object basis:
! my $alter = { my_date => "DATE_FORMAT( my_date, '%Y/%m/%d %I:%i %p' )" };
! my $object = My::SPOPS->fetch( $object_id, { field_alter => $alter } );
Both will have exactly the same effect.
--- 198,206 ----
First, you can specify the information in your object configuration:
! [% INCLUDE examples/object_fieldalter_config | linenum %]
Second, you can pass the information in on a per-object basis:
! [% INCLUDE examples/object_fieldalter_inmethod | linenum %]
Both will have exactly the same effect.
***************
*** 282,299 ****
So, how would you do this in Perl and SPOPS? You would likely create
a post_fetch rule that did whatever data manipulation you wanted:
-
- sub ruleset_add {
- my ( $class, $rs_table ) = @_;
- push @{ $rs_table->{post_fetch_action} }, \&manipulate_date;
- return ref $class || $class;
- }
! sub manipulate_date {
! my ( $self, $p ) = @_;
! return 1 unless ( $self->{start_date} );
! my $start_date_object = Class::Date->new( $self->{start_date} );
! local $Class::Date::DATE_FORMAT = '%Y/%m/%d %I:%M %p';
! $self->{start_date} = "$start_date_object";
! }
See L<SPOPS::Manual::ObjectRules|SPOPS::Manual::ObjectRules> for more
--- 208,213 ----
So, how would you do this in Perl and SPOPS? You would likely create
a post_fetch rule that did whatever data manipulation you wanted:
! [% INCLUDE examples/object_fieldalter_asrule | linenum %]
See L<SPOPS::Manual::ObjectRules|SPOPS::Manual::ObjectRules> for more
***************
*** 308,329 ****
should be multivalued:
! multivalue => [ 'field1', 'field2' ]
Thereafter you can access them as below (more examples in
L<SPOPS::Tie|SPOPS::Tie>):
-
- my $object = My::Object->new;
-
- # Set field1 to [ 'a', 'b' ]
- $object->{field1} = [ 'a', 'b' ];
-
- # Replace the value of 'a' with 'z'
- $object->{field1} = { replace => { a => 'z' } };
! # Add the value 'c'
! $object->{field1} = 'c';
!
! # Find only the ones I want
! my @ones = grep { that_i_want( $_ ) } @{ $object->{field1} };
Note that the value returned from a field access to a multivalue field
--- 222,231 ----
should be multivalued:
! [% INCLUDE examples/object_multivalue_config %]
Thereafter you can access them as below (more examples in
L<SPOPS::Tie|SPOPS::Tie>):
! [% INCLUDE examples/object_multivalue_usage %]
Note that the value returned from a field access to a multivalue field
***************
*** 337,450 ****
the configuration option 'strict_field'. For instance:
- $spops = {
- user => {
- class => 'My::User',
- isa => [ qw/ SPOPS::DBI::Pg SPOPS::DBI / ],
- field => [ qw/ first_name last_name login / ],
- strict_field => 1,
- ...
- },
- };
- ...
- my $user = My::User->new;
- $user->{firstname} = 'Chucky';
-
would result in a message to STDERR, something like:
! Error setting value for field (firstname): it is not a valid field
! at my_tie.pl line 9
! since you have misspelled the property, which should be
! 'first_name'. Note that SPOPS will continue working and will not 'die'
! on such an error, just issue a warning.
=head2 More Examples
-
- # Retrieve all themes and print a description
-
- my $themes = eval { $theme_class->fetch_group( { order => 'title' } ) };
- if ( $@ ) { ... report error ... }
- else {
- foreach my $thm ( @{ $themes } ) {
- print "Theme: $thm->{title}\n",
- "Description: $thm->{description}\n";
- }
- }
-
- # Create a new user, set some values and save
-
- my $user = $user_class->new;
- $user->{email} = 'my...@us...';
- $user->{first_name} = 'My';
- $user->{last_name} = 'User';
- my $user_id = eval { $user->save };
- if ( $@ ) {
- print "There was an error: ", $R->error->report(), "\n";
- }
-
- # Retrieve that same user from the database
-
- my $user_id = $cgi->param( 'user_id' );
- my $user = eval { $user_class->fetch( $user_id ) };
- if ( $@ ) { ... report error ... }
- else {
- print "The user's first name is: $user->{first_name}\n";
- }
-
- # Create a new object with initial values, set another value and save
-
- my $data = MyClass->new({ field1 => 'value1',
- field2 => 'value2' });
- print "The value for field2 is: $data->{field2}\n";
- $data->{field3} = 'value3';
- eval { $data->save };
- if ( $@ ) { ... report error ... }
-
- # Remove the object permanently
-
- eval { $data->remove };
- if ( $@ ) { ... report error ... }
-
- # Call arbitrary object methods to get other objects
-
- my $other_obj = eval { $data->call_to_get_other_object() };
- if ( $@ ) { ... report error ... }
-
- # Clone the object with an overridden value and save
! my $new_data = $data->clone({ field1 => 'new value' });
! eval { $new_data->save };
! if ( $@ ) { ... report error ... }
!
! # $new_data is now its own hashref of data --
! # explore the fields/values in it
!
! while ( my ( $k, $v ) = each %{ $new_data } ) {
! print "$k == $v\n";
! }
!
! # Retrieve saved data
!
! my $saved_data = eval { MyClass->fetch( $id ) };
! if ( $@ ) { ... report error ... }
! else {
! while ( my ( $k, $v ) = each %{ $saved_data } ) {
! print "Value for $k with ID $id is $v\n";
! }
! }
! # Retrieve lots of objects, display a value and call a
! # method on each
! my $data_list = eval { MyClass->fetch_group({
! where => "last_name like 'winter%'" }) };
! if ( $@ ) { ... report error ... }
! else {
! foreach my $obj ( @{ $data_list } ) {
! print "Username: $obj->{username}\n";
! $obj->increment_login();
! }
! }
=head1 COPYRIGHT
--- 239,258 ----
the configuration option 'strict_field'. For instance:
+ [% INCLUDE examples/object_strictfield_define | linenum %]
would result in a message to STDERR, something like:
! [% INCLUDE examples/object_strictfield_errormsg | linenum %]
! since you have misspelled the property. Note that SPOPS will continue
! working and will not 'die' on such an error, just issue a warning.
=head2 More Examples
! [% INCLUDE examples/object_example_allthemes %]
! [% INCLUDE examples/object_example_users %]
! [% INCLUDE examples/object_example_misc %]
=head1 COPYRIGHT
***************
*** 457,459 ****
Chris Winters <ch...@cw...>
-
--- 265,266 ----
Index: ObjectRules.pod
===================================================================
RCS file: /cvsroot/openinteract/SPOPS/doc/Manual/ObjectRules.pod,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** ObjectRules.pod 2001/10/12 05:39:13 1.3
--- ObjectRules.pod 2001/10/12 19:39:07 1.4
***************
*** 5,18 ****
=head1 DESCRIPTION
! =head1 DATA MANIPULATION CALLBACKS: RULESETS
! When a SPOPS object calls fetch/save/remove, the base class takes care
! of most of the details for retrieving and constructing the
! object. However, sometimes you want to do something more complex or
! different. Each data manipulation method allows you to define two
! methods to accomplish these things. One is called before the action is
! taken (usually at the very beginning of the action) and the other
! after the action has been successfully completed.
What kind of actions might you want to accomplish? Cascading deletes
(when you delete one object, delete a number of dependent objects as
--- 5,41 ----
=head1 DESCRIPTION
! This document aims to answer the questions:
! =over 4
!
! =item *
!
! What is a rule?
!
! =item *
!
! What can a rule do?
!
! =item *
!
! What is a ruleset?
!
! =item *
!
! How do I implement a rule?
!
! =back
!
! =head1 RULES AND RULESETS DEFINED
+ When a SPOPS object calls C<save()>, C<fetch()>, or C<remove()>, the
+ implementing class (e.g., L<SPOPS::DBI|SPOPS::DBI>) takes care of most
+ of the details for retrieving and constructing the object. However,
+ sometimes you want to do something more complex or different. Each
+ data manipulation method allows you to define two methods to
+ accomplish these things. One is called before the action is taken
+ (usually at the very beginning of the action) and the other after the
+ action has been successfully completed.
+
What kind of actions might you want to accomplish? Cascading deletes
(when you delete one object, delete a number of dependent objects as
***************
*** 20,28 ****
component objects as well); implement a consistent data layer (such as
full-text searching) by sending all inserts and updates to a separate
! module or daemon. Whatever.
! Each of these actions is a rule, and together they are rulesets. There
! are some fairly simple guidelines to rules:
=over 4
--- 43,55 ----
component objects as well); implement a consistent data layer (such as
full-text searching) by sending all inserts and updates to a separate
! module or daemon; data validation (by submitting the data in the
! object to a rules engine). Whatever -- it's up to you.
! Each of these actions is a rule, and together they are rulesets.
+ =head2 Rule Guidelines
+
+ There are some fairly simple guidelines to rules:
+
=over 4
***************
*** 50,57 ****
say on whether a particular object is fetched, saved or removed.
=back
! For example, you may want to implement a 'layer' over certain classes
! of data. Perhaps you want to collect how many times users from various
groups visit a set of objects on your website. You can create a fairly
simple class that puts a rule into the ruleset of its children that
--- 77,90 ----
say on whether a particular object is fetched, saved or removed.
+ NOTE: This will probably be dropped in favor of a more flexible scheme
+ that allows non-essential rules to fail without forcing the entire
+ action to fail.
+
=back
! =head2 Rule Uses
!
! Rules enable you to implement a 'layer' over certain classes of
! data. Perhaps you want to collect how many times users from various
groups visit a set of objects on your website. You can create a fairly
simple class that puts a rule into the ruleset of its children that
***************
*** 67,76 ****
data of the row that is being manipulated, whereas a rule should not.
! B<pre_fetch_action( { id =E<gt> $ } )>
Called before a fetch is done, although if an object is retrieved from
! the cache this action is skipped. The only argument is the ID of the
! object you are trying to fetch.
B<post_fetch_action( \% )>
--- 100,124 ----
data of the row that is being manipulated, whereas a rule should not.
! =head2 Rules and Aspects
!
! Another useful way to think of rules is in terms of aspect oriented
! programming (AOP). AOP works in conjunction with other methods of
! programming (object-oriented, procedural, functional) and allows you
! to create joinpoints at which you perform actions with and on
! different types of data.
+ #TODO: Put reference URL here and/or Aspect CPAN link
+
+ =head1 RULESET HOOKS
+
+ B<pre_fetch_action({ id =E<gt> $ })>
+
Called before a fetch is done, although if an object is retrieved from
! the cache this action is skipped. (NOTE: THIS MIGHT NOT BE TRUE -- WE
! NEED TO IMPLEMENT CACHING AND SEE HOW THIS WORKS IN REALITY.) The only
! argument is the ID of the object you are trying to fetch.
+ This hook is generally not used very often.
+
B<post_fetch_action( \% )>
***************
*** 78,87 ****
a positive cache hit.
! B<pre_save_action( { is_add =E<gt>; bool } )>
Called before a save has been attempted. If this is an add operation
(versus an update), we pass in a true value for the 'is_add' parameter.
! B<post_save_action( { is_add =E<gt> bool } )>
Called after a save has been successfully completed. If this object
--- 126,135 ----
a positive cache hit.
! B<pre_save_action( is_add =E<gt>; bool })>
Called before a save has been attempted. If this is an add operation
(versus an update), we pass in a true value for the 'is_add' parameter.
! B<post_save_action({ is_add =E<gt> bool })>
Called after a save has been successfully completed. If this object
***************
*** 97,107 ****
Called after a remove has been successfully completed.
B<ruleset_add( $class, \%class_ruleset )>
! Interface for adding rulesets to a class. The first argument is the
! class to which we want to add the ruleset, the second is the ruleset
! for the class. The ruleset is simply a hash reference with keys as the
! methods named above ('pre_fetch_action', etc.) pointing to an arrayref
! of code references.
This means that every phase named above above ('pre_fetch_action',
--- 145,165 ----
Called after a remove has been successfully completed.
+ =head1 RULE IMPLEMENTATION
+
+ Adding rules to an object class is very simple. You have one simple
+ method to create to add your rule(s) to the ruleset for an object, and
+ then the actual rules.
+
+ =head2 Rule Factory
+
B<ruleset_add( $class, \%class_ruleset )>
! NOTE: THIS METHOD MIGHT BE RENAMED TO 'rule_factory()'
!
! Interface for adding rules to a class. The first argument is the class
! to which we want to add the ruleset, the second is the ruleset for the
! class. The ruleset is simply a hash reference with keys as the methods
! named above ('pre_fetch_action', etc.) pointing to an arrayref of code
! references.
This means that every phase named above above ('pre_fetch_action',
***************
*** 126,132 ****
ensure that the same rule does not get entered multiple times.
B<ruleset_process_action( ($object|$class), $action, \%params )>
! This method executes all the rules in a given ruleset for a give
action. For instance, when called with the action name
'pre_fetch_action' it executes all the rules in that part of the
--- 184,199 ----
ensure that the same rule does not get entered multiple times.
+ NOTE: THIS INTERFACE MAY BE CHANGED TO INSTEAD RETURN THE NAMES
+ (PACKAGE + METHOD) OF ALL ROUTINES ADDED TO THE RULESET.
+
+ =head2 Rule Processor
+
+ You should never have to worry about this since it is implemented in
+ L<SPOPS|SPOPS> and therefore part of every SPOPS class. But it is here
+ for completeness:
+
B<ruleset_process_action( ($object|$class), $action, \%params )>
! This method executes all the rules in a given ruleset for a given
action. For instance, when called with the action name
'pre_fetch_action' it executes all the rules in that part of the
***************
*** 134,137 ****
--- 201,207 ----
Return value is true if all the rules executed ok, false if not.
+
+ NOTE: THIS MAY BE MODIFIED SO THAT EACH RULE CAN REPORT A STATUS WHICH
+ IS AVAILABLE FOR LATER INSPECTION.
=head1 COPYRIGHT
Index: Relationships.pod
===================================================================
RCS file: /cvsroot/openinteract/SPOPS/doc/Manual/Relationships.pod,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** Relationships.pod 2001/10/12 05:39:13 1.3
--- Relationships.pod 2001/10/12 19:39:07 1.4
***************
*** 5,11 ****
=head1 DESCRIPTION
! =head1 HAS_A
! =head1 LINKS_TO
=head1 COPYRIGHT
--- 5,17 ----
=head1 DESCRIPTION
! This document aims to answer the following questions:
! =over 4
!
! =item *
!
! How do I relate objects?
!
! =back
=head1 COPYRIGHT
Index: Security.pod
===================================================================
RCS file: /cvsroot/openinteract/SPOPS/doc/Manual/Security.pod,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** Security.pod 2001/10/12 05:39:13 1.4
--- Security.pod 2001/10/12 19:39:07 1.5
***************
*** 11,14 ****
--- 11,40 ----
provide some concrete examples.
+ This document should answer the following questions:
+
+ =over 4
+
+ =item *
+
+ How does security work?
+
+ =item *
+
+ How does security use users and groups?
+
+ =item *
+
+ How does SPOPS implement security?
+
+ =item *
+
+ How can I implement security?
+
+ =item *
+
+ How can I customize security?
+
+ =back
+
=head1 OVERVIEW
***************
*** 90,94 ****
------------------------------------------------
! >From this, we can say:
=over 4
--- 116,120 ----
------------------------------------------------
! From this, we can say:
=over 4
***************
*** 136,155 ****
your user object must implement a method that returns the groups that
user belongs to via the method 'group':
-
- # Note that 'login_name' is not required as a parameter; this is just
- # an example
-
- my $user_members = eval { $group->user };
- foreach my $user ( @{ $user_members } ) {
- print "Username is $user->{login_name}\n";
- }
-
- # Note that 'name' is not required as a parameter; this is just an
- # example
! my $groups = eval { $user->group };
! foreach my $group ( @{ $groups } ) {
! print "Group name is $group->{name}\n";
! }
=item *
--- 162,167 ----
your user object must implement a method that returns the groups that
user belongs to via the method 'group':
! [% INCLUDE examples/security_get_users_groups | linenum %]
=item *
Index: Serialization.pod
===================================================================
RCS file: /cvsroot/openinteract/SPOPS/doc/Manual/Serialization.pod,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** Serialization.pod 2001/10/12 05:39:13 1.5
--- Serialization.pod 2001/10/12 19:39:07 1.6
***************
*** 5,22 ****
=head1 DESCRIPTION
! =head2 Storable Serialization
! Since the main SPOPS class from which all SPOPS objects derive has
! L<Storable|Storable> as a parent, you can call any of its methods from any
! SPOPS object and have a serialized version of your object. You can
! send it over the network, save it for later -- whatever you like.
! Note that this feature appeared starting version 0.39, so if you have
! any issues with it please e-mail the author. There are some issues to
! be worked out with configuration and the like, but it basically just
! works.
! =head1 FAILED ACTIONS
If an action fails, the 'fail' method associated with that action is
triggered. This can be a notification to an administrator, or saving
--- 5,46 ----
=head1 DESCRIPTION
! This part of the SPOPS manual aims to answer the following questions:
! =over 4
! =item *
! How does serialization work?
!
! =item *
!
! How can I customize serialization?
!
! =item *
!
! How does caching work?
!
! =item *
+ How can I lazy-load my fields?
+
+ =back
+
+ =head1 SERIALIZATION BASICS
+
+ =head1 CUSTOMIZING SERIALIZATION
+
+ =head2 Pre/Post Hooks
+
+ SPOPS allows you to create multiple pre- and post-actions to
+ C<save()>, C<fetch()> and C<remove()>. These actions can be as simple
+ or complex as you like and allow objects to be extremely flexible.
+
+ These the actions implemented in the hooks are called rules, and each
+ collection of rules is called a ruleset. Rulesets are documented in
+ L<SPOPS::Manual::ObjectRules|SPOPS::Manual::ObjectRules>.
+
+ =head2 Failed Actions
+
If an action fails, the 'fail' method associated with that action is
triggered. This can be a notification to an administrator, or saving
***************
*** 37,44 ****
=head1 CACHING
! SPOPS has hooks for object caching. As mentioned above, you will need
! to define a B<global_cache> either in your SPOPS object class one of
! its parents. Typically, you will put the I<stash class> in the @ISA of
! your SPOPS object.
B<pre_cache_fetch()>
--- 61,71 ----
=head1 CACHING
! SPOPS has hooks for object caching. You will need to return a caching
! object via the a C<global_cache()> method implemented either in your
! SPOPS object class one of its parents.
!
! The caching object will have a simple interface so it's easy to wrap
! it around your favorite caching backend. (Who wants to write this
! stuff from scratch themselves?)
B<pre_cache_fetch()>
***************
*** 68,72 ****
Called after an object is successfully removed from the cache.
! =head2 Lazy Loading
This section describes how to implement lazy loading for your objects.
--- 95,99 ----
Called after an object is successfully removed from the cache.
! =head1 LAZY LOADING
This section describes how to implement lazy loading for your objects.
***************
*** 86,94 ****
=back
! Here are the methods to implement lazy loading:
! =over 4
! B<get_lazy_load_sub>
Called by SPOPS when initializing a new object if one or more
--- 113,121 ----
=back
! =head2 What You Need To Do
! Here are the methods you need to create to implement lazy loading:
! B<get_lazy_load_sub()>
Called by SPOPS when initializing a new object if one or more
***************
*** 107,114 ****
includes the ID field and value of the object.
- =back
-
For lazy loading usage, see L<SPOPS::Manual::Object|SPOPS::Manual::Object>.
B<is_loaded( $field )>
--- 134,143 ----
includes the ID field and value of the object.
For lazy loading usage, see L<SPOPS::Manual::Object|SPOPS::Manual::Object>.
+ =head2 What SPOPS does
+
+ These are methods implemented by SPOPS for lazy loading.
+
B<is_loaded( $field )>
***************
*** 135,138 ****
--- 164,193 ----
For an example of how a SPOPS subclass implements lazy-loading, see
L<SPOPS::DBI|SPOPS::DBI>.
+
+ =head1 STORABLE SERIALIZATION
+
+ Since the main SPOPS class from which all SPOPS objects derive has
+ L<Storable|Storable> as a parent, you can call any of the Storable
+ methods from any SPOPS object and have a serialized version of your
+ object. You can send it over the network, save it for later --
+ whatever you like.
+
+ Example:
+
+ [% INCLUDE examples/serial_storable_user | linenum %]
+
+ This has not been extensively tested, particularly with the
+ C<nstore()> option for transporting objects among different
+ architectures. In theory, this shouldn't be an issue at all, as long
+ as when thawing the object the specific SPOPS class has been
+ previously initialized.
+
+ This could be an interesting area of future development, since you
+ could in theory send an object over a network along with a minimal
+ configuration and object definition that, when it reached the
+ C<read_code> section of the code generation, reached out over the
+ network to read in the actual meat of a class. Basically, the thawing
+ routine could check to see if it had processed the SPOPS class and if
+ not, grab it off the network and whip it up.
=head1 COPYRIGHT
|
|
From: Chris W. <la...@us...> - 2001-10-12 19:39:10
|
Update of /cvsroot/openinteract/SPOPS/doc In directory usw-pr-cvs1:/tmp/cvs-serv23215/doc Modified Files: status Log Message: lots of doc updates (some just intro to the manual section, some beefup and moving examples to examples/ dir) Index: status =================================================================== RCS file: /cvsroot/openinteract/SPOPS/doc/status,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** status 2001/10/12 16:09:31 1.1 --- status 2001/10/12 19:39:06 1.2 *************** *** 1,10 **** ! SPOPS::Manual::Intro - Pretty much done. If we add further sections to the manual we'll have to put a pointer here, but other than that... SPOPS::Manual::Object ! - More examples. Otherwise I think the basics are there SPOPS::Manual::Configuration --- 1,17 ---- ! SPOPS::Manual - Pretty much done. If we add further sections to the manual we'll have to put a pointer here, but other than that... + SPOPS::Manual::Intro + + - More overview -- maybe as an example walk through a single request + in pseudocode? + + - Put the ASCII-art in better context, although it's mostly there. + SPOPS::Manual::Object ! - More examples. Otherwise I think the basics are there. SPOPS::Manual::Configuration *************** *** 28,32 **** - Storable example ! - Discuss save(), fetch(), remove SPOPS::Manual::ObjectRules --- 35,39 ---- - Storable example ! - Discuss save(), fetch(), remove() SPOPS::Manual::ObjectRules *************** *** 38,42 **** SPOPS::Manual::Datasource ! - General discussion (what is a datasource) and how we view them SPOPS::Manual::Security --- 45,51 ---- SPOPS::Manual::Datasource ! - General discussion (what is a datasource); how SPOPS views ! datasources; how to create a connection manager (swipe from ! cookbook?) SPOPS::Manual::Security |
|
From: Chris W. <la...@us...> - 2001-10-12 16:11:42
|
Update of /cvsroot/openinteract/OpenInteract/template
In directory usw-pr-cvs1:/tmp/cvs-serv25925
Modified Files:
form_radio
Log Message:
is_pick -> is_picked (duh)
Index: form_radio
===================================================================
RCS file: /cvsroot/openinteract/OpenInteract/template/form_radio,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** form_radio 2001/10/08 20:20:00 1.1
--- form_radio 2001/10/12 16:11:39 1.2
***************
*** 4,7 ****
########################################-%]
! [%- is_picked = ( value == picked ) ? ' SELECTED' : '' -%]
<input type="radio" name="[% name %]" value="[% value %]"[% is_picked %]>
--- 4,7 ----
########################################-%]
! [%- is_picked = ( value == picked ) ? ' CHECKED' : '' -%]
<input type="radio" name="[% name %]" value="[% value %]"[% is_picked %]>
|
|
From: Chris W. <la...@us...> - 2001-10-12 16:09:34
|
Update of /cvsroot/openinteract/SPOPS/doc In directory usw-pr-cvs1:/tmp/cvs-serv25014/doc Added Files: status Log Message: added status of Manual for people who want to help out (hint!) --- NEW FILE: status --- SPOPS::Manual::Intro - Pretty much done. If we add further sections to the manual we'll have to put a pointer here, but other than that... SPOPS::Manual::Object - More examples. Otherwise I think the basics are there SPOPS::Manual::Configuration - More examples - Put examples into external files SPOPS::Manual::CodeGeneration - More examples (use DiscoverFields, talk about metadata discovery) - Discuss strategy SPOPS::Manual::Serialization - Lazy loading example - Failed action example - Storable example - Discuss save(), fetch(), remove SPOPS::Manual::ObjectRules - More examples -- ALL kinds of stuff - Put existing example in external file SPOPS::Manual::Datasource - General discussion (what is a datasource) and how we view them SPOPS::Manual::Security - Add examples -- use My::Security and other stuff SPOPS::Manual::Error - More examples SPOPS::Manual::Cookbook - Solicit for recipes? |
|
From: Chris W. <la...@us...> - 2001-10-12 16:07:20
|
Update of /cvsroot/openinteract/OpenInteract
In directory usw-pr-cvs1:/tmp/cvs-serv23933
Modified Files:
Changes
Log Message:
update package versions in 1.30; small changes in wording
Index: Changes
===================================================================
RCS file: /cvsroot/openinteract/OpenInteract/Changes,v
retrieving revision 1.67
retrieving revision 1.68
diff -C2 -d -r1.67 -r1.68
*** Changes 2001/10/11 11:41:14 1.67
--- Changes 2001/10/12 16:07:17 1.68
***************
*** 25,29 ****
boost. Also, OpenInteract works flawlessly with the new
Template::Stash::XS module, which itself makes templates run up to
! twice as fast.
* Template widgets:
--- 25,29 ----
boost. Also, OpenInteract works flawlessly with the new
Template::Stash::XS module, which itself makes templates run up to
! twice as fast. (Be sure to use version 2.05b or higher of TT.)
* Template widgets:
***************
*** 52,67 ****
- Added 'content_email' - address for a content administrator
! - Added 'custom_variable_class' and 'custom_variable_method' to the
! 'template_info' key. Allows each website to define a handler that
! can step in just before every template is processed and modify the
! variables sent to the template. (See OI/Template/Process.pm)
! - Added 'custom_init_class' and 'custom_init_method' to the
! 'template_info' key. Allows each website to define a handler that can
! step in just before the template object is initialized and modify
! its configuration.(See OI/Template/Process.pm)
! - Added 'cache_tt' to 'dir' key (Template Toolkit caching
! directory)
- Added 'template_info'->'compile_cleanup' -- set to true if you want
--- 52,68 ----
- Added 'content_email' - address for a content administrator
! - Added 'template_info'->'custom_variable_class' and
! 'template_info'->'custom_variable_method'. Allows each website to
! define a handler that can step in just before every template is
! processed and modify the variables sent to the template. (See
! OI/Template/Process.pm)
! - Added 'template_info'->'custom_init_class' and
! 'template_info'->'custom_init_method'. Allows each website to
! define a handler that can step in just before the template object
! is initialized and modify its configuration.(See
! OI/Template/Process.pm)
! - Added 'dir'->'cache_tt' key (Template Toolkit caching directory)
- Added 'template_info'->'compile_cleanup' -- set to true if you want
***************
*** 94,99 ****
- Changed content handler to an object handler (with '($$)'
! declaration) and added documentation about the method names used in
! case anyone wants to subclass the handler with their own behaviors.
* OpenInteract/ApacheStartup.pm:
--- 95,102 ----
- Changed content handler to an object handler (with '($$)'
! declaration), changed all methods to class methods (with
! non-private names) and added documentation about the method names
! used in case anyone wants to subclass the handler with their own
! behaviors.
* OpenInteract/ApacheStartup.pm:
***************
*** 125,129 ****
- Created base handler for most tasks (search form, search,
display, edit, remove) so that many actual handlers will just need
! to specify configuration options. (See docs.)
* OpenInteract/DBI.pm:
--- 128,133 ----
- Created base handler for most tasks (search form, search,
display, edit, remove) so that many actual handlers will just need
! to specify configuration options. This is extremely cool -- see
! docs for implementation.
* OpenInteract/DBI.pm:
***************
*** 161,166 ****
the $WEBSITE_DIR/template directory
! - In '_copy_spops_config_file()' (called when you apply or upgrade
! a package), check the website configuration when copying over the
'creation_security' hashref for each SPOPS object so we can modify
the public and site admin group IDs used. (Thanks to Andreas Nolte
--- 165,170 ----
the $WEBSITE_DIR/template directory
! - In '_copy_spops_config_file()' (called when you apply or upgrade a
! package), check the website configuration when copying over the
'creation_security' hashref for each SPOPS object so we can modify
the public and site admin group IDs used. (Thanks to Andreas Nolte
***************
*** 180,185 ****
- Create $R during main_initialize() and put the stash class in
there so we have normal access to the datasource during SPOPS
! configuration. (Hopefully it won't screw anything up with
! parent/child sharing issues, particular wrt DBI handles.)
- Modify create_config() and read_base_config() so that we can just
--- 184,190 ----
- Create $R during main_initialize() and put the stash class in
there so we have normal access to the datasource during SPOPS
! configuration, which is needed if you're using the 'DiscoverField'
! behavior. (Hopefully it won't screw anything up with parent/child
! sharing issues, particular wrt DBI handles.)
- Modify create_config() and read_base_config() so that we can just
***************
*** 248,251 ****
--- 253,278 ----
upgrade_package and pass it to the install_to_website() method of
OpenInteract::Package.
+
+
+ Packages changed:
+
+ OpenInteract 1.21 -> 1.30
+ ----------------------------
+ base: 1.60 -> 1.62
+ base_box: 0.30 -> 0.33
+ base_component: 1.25 -> 1.30
+ base_error: 1.30 -> 1.32
+ base_group: 1.25 -> 1.26
+ base_security: 1.46 -> 1.51
+ base_template: 1.27 -> 1.27
+ base_theme: 1.26 -> 1.27
+ base_user: 1.34 -> 1.37
+ lookup: n/a -> 0.15
+ results_manage: 0.02 -> 0.05
+ static_page: 1.49 -> 1.51
+ system_doc: 1.24 -> 1.25
+ classified: 1.28 -> 1.28
+ full_text: 1.26 -> 1.27
+ news: 1.33 -> 1.33
|
|
From: Chris W. <la...@us...> - 2001-10-12 16:04:17
|
Update of /cvsroot/openinteract/OpenInteract/pkg/static_page In directory usw-pr-cvs1:/tmp/cvs-serv22538/pkg/static_page Modified Files: Changes package.conf Log Message: enable static pages to have <template_status>no_parse</template_status> in them so we know not to parse them with TT (Thanks to Reinier Post <rp...@wi...> for reporting the original error which led to this fix.) Index: Changes =================================================================== RCS file: /cvsroot/openinteract/OpenInteract/pkg/static_page/Changes,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** Changes 2001/10/07 20:21:12 1.25 --- Changes 2001/10/12 16:04:14 1.26 *************** *** 1,4 **** --- 1,10 ---- Revision history for OpenInteract package static_page + 1.51 Fri Oct 12 08:55:12 EDT 2001 + + Modified OI/Handler/BasicPage.pm to enable pages to declare they + do not want their content run through TT. Thanks to Reinier Post + <rp...@wi...> for reporting the error which led to this. + 1.50 Sun Oct 7 16:34:17 EDT 2001 Index: package.conf =================================================================== RCS file: /cvsroot/openinteract/OpenInteract/pkg/static_page/package.conf,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** package.conf 2001/10/07 20:21:13 1.26 --- package.conf 2001/10/12 16:04:14 1.27 *************** *** 1,4 **** name static_page ! version 1.50 author Chris Winters (ch...@cw...) url http://www.openinteract.org/ --- 1,4 ---- name static_page ! version 1.51 author Chris Winters (ch...@cw...) url http://www.openinteract.org/ |
|
From: Chris W. <la...@us...> - 2001-10-12 16:04:17
|
Update of /cvsroot/openinteract/OpenInteract/pkg/static_page/OpenInteract/Handler
In directory usw-pr-cvs1:/tmp/cvs-serv22538/pkg/static_page/OpenInteract/Handler
Modified Files:
BasicPage.pm
Log Message:
enable static pages to have
<template_status>no_parse</template_status> in them so we know not to
parse them with TT (Thanks to Reinier Post <rp...@wi...> for
reporting the original error which led to this fix.)
Index: BasicPage.pm
===================================================================
RCS file: /cvsroot/openinteract/OpenInteract/pkg/static_page/OpenInteract/Handler/BasicPage.pm,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -d -r1.14 -r1.15
*** BasicPage.pm 2001/08/22 04:21:19 1.14
--- BasicPage.pm 2001/10/12 16:04:14 1.15
***************
*** 22,26 ****
! use constant MAIN_SCRIPT => '/BasicPage';
# Use this to mark the beginning and end of the "good" content in a
--- 22,27 ----
! use constant MAIN_SCRIPT => '/BasicPage';
! use constant NO_PARSE_STATUS => 'no_parse';
# Use this to mark the beginning and end of the "good" content in a
***************
*** 49,54 ****
my ( $class ) = @_;
my $R = OpenInteract::Request->instance;
! return 'show' if ( $R->{path}->{full}->[0] ne 'BasicPage' );
! return lc shift @{ $R->{path}->{current} }
|| $OpenInteract::Handler::BasicPage::default_method;
}
--- 50,55 ----
my ( $class ) = @_;
my $R = OpenInteract::Request->instance;
! return 'show' if ( $R->{path}{full}->[0] ne 'BasicPage' );
! return lc shift @{ $R->{path}{current} }
|| $OpenInteract::Handler::BasicPage::default_method;
}
***************
*** 84,88 ****
}
! $R->{page}->{title} = 'Listing of Documents';
return $R->template->handler( {}, $params,
{ db => 'static_dir_listing',
--- 85,89 ----
}
! $R->{page}{title} = 'Listing of Documents';
return $R->template->handler( {}, $params,
{ db => 'static_dir_listing',
***************
*** 108,114 ****
my $location = $p->{location} ||
$R->apache->param( 'location' ) ||
! $R->{path}->{original};
! my $storage = $R->CONFIG->{action}->{basicpage}->{storage};
my ( $page_info );
--- 109,115 ----
my $location = $p->{location} ||
$R->apache->param( 'location' ) ||
! $R->{path}{original};
! my $storage = $R->CONFIG->{action}{basicpage}{storage};
my ( $page_info );
***************
*** 151,155 ****
# content will be plain old HTML...
! $R->{page}->{content_type} = 'text/html';
if ( $error_type =~ /^security/ ) {
--- 152,156 ----
# content will be plain old HTML...
! $R->{page}{content_type} = 'text/html';
if ( $error_type =~ /^security/ ) {
***************
*** 172,176 ****
if ( $page_info->{send_file} ) {
! $R->{page}->{send_file} = $page_info->{send_file};
$R->DEBUG && $R->scrib( 1, "File being retrieved is not displayable. Set 'send_file' to $page_info->{send_file}" );
return undef;
--- 173,177 ----
if ( $page_info->{send_file} ) {
! $R->{page}{send_file} = $page_info->{send_file};
$R->DEBUG && $R->scrib( 1, "File being retrieved is not displayable. Set 'send_file' to $page_info->{send_file}" );
return undef;
***************
*** 187,194 ****
if ( $do_edit ) {
$page ||= $R->static_page->new;
! $params->{static_page} = $page;
$text_params = { db => 'static_page_form',
package => 'static_page' };
! $R->{page}->{title} = 'Edit a Document';
my $update_items = eval { $page->fetch_updates( 5 ) } || [];
foreach my $update_info ( @{ $update_items } ) {
--- 188,195 ----
if ( $do_edit ) {
$page ||= $R->static_page->new;
! $params->{static_page} = $page;
$text_params = { db => 'static_page_form',
package => 'static_page' };
! $R->{page}{title} = 'Edit a Document';
my $update_items = eval { $page->fetch_updates( 5 ) } || [];
foreach my $update_info ( @{ $update_items } ) {
***************
*** 204,214 ****
unless ( my $is_active = $class->_check_active_date( $page_info ) ) {
$R->DEBUG && $R->scrib( 1, "Page has been marked as non-active ($is_active); returning error message." );
! $R->{page}->{title} = 'Page not yet active';
return '<h2 align="center">Not Active</h2>' .
'<p>Sorry, this page is not yet active.</p>';
}
! $R->{page}->{title} = $page_info->{title};
! $R->{page}->{script} .= $page_info->{script};
# Allows the page to define the main template it will use; if
--- 205,215 ----
unless ( my $is_active = $class->_check_active_date( $page_info ) ) {
$R->DEBUG && $R->scrib( 1, "Page has been marked as non-active ($is_active); returning error message." );
! $R->{page}{title} = 'Page not yet active';
return '<h2 align="center">Not Active</h2>' .
'<p>Sorry, this page is not yet active.</p>';
}
! $R->{page}{title} = $page_info->{title};
! $R->{page}{script} .= $page_info->{script};
# Allows the page to define the main template it will use; if
***************
*** 216,220 ****
# the default
! $R->{page}->{_template_name_} = $page_info->{main_template};
# You can split your page into multiple viewable pages -- see
--- 217,221 ----
# the default
! $R->{page}{_template_name_} = $page_info->{main_template};
# You can split your page into multiple viewable pages -- see
***************
*** 227,230 ****
--- 228,239 ----
}
}
+
+ # If the page has told us not to run it through TT, just return
+ # its content.
+
+ if ( $page_info->{_template_status} eq NO_PARSE_STATUS ) {
+ return $page_info->{pagetext};
+ }
+
return $R->template->handler( {}, $params, $text_params );
}
***************
*** 236,240 ****
my ( $class, $p ) = @_;
my $R = OpenInteract::Request->instance;
! $R->{page}->{return_url} = '/BasicPage/listing/';
my $apr = $R->apache;
--- 245,249 ----
my ( $class, $p ) = @_;
my $R = OpenInteract::Request->instance;
! $R->{page}{return_url} = '/BasicPage/listing/';
my $apr = $R->apache;
***************
*** 345,349 ****
$location = $class->_remove_query_string( $location );
$location = lc $location;
! my $home_name = $R->CONFIG->{action}->{basicpage}->{object_home_name};
my @locations = ( $location );
--- 354,358 ----
$location = $class->_remove_query_string( $location );
$location = lc $location;
! my $home_name = $R->CONFIG->{action}{basicpage}{object_home_name};
my @locations = ( $location );
***************
*** 398,402 ****
$R->DEBUG && $R->scrib( 1, "Trying to retrieve FILE with location ($location)" );
$location = $class->_remove_query_string( $location );
! my $home_name = $R->CONFIG->{action}->{basicpage}->{filesystem_home_name};
if ( $location =~ m|/$| ) {
--- 407,411 ----
$R->DEBUG && $R->scrib( 1, "Trying to retrieve FILE with location ($location)" );
$location = $class->_remove_query_string( $location );
! my $home_name = $R->CONFIG->{action}{basicpage}{filesystem_home_name};
if ( $location =~ m|/$| ) {
***************
*** 421,425 ****
my $html_dir = $R->CONFIG->get_dir( 'html' );
$html_dir =~ s|/$||;
!
foreach my $location ( @loc ) {
--- 430,434 ----
my $html_dir = $R->CONFIG->get_dir( 'html' );
$html_dir =~ s|/$||;
!
foreach my $location ( @loc ) {
***************
*** 450,455 ****
security_object_class => $R->security_object,
object_id => $location,
! user => $R->{auth}->{user},
! group => $R->{auth}->{group},
hierarchy_separator => '/' }) };
$R->scrib( 0, "Error found checking security: $@" ) if ( $@ );
--- 459,464 ----
security_object_class => $R->security_object,
object_id => $location,
! user => $R->{auth}{user},
! group => $R->{auth}{group},
hierarchy_separator => '/' }) };
$R->scrib( 0, "Error found checking security: $@" ) if ( $@ );
***************
*** 493,496 ****
--- 502,508 ----
if ( $page_info->{pagetext} =~ s|<boxes>(.*)?</boxes>|| ) {
$page_info->{boxes} = $1;
+ }
+ if ( $page_info->{pagetext} =~ m|<template_status>(.*)?</template_status>| ) {
+ $page_info->{_template_status} = $1;
}
|
|
From: Chris W. <la...@us...> - 2001-10-12 16:02:40
|
Update of /cvsroot/openinteract/OpenInteract In directory usw-pr-cvs1:/tmp/cvs-serv22010 Modified Files: MANIFEST Log Message: update static_page package version Index: MANIFEST =================================================================== RCS file: /cvsroot/openinteract/OpenInteract/MANIFEST,v retrieving revision 1.60 retrieving revision 1.61 diff -C2 -d -r1.60 -r1.61 *** MANIFEST 2001/10/11 15:43:38 1.60 --- MANIFEST 2001/10/12 16:02:37 1.61 *************** *** 100,104 **** pkg/news-1.33.tar.gz pkg/results_manage-0.05.tar.gz ! pkg/static_page-1.50.tar.gz pkg/system_doc-1.25.tar.gz script/oi_manage --- 100,104 ---- pkg/news-1.33.tar.gz pkg/results_manage-0.05.tar.gz ! pkg/static_page-1.51.tar.gz pkg/system_doc-1.25.tar.gz script/oi_manage |
|
From: Chris W. <la...@us...> - 2001-10-12 12:45:39
|
Update of /cvsroot/openinteract/OpenInteract/doc
In directory usw-pr-cvs1:/tmp/cvs-serv19304
Modified Files:
templates.html
Log Message:
forgot to reset items to original state when testing TT-interpreted version...
Index: templates.html
===================================================================
RCS file: /cvsroot/openinteract/OpenInteract/doc/templates.html,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** templates.html 2001/10/12 12:33:25 1.2
--- templates.html 2001/10/12 12:45:36 1.3
***************
*** 694,701 ****
<P>
! <PRE> [ % expires_on_info = date_into_hash( news.expires_on ) % ]
! [ % comp( 'date_select', day = expires_on_info.day,
year = expires_on_info.year,
! month = expires_on_info.month ) % ]
</PRE>
<LI>
--- 694,701 ----
<P>
! <PRE> [% expires_on_info = date_into_hash( news.expires_on ) %]
! [% comp( 'date_select', day = expires_on_info.day,
year = expires_on_info.year,
! month = expires_on_info.month ) %]
</PRE>
<LI>
***************
*** 714,718 ****
<P>
<PRE> <pre>
! [ % sprintf( '$%5.2f - $%5.2f = $%5.2f', in_bank, owed, total ) % ]
</pre>
</PRE>
--- 714,718 ----
<P>
<PRE> <pre>
! [% sprintf( '$%5.2f - $%5.2f = $%5.2f', in_bank, owed, total ) %]
</pre>
</PRE>
|
|
From: Chris W. <la...@us...> - 2001-10-12 12:42:17
|
Update of /cvsroot/openinteract/OpenInteract/doc
In directory usw-pr-cvs1:/tmp/cvs-serv18003
Modified Files:
template_widgets.html
Log Message:
added 'template_status' tag so we can tell static_page not to run through TT
Index: template_widgets.html
===================================================================
RCS file: /cvsroot/openinteract/OpenInteract/doc/template_widgets.html,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** template_widgets.html 2001/10/11 13:36:18 1.2
--- template_widgets.html 2001/10/12 12:42:14 1.3
***************
*** 5,8 ****
--- 5,10 ----
<body>
+ <!-- <template_status>no_parse</template_status> -->
+
<h1>OpenInteract: Template Widgets</h1>
***************
*** 277,281 ****
<!-- Created: Mon Oct 8 12:39:23 EDT 2001 -->
<!-- hhmts start -->
! Last modified: Thu Oct 11 09:49:54 EDT 2001
<!-- hhmts end -->
</body>
--- 279,283 ----
<!-- Created: Mon Oct 8 12:39:23 EDT 2001 -->
<!-- hhmts start -->
! Last modified: Fri Oct 12 08:56:46 EDT 2001
<!-- hhmts end -->
</body>
|
|
From: Chris W. <la...@us...> - 2001-10-12 12:33:27
|
Update of /cvsroot/openinteract/OpenInteract/doc
In directory usw-pr-cvs1:/tmp/cvs-serv14720
Modified Files:
LDAP.html admin.html database.html developer.html
glossary.html index.html manager.html overview.html
spops_overview.html templates.html
Log Message:
added 'template_status' tag so we can tell static_page not to run these through TT
Index: LDAP.html
===================================================================
RCS file: /cvsroot/openinteract/OpenInteract/doc/LDAP.html,v
retrieving revision 1.10
retrieving revision 1.11
diff -C2 -d -r1.10 -r1.11
*** LDAP.html 2001/09/05 12:45:31 1.10
--- LDAP.html 2001/10/12 12:33:25 1.11
***************
*** 4,7 ****
--- 4,8 ----
</head>
<body>
+ <!-- <template_status>no_parse</template_status> -->
<h1>OpenInteract and LDAP</h1>
Index: admin.html
===================================================================
RCS file: /cvsroot/openinteract/OpenInteract/doc/admin.html,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** admin.html 2001/06/18 12:09:32 1.4
--- admin.html 2001/10/12 12:33:25 1.5
***************
*** 6,9 ****
--- 6,10 ----
<body>
+ <!-- <template_status>no_parse</template_status> -->
<h1>OpenInteract Administrator's Guide</h1>
Index: database.html
===================================================================
RCS file: /cvsroot/openinteract/OpenInteract/doc/database.html,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** database.html 2001/06/07 02:39:12 1.5
--- database.html 2001/10/12 12:33:25 1.6
***************
*** 6,9 ****
--- 6,10 ----
<body>
+ <!-- <template_status>no_parse</template_status> -->
<h1>Databases and OpenInteract</h1>
Index: developer.html
===================================================================
RCS file: /cvsroot/openinteract/OpenInteract/doc/developer.html,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** developer.html 2001/07/06 17:43:50 1.3
--- developer.html 2001/10/12 12:33:25 1.4
***************
*** 6,9 ****
--- 6,10 ----
<body>
+ <!-- <template_status>no_parse</template_status> -->
<h1>OpenInteract Developer's Guide</h1>
Index: glossary.html
===================================================================
RCS file: /cvsroot/openinteract/OpenInteract/doc/glossary.html,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** glossary.html 2001/02/13 12:49:47 1.2
--- glossary.html 2001/10/12 12:33:25 1.3
***************
*** 6,9 ****
--- 6,10 ----
<body>
+ <!-- <template_status>no_parse</template_status> -->
<h1>OpenInteract Glossary</h1>
Index: index.html
===================================================================
RCS file: /cvsroot/openinteract/OpenInteract/doc/index.html,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** index.html 2001/08/27 15:00:28 1.2
--- index.html 2001/10/12 12:33:25 1.3
***************
*** 6,9 ****
--- 6,10 ----
<body>
+ <!-- <template_status>no_parse</template_status> -->
<h1>Guides to OpenInteract</h1>
***************
*** 16,19 ****
--- 17,21 ----
<li><a href="glossary.html">OpenInteract Glossary</a></li>
<li><a href="LDAP.html">OpenInteract and LDAP</a></li>
+ <li><a href="template_widgets.html">OpenInteract Template Widgets</a></li>
</ul>
Index: manager.html
===================================================================
RCS file: /cvsroot/openinteract/OpenInteract/doc/manager.html,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** manager.html 2001/02/02 06:18:47 1.1.1.1
--- manager.html 2001/10/12 12:33:25 1.2
***************
*** 6,9 ****
--- 6,10 ----
<body>
+ <!-- <template_status>no_parse</template_status> -->
<h1>Illustrated Manager's Guide to OpenInteract</h1>
Index: overview.html
===================================================================
RCS file: /cvsroot/openinteract/OpenInteract/doc/overview.html,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** overview.html 2001/02/02 06:18:52 1.1.1.1
--- overview.html 2001/10/12 12:33:25 1.2
***************
*** 6,9 ****
--- 6,10 ----
<body>
+ <!-- <template_status>no_parse</template_status> -->
Index: spops_overview.html
===================================================================
RCS file: /cvsroot/openinteract/OpenInteract/doc/spops_overview.html,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** spops_overview.html 2001/02/02 06:18:56 1.1.1.1
--- spops_overview.html 2001/10/12 12:33:25 1.2
***************
*** 6,9 ****
--- 6,10 ----
<body>
+ <!-- <template_status>no_parse</template_status> -->
<h1>Introduction to SPOPS</h1>
Index: templates.html
===================================================================
RCS file: /cvsroot/openinteract/OpenInteract/doc/templates.html,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** templates.html 2001/02/02 06:18:58 1.1.1.1
--- templates.html 2001/10/12 12:33:25 1.2
***************
*** 1,10 ****
! <HTML>
! <HEAD>
! <TITLE>No Title</TITLE>
! <LINK REV="made" HREF="mailto:ro...@mo...">
! </HEAD>
!
! <BODY>
!
<!-- INDEX BEGIN -->
--- 1,3 ----
! <!-- <template_status>no_parse</template_status> -->
<!-- INDEX BEGIN -->
***************
*** 376,380 ****
</PRE>
<P>
! <PRE> [% IF news.tmp_security_level >= security_level.write %]
You can edit this object
[% END %]
--- 369,373 ----
</PRE>
<P>
! <PRE> [% IF news.tmp_security_level >= security_level.write %]
You can edit this object
[% END %]
***************
*** 701,708 ****
<P>
! <PRE> [% expires_on_info = date_into_hash( news.expires_on ) %]
! [% comp( 'date_select', day = expires_on_info.day,
year = expires_on_info.year,
! month = expires_on_info.month, ... ) %]
</PRE>
<LI>
--- 694,701 ----
<P>
! <PRE> [ % expires_on_info = date_into_hash( news.expires_on ) % ]
! [ % comp( 'date_select', day = expires_on_info.day,
year = expires_on_info.year,
! month = expires_on_info.month ) % ]
</PRE>
<LI>
***************
*** 721,725 ****
<P>
<PRE> <pre>
! [% sprintf( '$%5.2f - $%5.2f = $%5.2f', in_bank, owed, total ) %]
</pre>
</PRE>
--- 714,718 ----
<P>
<PRE> <pre>
! [ % sprintf( '$%5.2f - $%5.2f = $%5.2f', in_bank, owed, total ) % ]
</pre>
</PRE>
|
|
From: Chris W. <la...@us...> - 2001-10-12 05:51:27
|
Update of /cvsroot/openinteract/SPOPS
In directory usw-pr-cvs1:/tmp/cvs-serv30457
Modified Files:
Changes
Log Message:
latest changes (note the added eg/ files...)
Index: Changes
===================================================================
RCS file: /cvsroot/openinteract/SPOPS/Changes,v
retrieving revision 1.61
retrieving revision 1.62
diff -C2 -d -r1.61 -r1.62
*** Changes 2001/10/08 13:02:58 1.61
--- Changes 2001/10/12 05:51:24 1.62
***************
*** 21,24 ****
--- 21,28 ----
manual are fairly complete while others are barren.
+ * eg/(items from 0.50):
+
+ - Actually added these to the distribution (doh!)
+
* eg/My/DiscoverField.pm:
|
|
From: Chris W. <la...@us...> - 2001-10-12 05:39:16
|
Update of /cvsroot/openinteract/SPOPS/doc/Manual In directory usw-pr-cvs1:/tmp/cvs-serv27463/Manual Modified Files: CodeGeneration.pod Configuration.pod Cookbook.pod Datasource.pod Error.pod Intro.pod Object.pod ObjectRules.pod Relationships.pod Security.pod Serialization.pod Log Message: cleanup (L<blah> -> L<blah|blah> issue); small edits; add license info Index: CodeGeneration.pod =================================================================== RCS file: /cvsroot/openinteract/SPOPS/doc/Manual/CodeGeneration.pod,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** CodeGeneration.pod 2001/10/09 13:42:26 1.5 --- CodeGeneration.pod 2001/10/12 05:39:13 1.6 *************** *** 269,274 **** Copyright (c) 2001 Chris Winters. All rights reserved. ! This library is free software; you can redistribute it and/or modify ! it under the same terms as Perl itself. =head1 AUTHORS --- 269,273 ---- Copyright (c) 2001 Chris Winters. All rights reserved. ! See L<SPOPS::Manual|SPOPS::Manual> for license. =head1 AUTHORS Index: Configuration.pod =================================================================== RCS file: /cvsroot/openinteract/SPOPS/doc/Manual/Configuration.pod,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Configuration.pod 2001/09/29 23:11:09 1.4 --- Configuration.pod 2001/10/12 05:39:13 1.5 *************** *** 12,15 **** --- 12,17 ---- [% INCLUDE examples/cb_ds_ancestor_config | linenum %] + =head2 General Configuration Fields + B<class> ($) *************** *** 149,152 **** --- 151,156 ---- =head1 SPOPS::DBI CONFIGURATION + =head2 General Configuration Fields + B<isa> (\@) *************** *** 193,197 **** These are typically database-specific. ! =head2 Relationship Fields B<links_to> (\%) --- 197,201 ---- These are typically database-specific. ! =head2 General Relationship Fields B<links_to> (\%) *************** *** 213,216 **** --- 217,222 ---- to that of other SPOPS objects, with a few modifications. + =head2 General Configuration Fields + B<isa> (\@) *************** *** 280,284 **** object and the value from another field. ! =head2 Relationship Configuration The 'has_a' relationship exists where one object has the information --- 286,290 ---- object and the value from another field. ! =head2 Relationship Fields The 'has_a' relationship exists where one object has the information *************** *** 335,338 **** --- 341,346 ---- unless otherwise noted. + =head2 General Configuration Fields + B<datasource> (\@) *************** *** 382,387 **** Copyright (c) 2001 Chris Winters. All rights reserved. ! This library is free software; you can redistribute it and/or modify ! it under the same terms as Perl itself. =head1 AUTHORS --- 390,394 ---- Copyright (c) 2001 Chris Winters. All rights reserved. ! See L<SPOPS::Manual|SPOPS::Manual> for license. =head1 AUTHORS Index: Cookbook.pod =================================================================== RCS file: /cvsroot/openinteract/SPOPS/doc/Manual/Cookbook.pod,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Cookbook.pod 2001/09/29 20:58:39 1.3 --- Cookbook.pod 2001/10/12 05:39:13 1.4 *************** *** 99,104 **** Copyright (c) 2001 Chris Winters. All rights reserved. ! This library is free software; you can redistribute it and/or modify ! it under the same terms as Perl itself. =head1 AUTHORS --- 99,103 ---- Copyright (c) 2001 Chris Winters. All rights reserved. ! See L<SPOPS::Manual|SPOPS::Manual> for license. =head1 AUTHORS Index: Datasource.pod =================================================================== RCS file: /cvsroot/openinteract/SPOPS/doc/Manual/Datasource.pod,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Datasource.pod 2001/09/29 23:23:14 1.2 --- Datasource.pod 2001/10/12 05:39:13 1.3 *************** *** 9,14 **** Copyright (c) 2001 Chris Winters. All rights reserved. ! This library is free software; you can redistribute it and/or modify ! it under the same terms as Perl itself. =head1 AUTHORS --- 9,13 ---- Copyright (c) 2001 Chris Winters. All rights reserved. ! See L<SPOPS::Manual|SPOPS::Manual> for license. =head1 AUTHORS Index: Error.pod =================================================================== RCS file: /cvsroot/openinteract/SPOPS/doc/Manual/Error.pod,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Error.pod 2001/09/30 01:25:00 1.3 --- Error.pod 2001/10/12 05:39:13 1.4 *************** *** 79,84 **** Copyright (c) 2001 Chris Winters. All rights reserved. ! This library is free software; you can redistribute it and/or modify ! it under the same terms as Perl itself. =head1 AUTHORS --- 79,83 ---- Copyright (c) 2001 Chris Winters. All rights reserved. ! See L<SPOPS::Manual|SPOPS::Manual> for license. =head1 AUTHORS Index: Intro.pod =================================================================== RCS file: /cvsroot/openinteract/SPOPS/doc/Manual/Intro.pod,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Intro.pod 2001/09/29 23:23:14 1.2 --- Intro.pod 2001/10/12 05:39:13 1.3 *************** *** 85,89 **** In Runtime State, the object representation is based on a hash of attributes. The object gets notified about any changes to it through ! the tie(3) mechanism. In Persistency State, the object exists in some persistent form, that --- 85,89 ---- In Runtime State, the object representation is based on a hash of attributes. The object gets notified about any changes to it through ! the L<tie|tie> mechanism. In Persistency State, the object exists in some persistent form, that *************** *** 104,112 **** need to prepare anything or clean up something, according to needs of your storage technology. These are pushed on a queue based on a ! search of @ISA, and executed front to end of the queue. If any of the ! calls in a given queue returns a false value, the whole action (save, ! remove, fetch) is short-circuited (that is, a failing method bombs out ! of the action). More information on this is in L<Data Manipulation ! Callbacks: Rulesets> below. =head1 COPYRIGHT --- 104,112 ---- need to prepare anything or clean up something, according to needs of your storage technology. These are pushed on a queue based on a ! search of C<@ISA>, and executed front to end of the queue. If any of ! the calls in a given queue returns a false value, the whole action ! (save, remove, fetch) is short-circuited (that is, a failing method ! bombs out of the action). More information on this is in L<Data ! Manipulation Callbacks: Rulesets> below. =head1 COPYRIGHT *************** *** 114,119 **** Copyright (c) 2001 Chris Winters. All rights reserved. ! This library is free software; you can redistribute it and/or modify ! it under the same terms as Perl itself. =head1 AUTHORS --- 114,118 ---- Copyright (c) 2001 Chris Winters. All rights reserved. ! See L<SPOPS::Manual|SPOPS::Manual> for license. =head1 AUTHORS Index: Object.pod =================================================================== RCS file: /cvsroot/openinteract/SPOPS/doc/Manual/Object.pod,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Object.pod 2001/09/29 23:23:14 1.4 --- Object.pod 2001/10/12 05:39:13 1.5 *************** *** 452,457 **** Copyright (c) 2001 Chris Winters. All rights reserved. ! This library is free software; you can redistribute it and/or modify ! it under the same terms as Perl itself. =head1 AUTHORS --- 452,456 ---- Copyright (c) 2001 Chris Winters. All rights reserved. ! See L<SPOPS::Manual|SPOPS::Manual> for license. =head1 AUTHORS Index: ObjectRules.pod =================================================================== RCS file: /cvsroot/openinteract/SPOPS/doc/Manual/ObjectRules.pod,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** ObjectRules.pod 2001/09/29 23:23:14 1.2 --- ObjectRules.pod 2001/10/12 05:39:13 1.3 *************** *** 123,128 **** Note that the return value is always the package that inserted the rule(s) into the ruleset. This enables the module that creates the ! class (L<SPOPS::Configure::Ruleset>) to ensure that the same rule does ! not get entered multiple times. B<ruleset_process_action( ($object|$class), $action, \%params )> --- 123,128 ---- Note that the return value is always the package that inserted the rule(s) into the ruleset. This enables the module that creates the ! class (L<SPOPS::Configure::Ruleset|SPOPS::Configure::Ruleset>) to ! ensure that the same rule does not get entered multiple times. B<ruleset_process_action( ($object|$class), $action, \%params )> *************** *** 139,144 **** Copyright (c) 2001 Chris Winters. All rights reserved. ! This library is free software; you can redistribute it and/or modify ! it under the same terms as Perl itself. =head1 AUTHORS --- 139,143 ---- Copyright (c) 2001 Chris Winters. All rights reserved. ! See L<SPOPS::Manual|SPOPS::Manual> for license. =head1 AUTHORS Index: Relationships.pod =================================================================== RCS file: /cvsroot/openinteract/SPOPS/doc/Manual/Relationships.pod,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Relationships.pod 2001/09/29 23:23:14 1.2 --- Relationships.pod 2001/10/12 05:39:13 1.3 *************** *** 13,18 **** Copyright (c) 2001 Chris Winters. All rights reserved. ! This library is free software; you can redistribute it and/or modify ! it under the same terms as Perl itself. =head1 AUTHORS --- 13,17 ---- Copyright (c) 2001 Chris Winters. All rights reserved. ! See L<SPOPS::Manual|SPOPS::Manual> for license. =head1 AUTHORS Index: Security.pod =================================================================== RCS file: /cvsroot/openinteract/SPOPS/doc/Manual/Security.pod,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Security.pod 2001/10/08 04:31:56 1.3 --- Security.pod 2001/10/12 05:39:13 1.4 *************** *** 297,302 **** Copyright (c) 2001 Chris Winters. All rights reserved. ! This library is free software; you can redistribute it and/or modify ! it under the same terms as Perl itself. =head1 AUTHORS --- 297,301 ---- Copyright (c) 2001 Chris Winters. All rights reserved. ! See L<SPOPS::Manual|SPOPS::Manual> for license. =head1 AUTHORS Index: Serialization.pod =================================================================== RCS file: /cvsroot/openinteract/SPOPS/doc/Manual/Serialization.pod,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Serialization.pod 2001/09/29 23:23:14 1.4 --- Serialization.pod 2001/10/12 05:39:13 1.5 *************** *** 8,12 **** Since the main SPOPS class from which all SPOPS objects derive has ! L<Storable> as a parent, you can call any of its methods from any SPOPS object and have a serialized version of your object. You can send it over the network, save it for later -- whatever you like. --- 8,12 ---- Since the main SPOPS class from which all SPOPS objects derive has ! L<Storable|Storable> as a parent, you can call any of its methods from any SPOPS object and have a serialized version of your object. You can send it over the network, save it for later -- whatever you like. *************** *** 134,138 **** For an example of how a SPOPS subclass implements lazy-loading, see ! L<SPOPS::DBI>. =head1 COPYRIGHT --- 134,138 ---- For an example of how a SPOPS subclass implements lazy-loading, see ! L<SPOPS::DBI|SPOPS::DBI>. =head1 COPYRIGHT *************** *** 140,145 **** Copyright (c) 2001 Chris Winters. All rights reserved. ! This library is free software; you can redistribute it and/or modify ! it under the same terms as Perl itself. =head1 AUTHORS --- 140,144 ---- Copyright (c) 2001 Chris Winters. All rights reserved. ! See L<SPOPS::Manual|SPOPS::Manual> for license. =head1 AUTHORS |
|
From: Chris W. <la...@us...> - 2001-10-12 05:39:16
|
Update of /cvsroot/openinteract/SPOPS/doc In directory usw-pr-cvs1:/tmp/cvs-serv27463 Modified Files: Manual.pod Log Message: cleanup (L<blah> -> L<blah|blah> issue); small edits; add license info Index: Manual.pod =================================================================== RCS file: /cvsroot/openinteract/SPOPS/doc/Manual.pod,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** Manual.pod 2001/10/09 13:43:12 1.5 --- Manual.pod 2001/10/12 05:39:12 1.6 *************** *** 19,25 **** directions, etc. If you need implementation-specific information, please see the documentation for the appropriate module. (All modules ! listed below.) ! The manual is broken down into several pieces: =over 4 --- 19,25 ---- directions, etc. If you need implementation-specific information, please see the documentation for the appropriate module. (All modules ! are listed below.) ! The manual is broken down into: =over 4 *************** *** 38,43 **** Describes how the configuration process works and what common configuration values are for the different implementations (e.g., ! L<SPOPS::DBI>, L<SPOPS::LDAP>, L<SPOPS::GDBM|SPOPS::DBI>, ! L<SPOPS::LDAP>, L<SPOPS::GDBM>). Also contains information about security-specific configuration items. --- 38,43 ---- Describes how the configuration process works and what common configuration values are for the different implementations (e.g., ! L<SPOPS::DBI|SPOPS::DBI>, L<SPOPS::LDAP|SPOPS::LDAP>, ! L<SPOPS::GDBM|SPOPS::GDBM>). Also contains information about security-specific configuration items. *************** *** 84,88 **** =over 4 ! =item * L<SPOPS|SPOPS> =back --- 84,88 ---- =over 4 ! =item L<SPOPS|SPOPS> =back *************** *** 92,96 **** =over 4 ! =item * L<SPOPS::Initialize|SPOPS::Initialize> =back --- 92,96 ---- =over 4 ! =item L<SPOPS::Initialize|SPOPS::Initialize> =back *************** *** 100,106 **** =over 4 ! =item * L<SPOPS::ClassFactory|SPOPS::ClassFactory> ! =item * L<SPOPS::ClassFactory::DefaultBehavior|SPOPS::ClassFactory::DefaultBehavior> =back --- 100,106 ---- =over 4 ! =item L<SPOPS::ClassFactory|SPOPS::ClassFactory> ! =item L<SPOPS::ClassFactory::DefaultBehavior|SPOPS::ClassFactory::DefaultBehavior> =back *************** *** 110,114 **** =over 4 ! =item * L<SPOPS::Error|SPOPS::Error> =back --- 110,114 ---- =over 4 ! =item L<SPOPS::Error|SPOPS::Error> =back *************** *** 118,124 **** =over 4 ! =item * L<SPOPS::Security|SPOPS::Security> ! =item * L<SPOPS::Security::Hierarchy|SPOPS::Security::Hierarchy> =back --- 118,124 ---- =over 4 ! =item L<SPOPS::Security|SPOPS::Security> ! =item L<SPOPS::Security::Hierarchy|SPOPS::Security::Hierarchy> =back *************** *** 128,152 **** =over 4 ! =item * L<SPOPS::ClassFactory::DBI|SPOPS::ClassFactory::DBI> ! =item * L<SPOPS::DBI|SPOPS::DBI> ! =item * L<SPOPS::SQLInterface|SPOPS::SQLInterface> ! =item * L<SPOPS::DBI::MySQL|SPOPS::DBI::MySQL> ! =item * L<SPOPS::DBI::Sybase|SPOPS::DBI::Sybase> ! =item * L<SPOPS::DBI::Pg|SPOPS::DBI::Pg> ! =item * L<SPOPS::Iterator::DBI|SPOPS::Iterator::DBI> ! =item * L<SPOPS::Key::DBI::HandleField|SPOPS::Key::DBI::HandleField> ! =item * L<SPOPS::Key::DBI::Identity|SPOPS::Key::DBI::Identity> ! =item * L<SPOPS::Key::DBI::Pool|SPOPS::Key::DBI::Pool> ! =item * L<SPOPS::Key::DBI::Sequence|SPOPS::Key::DBI::Sequence> =back --- 128,152 ---- =over 4 ! =item L<SPOPS::ClassFactory::DBI|SPOPS::ClassFactory::DBI> ! =item L<SPOPS::DBI|SPOPS::DBI> ! =item L<SPOPS::SQLInterface|SPOPS::SQLInterface> ! =item L<SPOPS::DBI::MySQL|SPOPS::DBI::MySQL> ! =item L<SPOPS::DBI::Sybase|SPOPS::DBI::Sybase> ! =item L<SPOPS::DBI::Pg|SPOPS::DBI::Pg> ! =item L<SPOPS::Iterator::DBI|SPOPS::Iterator::DBI> ! =item L<SPOPS::Key::DBI::HandleField|SPOPS::Key::DBI::HandleField> ! =item L<SPOPS::Key::DBI::Identity|SPOPS::Key::DBI::Identity> ! =item L<SPOPS::Key::DBI::Pool|SPOPS::Key::DBI::Pool> ! =item L<SPOPS::Key::DBI::Sequence|SPOPS::Key::DBI::Sequence> =back *************** *** 156,166 **** =over 4 ! =item * L<SPOPS::ClassFactory::LDAP|SPOPS::ClassFactory::LDAP> ! =item * L<SPOPS::Iterator::LDAP|SPOPS::Iterator::LDAP> ! =item * L<SPOPS::LDAP|SPOPS::LDAP> ! =item * L<SPOPS::LDAP::MultiDatasource|SPOPS::LDAP::MultiDatasource> =back --- 156,166 ---- =over 4 ! =item L<SPOPS::ClassFactory::LDAP|SPOPS::ClassFactory::LDAP> ! =item L<SPOPS::Iterator::LDAP|SPOPS::Iterator::LDAP> ! =item L<SPOPS::LDAP|SPOPS::LDAP> ! =item L<SPOPS::LDAP::MultiDatasource|SPOPS::LDAP::MultiDatasource> =back *************** *** 170,175 **** =over 4 ! =item * L<SPOPS::Iterator|SPOPS::Iterator> =back --- 170,177 ---- =over 4 ! =item L<SPOPS::Iterator|SPOPS::Iterator> + =item L<SPOPS::Iterator::WrapList|SPOPS::Iterator::WrapList> + =back *************** *** 178,184 **** =over 4 ! =item * L<SPOPS::Key::Random|SPOPS::Key::Random> ! =item * L<SPOPS::Utility|SPOPS::Utility> =back --- 180,186 ---- =over 4 ! =item L<SPOPS::Key::Random|SPOPS::Key::Random> ! =item L<SPOPS::Utility|SPOPS::Utility> =back *************** *** 188,194 **** =over 4 ! =item * L<SPOPS::Tie|SPOPS::Tie> ! =item * L<SPOPS::Tie::StrictField|SPOPS::Tie::StrictField> =back --- 190,196 ---- =over 4 ! =item L<SPOPS::Tie|SPOPS::Tie> ! =item L<SPOPS::Tie::StrictField|SPOPS::Tie::StrictField> =back *************** *** 198,203 **** Copyright (c) 2001 Chris Winters. All rights reserved. ! This library is free software; you can redistribute it and/or modify ! it under the same terms as Perl itself. =head1 AUTHORS --- 200,209 ---- Copyright (c) 2001 Chris Winters. All rights reserved. ! Permission is granted to copy, distribute and/or modify this document ! under the terms of the GNU Free Documentation License, Version 1.1 or ! any later version published by the Free Software Foundation; with no ! Invariant Sections, with no Front-Cover Texts, and with no Back-Cover ! Texts. A copy of the license is included in the file titled ! "COPYING-DOCS". =head1 AUTHORS |
|
From: Chris W. <la...@us...> - 2001-10-12 04:09:02
|
Update of /cvsroot/openinteract/SPOPS/eg/My
In directory usw-pr-cvs1:/tmp/cvs-serv1808
Modified Files:
DiscoverField.pm
Log Message:
added more docs; use the SPOPS DEBUG constant
Index: DiscoverField.pm
===================================================================
RCS file: /cvsroot/openinteract/SPOPS/eg/My/DiscoverField.pm,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** DiscoverField.pm 2001/10/08 02:04:58 1.3
--- DiscoverField.pm 2001/10/12 04:08:59 1.4
***************
*** 1,13 ****
package My::DiscoverField;
use strict;
! use SPOPS qw( _w _wm );
use SPOPS::ClassFactory qw( ERROR OK NOTIFY );
- use constant DEBUG => 1;
-
sub behavior_factory {
my ( $class ) = @_;
! DEBUG() && _wm( 1, DEBUG, "Installing field discovery for ($class)" );
return { manipulate_configuration => \&discover_fields };
}
--- 1,13 ----
package My::DiscoverField;
+ # $Id$
+
use strict;
! use SPOPS qw( DEBUG _w );
use SPOPS::ClassFactory qw( ERROR OK NOTIFY );
sub behavior_factory {
my ( $class ) = @_;
! DEBUG() && _w( 1, "Installing field discovery for ($class)" );
return { manipulate_configuration => \&discover_fields };
}
***************
*** 30,35 ****
return ( NOTIFY, "Cannot discover fields: $@" ) if ( $@ );
$CONFIG->{field} = $sth->{NAME};
! DEBUG() && _wm( 1, DEBUG, "Table: ($CONFIG->{base_table}); ",
! "Fields: (", join( ', ', @{ $CONFIG->{field} } ), ")" );
return ( OK, undef );
}
--- 30,35 ----
return ( NOTIFY, "Cannot discover fields: $@" ) if ( $@ );
$CONFIG->{field} = $sth->{NAME};
! DEBUG() && _w( 1, "Table: ($CONFIG->{base_table}); ",
! "Fields: (", join( ', ', @{ $CONFIG->{field} } ), ")" );
return ( OK, undef );
}
***************
*** 59,62 ****
--- 59,89 ----
# All fields in 'mydata' table now available as object properties
+
+ =head1 DESCRIPTION
+
+ Simple behavior rule to dynamically find all fields in a particular
+ database table and set them in our object.
+
+ Configuration is easy, just put:
+
+ rules_from => [ 'My::DiscoverField' ],
+
+ in your object configuration, or add 'My::DiscoverField' to an
+ already-existing 'rules_from' list. Then add:
+
+ field_discover => 'yes',
+
+ to your object configuration. Initialize the class and everything in
+ 'field' will be overwritten.
+
+ =head1 GOTCHAS
+
+ These fields are only discovered once, when the class is created. If
+ you modify the schema of a table (such as with an 'ALTER TABLE'
+ statement while a process (like a webserver) is running with SPOPS
+ definitions the field modifications will not be reflected in the
+ object class definition. (This is actually true of all
+ L<SPOPS::DBI|SPOPS::DBI> objects, but probably more apt to pop up
+ here.)
=head1 COPYRIGHT
|
|
From: Chris W. <la...@us...> - 2001-10-11 15:43:41
|
Update of /cvsroot/openinteract/OpenInteract In directory usw-pr-cvs1:/tmp/cvs-serv27962 Modified Files: MANIFEST Log Message: updated package version for base_security Index: MANIFEST =================================================================== RCS file: /cvsroot/openinteract/OpenInteract/MANIFEST,v retrieving revision 1.59 retrieving revision 1.60 diff -C2 -d -r1.59 -r1.60 *** MANIFEST 2001/10/11 15:20:31 1.59 --- MANIFEST 2001/10/11 15:43:38 1.60 *************** *** 91,95 **** pkg/base_error-1.32.tar.gz pkg/base_group-1.26.tar.gz ! pkg/base_security-1.50.tar.gz pkg/base_template-1.27.tar.gz pkg/base_theme-1.27.tar.gz --- 91,95 ---- pkg/base_error-1.32.tar.gz pkg/base_group-1.26.tar.gz ! pkg/base_security-1.51.tar.gz pkg/base_template-1.27.tar.gz pkg/base_theme-1.27.tar.gz |
|
From: Chris W. <la...@us...> - 2001-10-11 15:42:23
|
Update of /cvsroot/openinteract/SPOPS/SPOPS
In directory usw-pr-cvs1:/tmp/cvs-serv27499
Modified Files:
HashFile.pm
Log Message:
dumb typo
Index: HashFile.pm
===================================================================
RCS file: /cvsroot/openinteract/SPOPS/SPOPS/HashFile.pm,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -d -r1.11 -r1.12
*** HashFile.pm 2001/10/11 13:18:40 1.11
--- HashFile.pm 2001/10/11 15:42:20 1.12
***************
*** 25,29 ****
# Subclasses can override
! sub initialize { return 1; }
sub class_initialize {
--- 25,29 ----
# Subclasses can override
! sub initialize { return 1 }
sub class_initialize {
***************
*** 58,62 ****
}
if ( -f "$obj->{filename}.backup" ) {
! unlink( "$obj->{filename.backup" ); # just to be sure...
}
if ( -f $obj->{filename} ) {
--- 58,62 ----
}
if ( -f "$obj->{filename}.backup" ) {
! unlink( "$obj->{filename}.backup}" ); # just to be sure...
}
if ( -f $obj->{filename} ) {
***************
*** 142,146 ****
die "You must pass a filename to use for reading and writing.\n";
}
! my $file_exists = ( -f $filename ) ? 1 : 0;
unless ( $file_exists ) {
if ( $perm eq 'write-new' or $perm eq 'new' ) {
--- 142,146 ----
die "You must pass a filename to use for reading and writing.\n";
}
! my $file_exists = ( -f $filename );
unless ( $file_exists ) {
if ( $perm eq 'write-new' or $perm eq 'new' ) {
|
|
From: Chris W. <la...@us...> - 2001-10-11 15:39:29
|
Update of /cvsroot/openinteract/OpenInteract/OpenInteract
In directory usw-pr-cvs1:/tmp/cvs-serv26350/OpenInteract
Modified Files:
PackageRepository.pm
Log Message:
cosmetic
Index: PackageRepository.pm
===================================================================
RCS file: /cvsroot/openinteract/OpenInteract/OpenInteract/PackageRepository.pm,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** PackageRepository.pm 2001/07/11 12:26:27 1.4
--- PackageRepository.pm 2001/10/11 15:39:26 1.5
***************
*** 44,48 ****
$C->{field} = {};
foreach my $field ( @{ $C->{field_list} } ) {
! $C->{field}->{ $field } = $count;
$count++;
}
--- 44,48 ----
$C->{field} = {};
foreach my $field ( @{ $C->{field_list} } ) {
! $C->{field}{ $field } = $count;
$count++;
}
***************
*** 70,73 ****
--- 70,82 ----
+ # Backup the repository
+
+ sub backup {
+ my ( $self, $p ) = @_;
+ my $extension = $p->{extension} || 'backup';
+ $extension = ".$extension" unless ( $extension =~ /^\./ );
+ }
+
+
# Ensure that the base_dir, name and version properties are defined
# for every package in the repository. Also remove each package's
***************
*** 78,92 ****
foreach my $pkg_key ( keys %{ $self } ) {
next if ( $pkg_key eq META_KEY );
! unless ( -d $self->{ $pkg_key }->{base_dir} ) {
warn( "Cannot save package repository: the OpenInteract base installation ",
"directory for package ($pkg_key) is not specified or does not exist!" );
return undef;
}
! unless ( $self->{ $pkg_key }->{name} and $self->{ $pkg_key }->{version} ) {
warn( "Cannot save package repository: both the package 'name' and 'version' ",
"must be specified for package ($pkg_key) before saving.\n" );
return undef;
}
! delete $self->{ $pkg_key }->{repository};
}
return 1;
--- 87,101 ----
foreach my $pkg_key ( keys %{ $self } ) {
next if ( $pkg_key eq META_KEY );
! unless ( -d $self->{ $pkg_key }{base_dir} ) {
warn( "Cannot save package repository: the OpenInteract base installation ",
"directory for package ($pkg_key) is not specified or does not exist!" );
return undef;
}
! unless ( $self->{ $pkg_key }{name} and $self->{ $pkg_key }{version} ) {
warn( "Cannot save package repository: both the package 'name' and 'version' ",
"must be specified for package ($pkg_key) before saving.\n" );
return undef;
}
! delete $self->{ $pkg_key }{repository};
}
return 1;
***************
*** 120,124 ****
next if ( $pkg_key eq META_KEY );
DEBUG && _w( 1, "Setting repository in package key $pkg_key" );
! $self->{ $pkg_key }->{repository} = $self;
}
}
--- 129,133 ----
next if ( $pkg_key eq META_KEY );
DEBUG && _w( 1, "Setting repository in package key $pkg_key" );
! $self->{ $pkg_key }{repository} = $self;
}
}
***************
*** 190,194 ****
foreach my $pkg_key ( keys %{ $self } ) {
next unless ( ref $self->{ $pkg_key } eq 'HASH' );
! if ( $self->{ $pkg_key }->{name} eq $name ) {
push @match, $self->{ $pkg_key };
DEBUG && _w( 1, "Found package $pkg_key; try to match up with package $name" );
--- 199,203 ----
foreach my $pkg_key ( keys %{ $self } ) {
next unless ( ref $self->{ $pkg_key } eq 'HASH' );
! if ( $self->{ $pkg_key }{name} eq $name ) {
push @match, $self->{ $pkg_key };
DEBUG && _w( 1, "Found package $pkg_key; try to match up with package $name" );
|
|
From: Chris W. <la...@us...> - 2001-10-11 15:20:33
|
Update of /cvsroot/openinteract/OpenInteract In directory usw-pr-cvs1:/tmp/cvs-serv18753 Modified Files: MANIFEST Log Message: added new template/ items from base_component package Index: MANIFEST =================================================================== RCS file: /cvsroot/openinteract/OpenInteract/MANIFEST,v retrieving revision 1.58 retrieving revision 1.59 diff -C2 -d -r1.58 -r1.59 *** MANIFEST 2001/10/11 03:57:09 1.58 --- MANIFEST 2001/10/11 15:20:31 1.59 *************** *** 106,109 **** --- 106,110 ---- t/dummy.t template/data_cell_begin + template/date_select template/form_checkbox template/form_hidden *************** *** 114,117 **** --- 115,119 ---- template/form_select_options_iterator template/form_select_options_list + template/form_select_options_plain_list template/form_submit template/form_submit_row *************** *** 128,134 **** template/label_row_begin template/label_text_row template/row_color template/search_results_page_listing template/show_label template/table_bordered_begin ! template/table_bordered_end \ No newline at end of file --- 130,138 ---- template/label_row_begin template/label_text_row + template/page_count template/row_color template/search_results_page_listing template/show_label template/table_bordered_begin ! template/table_bordered_end ! template/to_group \ No newline at end of file |
|
From: Chris W. <la...@us...> - 2001-10-11 15:18:14
|
Update of /cvsroot/openinteract/OpenInteract/template
In directory usw-pr-cvs1:/tmp/cvs-serv17951
Added Files:
to_group
Log Message:
copied to_group component from base_component
--- NEW FILE: to_group ---
[%########################################
to_group()
Display a from and to SELECT box (SIZEd) for moving items from
one group to another, plus the Javascript necessary to make it
happen.
This is not a complete form, just a self-contained table you can
place anywhere you wish.
To make this work, you must have an onSubmit handler for your
form; just add this to the form tag:
onsubmit="return tally_added_items()"
In your application, all the 'id' values will be
semicolon-separated in a form field named whatever the
'mem_list_hold' variable was set to.
Parameters:
form_name - name of form where these items reside
from_element - name of the SELECT control that has the population of records
to_element - name of the SELECT control that has the member records
pop_list - list of population record hashrefs: id = x, name = y
mem_list - list of member record hashrefs: id = x, name = y
mem_list_hold - name of hidden variable that will hold the ID numbers
label_from - label to place over SELECT control with population
label_to - label to place over SELECT control with members
id_field - hash key under which the ID (or 'OPTION' value) is stored
name_field - hash key under which the value is stored
list_size - size of SELECT lists (DEFAULT: 6)
Defaults:
id_field = 'id'
name_field = 'name'
list_size = 6
########################################%]
[%- DEFAULT id_field = 'id';
DEFAULT name_field = 'name';
DEFAULT list_size = 6; -%]
<!-- Begin table with to_group tool -->
<table border="0" cellspacing="0" cellpadding="5">
<tr>
<td align="center">
<b>[% label_from %]</b>
</td>
<td align="center"> </td>
<td align="center" colspan="2">
<b>[% label_to %] </b>
</td>
</tr>
<tr>
<td align="right" valign="bottom">
<select name="[% from_element %]" size="[% list_size %]">
[% FOREACH pop_item = pop_list %]
<option value="[% pop_item.$id_field %]">[% pop_item.$name_field %] </option>
[% END %]
</select>
</td>
<td align="center" valign="middle">
<input type="button" name="add" value=">>" onclick="add_item()"><br>
<input type="button" name="remove" value="<<" onclick="remove_item()"><br>
</td>
<td align="left" valign="bottom">
<select name="[% to_element %]" size="6">
[% FOREACH mem_item = mem_list %]
<option value="[% mem_item.$id_field %]">[% mem_item.$name_field %] </option>
[% END %]
</select>
</td>
<td align="left" valign="middle">
<input type="button" value="Up" onclick="raise_item()"><br>
<input type="button" value="Down" onclick="lower_item()"><br>
</td>
</tr>
</table>
<input type="hidden" name="[% mem_list_hold %]">
<!-- End table with to_group tool -->
<script language="javascript">
// NAME of the form we're editing
var edit_form_name = '[% form_name %]';
// NAME of the element that has the list of ALL items
var from_element = '[% from_element %]';
// NAME of the element that has the member list
var to_element = '[% to_element %]';
// NAME of the hidden variable that will hold the
// packed value of all the member items.
var mem_list_hold = '[% mem_list_hold %]';
[%####################
NOTE: There are no other TT-modified variables below this point;
just Javascript.
####################-%]
// Raise an item in the listings. Remove the option
// above the one selected.
function raise_item() {
var form = self.document[ edit_form_name ];
var members = form[ to_element ];
var idx = members.selectedIndex;
// alert( 'Selected index: ' + idx );
if ( idx == 0 ) {
alert( 'Cannot raise an item already at the top!' );
return false;
}
var new_opts = new Array();
// Remove the option above the one selected
// and save it.
var save_idx = idx - 1;
new_opts[0] = new Option( members.options[ save_idx ].text, members.options[ save_idx ].value );
members.options[ save_idx ] = null;
// confirm( 'Value of first option: ' + new_opts[0].value + ' -- ' + new_opts[0].text );
var end_list = members.options.length - 1;
var this_opt;
for ( i = end_list; i >= idx; i-- ) {
// alert( 'Trying option: ' + i );
this_opt = new Option( members.options[ i ].text, members.options[ i ].value );
new_opts.push( this_opt );
members.options[ i ] = null;
// confirm( 'Value of option just added for space ' + i + ': ' + this_opt.value + ' -- ' + this_opt.text );
}
for ( j = 0; j < new_opts.length; j++ ) {
this_opt = new_opts[ j ];
// confirm( 'Going to add: ' + this_opt.value + ' -- ' + this_opt.text );
members.options[ members.options.length ] = new Option( this_opt.text, this_opt.value );
}
return true;
}
// Lower an item in the listings -- first remove
// it OI.from its place as well as all items below,
// then reinsert the items at the end.
function lower_item() {
var form = self.document[ edit_form_name ];
var members = form[ to_element ];
var idx = members.selectedIndex;
if ( idx == members.options.length - 1 ) {
alert( 'Cannot lower an item already at the bottom!' );
return false;
}
var new_opts = new Array();
// Put the option selected at the head of the options
// to be inserted.
new_opts[0] = new Option( members.options[ idx ].text, members.options[ idx ].value );
// Remove the option selected. members.options[ idx ]
// will be the option that 'moves up'.
members.options[ idx ] = null
// alert( 'Value of first option: ' + new_opts[0].value );
// Cycle down OI.from the end of the list and eliminate
// options, saving them in the new_opts list.
var end_list = members.options.length - 1;
var this_opt;
for ( i = end_list; i > idx; i-- ) {
this_opt = new Option( members.options[ i ].text, members.options[ i ].value );
new_opts.push( this_opt );
members.options[ i ] = null;
// alert( 'Value of option just added: ' + new_opts[ new_opts.length - 1 ].value );
}
// Now, cycle through the saved options and add each in
// turn to the end of the displayed options.
for ( j = 0; j < new_opts.length; j++ ) {
this_opt = new Option( new_opts[ j ].text, new_opts[ j ].value );
members.options[ members.options.length ] = this_opt;
}
return true;
}
function add_option ( Element, Text, Value ) {
var form = self.document[edit_form_name];
var members = form[ Element ];
var newopt = new Option( Text , Value );
for ( opt = 0; opt < members.options.length; opt++ ) {
if ( members.options[opt].value == Value )
return false;
}
members.options[ members.options.length ] = newopt;
return true;
}
function remove_option ( Element, Value ) {
var form = self.document[edit_form_name];
var members = form[Element];
for ( opt = 0; opt < members.options.length; opt++ ) {
if ( members.options[opt].value == Value ) {
members.options[opt] = null;
return true;
}
}
return false;
}
function add_item ( ) {
var form = self.document[edit_form_name];
var listing = form[from_element];
var idx = listing.selectedIndex;
if ( idx == -1 ) {
alert('Please pick an item to add!');
return false;
}
if ( listing.options[idx].value == '' ) {
return false;
}
var id = listing.options[idx].value;
var value = listing.options[idx].text;
add_option( to_element, value, id );
remove_option( from_element, id );
return true;
}
function remove_item ( ) {
var form = self.document[edit_form_name];
var listing = form[to_element];
var idx = listing.selectedIndex;
if ( idx == -1 ) {
alert('Please pick an item to remove OI.from the member list!');
return false;
}
if ( listing.options[idx].value == '' ) {
return false;
}
var id = listing.options[idx].value;
var value = listing.options[idx].text;
remove_option( to_element, id );
add_option( from_element, value, id );
return true;
}
function tally_added_items ( ) {
var form = self.document[edit_form_name];
var listing = form[to_element];
var return_string = '';
for ( opt = 0; opt < listing.options.length; opt++ ) {
if ( listing.options[opt].value != '' )
return_string += listing.options[opt].value + ';';
}
return_string = return_string.substring( 0, return_string.length - 1 );
form[ mem_list_hold ].value = return_string;
// return confirm( 'Value of itemlist: ['+form[mem_list_hold].value+']. Continue?');
return true;
}
</script>
|
|
From: Chris W. <la...@us...> - 2001-10-11 15:17:55
|
Update of /cvsroot/openinteract/OpenInteract/template
In directory usw-pr-cvs1:/tmp/cvs-serv17827
Added Files:
form_select_options_plain_list
Log Message:
enable plain lists (as opposed to objects) to be used in SELECT creation
--- NEW FILE: form_select_options_plain_list ---
[%########################################
form_select_options_plain_list( value_list, label_list, picked )
Cycle through all objects in a list and display an <OPTION> for
each.
########################################-%]
[%- FOREACH idx = [ 0..value_list.max ] -%]
[%- SET label = ( label_list.$idx ) ? label_list.$idx : value_list.$idx;
SET value = value_list.$idx -%]
[%- INCLUDE form_select_option -%]
[%- END -%]
|
|
From: Chris W. <la...@us...> - 2001-10-11 15:17:19
|
Update of /cvsroot/openinteract/OpenInteract/template
In directory usw-pr-cvs1:/tmp/cvs-serv17678
Added Files:
page_count
Log Message:
copied page_count component from base_component
--- NEW FILE: page_count ---
[%#########################################
page_count( total_pages, current_pagenum, url, break_count )
Component to display the total number of pages and for each of
the pages not current link it to a URL to display that page.
Parameters:
total_pages - Total number of pages in result set
current_pagenum - Page you are currently on
url - URL to which we append ';pagenum=x'
break_count - number of pages to display on a line
Defaults:
break_count = 20
########################################-%]
[%- DEFAULT break_count = 20 -%]
Page [
[%- FOREACH page_count = [ 1 .. total_pages ] -%]
[%- IF page_count == 1 -%]
[%- IF current_pagenum != 1 -%]
<a href="[% url %];pagenum=[% current_pagenum - 1 %]"><<</a>
[%- ELSE %]<<[% END -%]
[%- END -%]
[%- IF page_count == current_pagenum %][% page_count %]
[%- ELSE %]<a href="[% url %];pagenum=[% page_count %]">[% page_count %]</a>
[%- END -%]
[%- IF page_count mod break_count == 0 -%]<br>[% ELSE %] [% END -%]
[%- IF page_count == total_pages -%]
[%- IF current_pagenum != total_pages -%]
<a href="[% url %];pagenum=[% current_pagenum + 1 %]">>></a>
[%- ELSE %]>>[% END -%]
[%- END -%]
[%- END -%]
]
|
|
From: Chris W. <la...@us...> - 2001-10-11 15:15:12
|
Update of /cvsroot/openinteract/OpenInteract/template
In directory usw-pr-cvs1:/tmp/cvs-serv17029
Added Files:
date_select
Log Message:
copied date selecting component from base_component
--- NEW FILE: date_select ---
[%########################################
date_select( year_list, year_value, month_value, day_value,
blank, year_field, month_field, day_field, field_prefix )
Display three dropdown boxes for inputting dates.
Parameters:
year_list = list of years
year_value = chosen year
month_value = chosen month (number)
day_value = chosen day (number)
blank = if true, start each SELECT with a blank option
year_field = name for year SELECT
month_field = name for month SELECT
day_field = name for day SELECT
field_prefix = use instead of specifying year/month/day_field;
prefix to put in front of '_year', '_month' and
'_day' (e.g, if field_prefix = 'birthdate', the
fields would be 'birthdate_year',
'birthdate_month', and 'birthdate_day')
comment = if true includes an HTML comment with values (debugging)
Defaults:
year_list = 2000 .. 2010
########################################-%]
[%- SET month_names = [ 'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec' ];
DEFAULT year_list = [ 2000..2010 ]; -%]
[%- IF field_prefix -%]
[%- month_field = "${field_prefix}_month";
day_field = "${field_prefix}_day";
year_field = "${field_prefix}_year"; -%]
[% END -%]
[% INCLUDE form_select( name = month_field, plain = 1, first_blank = is_blank,
value_list = [ 1..12 ], label_list = month_names,
picked = month_value ) -%]
[% INCLUDE form_select( name = day_field, plain = 1, first_blank = is_blank,
value_list = [ 1..31 ], picked = day_value ) -%]
[% INCLUDE form_select( name = year_field, plain = 1, first_blank = is_blank,
value_list = year_list, picked = year_value ) -%]
[% IF comment %]<!-- Date: [% year_value %] (y) [% month_value %] (m) [% day_value %] (d) -->[% END -%]
|
|
From: Chris W. <la...@us...> - 2001-10-11 15:14:34
|
Update of /cvsroot/openinteract/OpenInteract/template
In directory usw-pr-cvs1:/tmp/cvs-serv16791
Modified Files:
search_results_page_listing
Log Message:
create a break point so that resultsets with lots of pages don't make
the page 1200+ pixels wide (since we use )
Index: search_results_page_listing
===================================================================
RCS file: /cvsroot/openinteract/OpenInteract/template/search_results_page_listing,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** search_results_page_listing 2001/10/08 20:20:00 1.1
--- search_results_page_listing 2001/10/11 15:14:31 1.2
***************
*** 1,18 ****
[%########################################
! search_results_page_listing( table_width, total_pages, current_page,
! search_results_key, search_id, align, base_url )
Generate a table of the specified width with the search results
listing in it.
########################################-%]
! [%- DEFAULT align = 'right';
! DEFAULT table_width = '90%'; -%]
<table border="0" width="[% table_width %]"
cellpadding="2" cellspacing="0">
<tr><td align="[% align %]">
! [%- return_url = "$base_url?$search_results_key=$search_id" -%]
! [%- OI.comp( 'page_count', total_pages = total_pages,
! current_pagenum = current_page,
! url = return_url ) -%]
</td></tr>
</table>
--- 1,37 ----
[%########################################
! search_results_page_listing( table_width, search_results_key, search_id, align,
! base_url, total_pages, current_page )
Generate a table of the specified width with the search results
listing in it.
+
+ Parameters
+ table_width - width of the table
+ search_results_key - name of field to set the search results key to
+ search_id - ID to retrieve search results
+ align - align the listing
+ base_url - URL to which we append ?$search_results_key=$search_id;pagenum=x
+ so we can get more search results
+ total_pages - total pages in resultset
+ current_page - what page you're on
+
+ Defaults
+ align - 'right'
+ table_width - '90%'
+ search_results_key - 'search_id'
+
########################################-%]
! [%- DEFAULT align = 'right';
! DEFAULT table_width = '90%';
! DEFAULT search_results_key = 'search_id'; -%]
<table border="0" width="[% table_width %]"
cellpadding="2" cellspacing="0">
<tr><td align="[% align %]">
! [%- return_url = "$base_url?$search_results_key=$search_id" -%]
! <font size="-1">
! [%- PROCESS page_count( total_pages = total_pages,
! current_pagenum = current_page,
! url = return_url ) -%]
! </font>
</td></tr>
</table>
|