View · Search · Index


Filtered by category Cookbook, 11 - 20 of 21 Postings (all, summary)

XoWiki: How to save files directly in the wiki

Created by Gustaf Neumann, last modified by Benjamin Brink 30 Jun 2017, at 07:08 AM

In order to save files directly in the wiki, just add a link with the content file:yourfile to a page (as for other links, between curly double brackets).

[[file:oacs-dotlrn-vienna-xowiki.pdf|XoWiki Slides from the Vienna OpenACS conference]]

When the file link is added, and the file does not exist, the wiki marks the link with a handle to upload the file. According to the current policies, everybody who is logged-in has sufficient permissions is allowed to edit pages.. 

Here is an example of a file-link, pointing to the xowiki slides from the the Vienna oacs-dotlrn conference XoWiki Slides from the Vienna OpenACS conference 


OpenACS Performance Tuning

Created by OpenACS community, last modified by Benjamin Brink 30 Jun 2017, at 06:56 AM

OpenACS Performance Tuning

Here is some documentation on general OpenACS performance tuning:

Much performance tuning is targeted at the subsystems level, and so you will find some specific tuning information in these pages:

A broad scope of causes can be attributed to OpenACS performance issues. These forum threads help identify useful diagnostic techniques and accurate testing to help narrow the scope of problem areas etc.

Outgoing E-Mail

Created by Malte Sussdorff, last modified by Benjamin Brink 30 Jun 2017, at 06:55 AM

Current documentation for ACS Mail Lite, the standard API for inbound and outbound email is at .


Outgoing E-Mail at the moment in acs-mail-lite is split in a multitude of procedures, some doubling the efforts of the other. To clean this up I propose the following (in general):

  •  Replace acs-mail-lite::send with acs-mail-lite::complex_send, making it a wrapper for complex_send or the other way round (rename complex_send to send and so on).
  • Only support sending of e-mails via SMTP. Use smtp::sendmessage from TCLLIB for it (as does complex_send).
  • Daveb suggested to split up complex_send  to make it easier to test parts of it. Here are some ideas:
    • Sub procedure to generate "to/cc/bcc/_lists" which are used in the respective TO/CC/BCC header. This will also clean up the sending of individual emails.
    • Have only one call to smtp::sendmessage and one hook for the complex_send callback.
    • Sub-procedure to append file tokens. Not sure this is useful as we need to do upvar for the tokens and could not do automated tests on them anyway. So I'd not do it.
  • Have only one sweeper (the complex_sweeper) with support for multiple mail sending servers (so you can have multiple mail senders in the cluster instead of only one).
  • Split of incoming email handing into a separate file
  • Delete acs-mail-lite-procs.tcl :-). Just kidding, but deprecate most of the procedures.

Sadly it is not a straightforward approach, as there is a catch. Using smtp::sendmessage forces us to figure out a new way for setting the bounce-email address header, as the old approach will not work anymore (using the SMTP command "FROM" set to the bounce address). Another options is to use the non-standard "Errors-To" Header  instead.

Email Event Handling

Created by Dave Bauer, last modified by Benjamin Brink 30 Jun 2017, at 06:54 AM

Sending email on certain events in OpenACS/.LRN is done very haphazardly. This needs to be rewritten so there is a simple way to figure out when an email will be sent, and allow proper handling of user preferences, administrative parameters, and customization.

There are cases where the system (OpenACS or .LRN) needs to send out email, for example, when a new user joins, requests a password reset, or is added to a subsite or .LRN community.

Right now there isn't any system-wide way to mange this email. In some cases, the administrator is notified an email will be sent and is given the option to edit the email before it is sent, but there is no one way this is done.  There are several pages that call  ns_sendmail explicitly, or acs_mail_lite::send explicitly. There are more places this happens in .LRN. Unfortunately there is also a "magic" place where email is sent that is totally unexpected. Inside the dotlrn_community::membership_approve procedure, there is a call to dotlrn_community::send_member_email, which will send an email to the user when the membership is approved, if 1) a parameter is set and 2) an administrator has created and enabled an email message to be sent.

 In addition there is a email sent using the "spam" package in dotlrn/www/admin/users-add-to-community where a dotlrn sitewide administrator can add users to a community, and the users are automatically emailed. In this case the administrator is not notified that an email is sent, or given an opportunity to customize or suppress the email. This causes problems when an administrator attempts to fix a problem by adding a user to a community automatically, and the user is sent a confusing message.

The dotlrn package allows for a custom email to get written by the community admin for each community, but the admin is not allowed to choose if the email is sent when an individual member is added. It is either on or off, always sent, or never sent.

dotlrn-ecommerce extends this by adding several more events for application submission, approval, rejection, etc. And admin can edit these emails on a sitewide or per community basis. In most cases the email is automatically sent, in one o r two cases the admin can edit the email, but not suppress it.

This leads to unwanted email. Often an admin must manually add or remove someone from a subsite or community or otherwise handle a problem. This can lead to welcome emails being sent at the wrong time, confusing the users. 

 A system wide solution would allow packages to create events where email is sent by the system (besides subscribed notifications). This solution would provide an includable interface for creating and editing a default email message for the events. It would also provide an interface to notify an admin that an email will be sent, giving options to suppress the email or edit the content of the email before sending it.

 The beginnings of this feature exist in the dotlrn_member_emails table, dotlrn_community::send_member_email procedure, and the dotlrn-ecommerce package which has a few pages that replicate this interface, but probably needs more generalization to allow working with subsites as well as dotlrn communities. There is also the reusable include for editing the default emails under dotlrn/lib/member-email

This proposal would provide a comprehensive solution for handling system level email events, allowing admins to know when an email is sent, and provide a consistent user interface to manage the emails.



You could achieve this in a general way by using the acs-lang interface at least for the subject and body. For each object_id you would create a new message key, e.g. acs-translations.welcome_email_subject_${object_id} and acs-translations.welcome_email_body_${object_id}. If you have multiple emails per community / subsite, you would rename them to acs-translations.confirmation_email_subject_${object_id} aso. A general interface would then be provided to look for all language key combinations of acs-translations.email_xxx, allowing you to edit the messages for all communities and subsites. If you want to edit them for only one, then you can look for all who have the same object_id. 

A default message would be given with acs-translations.email_subject_welcome, which the mail sending could default to in case no specific language key exists for the community / object_id. Furthermore, acs-translations.welcome_email_help message key is present describing what this email is about. A package like dotlrn would register the three default e-mail keys to start off with this and then the email-handling package can do the rest (e.g. with email-handler::send -to_party_ids -from_addr -email_type "welcome" -object_id).

This approach has the major advantage that you have internationalization by default.

Alternatively you could mimic the message handling done by contacts which allows you to have multiple message types, e.g. email, which you can fill in with default values, which has it's own I18N by having a locale stored in the DB table. But if you ask me, the acs-translations idea sounds better to me :). Though, you can obviously do this with your own tables as well, but you would loose on the nice features acs-lang has to offer.


 Files that currently could trigger email

add_user calls add_user_to_community

add_user_to_community calls membership_approve (if applicable). membership_approve calls send_member_email unconditionaly

so any call to add_user or add_user_to_community could result in a call to send_member_email





Add extra headers

Created by Rocael Hernández Rizzardini, last modified by Benjamin Brink 30 Jun 2017, at 06:53 AM

Usually you can do it with templates:
<property name="header_stuff">

But sometimes you want to add it not in just one page, so you usually go to www/site-master.adp, but that is not really good to maintain modularity, so instead, now you can define within your package a tcl callback like this:

ad_proc -public -callback subsite::get_extra_headers -impl my_implementation {} {
    return the stuff that should go into the html headers
} {

    set scripts "...."
    set tags "...."

    set text_to_return $scripts
    append text_to_return $tags

    return $text_to_return


Using Pound as a reverse Proxy

Created by Nima Mazloumi, last modified by Benjamin Brink 30 Jun 2017, at 06:52 AM

Requirements: You have OpenSSL installed and created a certificate.


  • You have OpenACS 5.2 installed (branch oacs-5-2) under /www/service0
  • Your Server has the IP-Address
  • Pound is running on Port 443 under user "root" and group "users"
  • AOLserver on, Port 10000
  • Your certificate is under "/www/service0/certs/certificate.pem"

For an alternative of pound, see Nginx  with a sample configuration from Malte .

In order to use Pound for Load-Balancing and SSL encryption follow the below steps. Call "man pound" for a detailed description of the used parameters.

  1. Install Pound

    cd /opt/src
    tar xzpf Pound-2.1.6.tgz
    cd Pound-2.1.6
    make install

  2. Configure Pound

    emacs /usr/local/etc/pound.cfg/usr/local/etc/pound.cfg

    User            "root"
    Group           "users"
    LogLevel        0
    Alive           10

                Port 443
                Cert "/www/service0/certs/certificate.pem"
                xHTTP 2
                HeadRemove "X-SSL-Request"
                HeadRemove "X-Forwarded-For"
                AddHeader  "X-SSL-Request: 1"

                    URL ".*"
                            Port 10000

  3. Configure AOLserver

    emacs /www/service0/etc/config.tcl

    set httpport              10000
    set address     

  4. Start Pound+AOLserver



How to configure a Network Place under Windows XP to access file-storage via WebDAV

Created by Robert Taylor, last modified by Benjamin Brink 30 Jun 2017, at 06:50 AM


How to configure a Network Place under Windows XP to access a WebDAV folder in file storage. 


Creating a Network Place will allow you to drag and drop multiple files and even folders from your machine to your OpenACS or .LRN  website. Once you have done these eleven (arguably ten) simple (really!) steps to create a permanent connection on your computer to your file storage location. The Network Place will be accessible through My Network Places.

Once you have established a Network Place to your File Storage documents, you can transfer multiple files, create/delete/edit folders, delete files. Creating and modifying files and folders through the Network Place is the same as you would do using Explorer. You can also open, edit and save files without the hassle of downloading, saving and uploading them on your machine!



Step 1: To create a Network Place, open Windows Explorer.

Then, right click on "My Network Places" and select Open.


Step 2: Under Network Tasks, Select "Add a Network Place."


Step 3: Click "Next" to start the Wizard.

Step 4: Highlight "Choose Another Network Location" (if it is not already) and click "Next."



Step 5: Copy the WebDAV URL listed in the file storage folder you want to access and paste it in as the "Internet or Network Address" for your connection.


Step 6: Select "Yes" when you are prompted with the Security Alert dialog.


Step 7: Enter the email address you use to log into the site (or username if your site uses usernames) and password in the "Connect to:" dialog box. This establishes your connection to the Network Place.


Step 8: Create a name for the new Network Place or accept the default and then click "Next."


Step 9: Leave "Open this network place when I click Finish" checked.

Click "Finish" to complete the Wizard.


Step 10: The first time you do this, you may be prompted again with the Security alert and a login screen. Please say "Yes" to the alert.

Step 11: You may also need to login again using your site email address and password. (This is a Microsoft thing, not a bug and we can't do anything about it.)

Voila! Your new Network Place will open and you will see the folders as they appear in file-storage on your site. You can now open Explorer and select, drag and drop multiple files or folders from your machine into SloanSpace. After you do this, refresh your browser to see the files/folders.

The Network Place is permanent, so you only need to set it up once and reconnect to it when you need to (through My Network Places.


Passing values up from an include

Created by irc community, last modified by Benjamin Brink 30 Jun 2017, at 06:47 AM

following dialog from irc (names changed..) shows how to trick the system to pass values from an include to the calling page. This trick needs to be turned into real documentation.

dave: you can't pass stuff up from an include
dave: you have to use upvar
dave: ie: something like this works
michael: but, yes, the order is important. i.e., if i pass a reference to an include and hope to get/use a modified value, the value will be there *after* the <include>
dave: here is what works :)
dave: if you pass a property to a master template
dave: like this
dave: <property name="foo">@foo</property>
dave: <include src="myinclude">
dave: you can upvar #[template::adp_level] foo myfoo
dave: set myfoo "something"
dave: and something will be passed up to the master
dave: but since the code is just one big script
dave: you can't modify code that happens before
dave: we discussed quite a few times a way to work around that
dave: you could upvar something which would be available AFTER the include in the script
michael: i can do the same thing by passing in a reference
dave: yeah
dave: i just though of tha t:)
dave: cool.
michael: and the value will be there after the include
michael: so i just have to move my <property> tags to the bottom of the adp
dave: although that should be documented somehow that an include is modifying stuff in the caller
dave: i don't think you do. I can't remember. did that ages ago for gp and that code is hopefully long gone :)
michael: yeah, i tried it dave:
dave: cool.
tektubby: aha! one of the 7 mysteries of OpenACS solved.
dave: putting property at the bottom works? pretty clever
michael: when referencing the variable (set to "") before the include, i get "" on the calling page
michael: after the include, i get the modified value

Overview of Cookbook

Created by Gustaf Neumann, last modified by Benjamin Brink 29 Jun 2017, at 11:36 AM

Permissions explored, a practical way exists

Created by openacs irc community, last modified by Benjamin Brink 29 Jun 2017, at 04:31 AM

This is from a discussion about permissions on OpenACS' irc (names changed) that took place sometime circa 2005.

ryan: How do I create a group containing other groups? 
dave: composition_rel 
ryan: For instance, I have 30 admin groups, and instead of adding user A to each one manually, I want to add her to one group, and thus all 30. 
dave: what are you trying to accomplish? 
dave: you can't do that 
ryan: crap. 
dave: it it totally non-intuitive 
dave: here is why :) 
dave: we have the Super Admin group 
dave: wait. dave: no it doesn't work 
ryan: So what is a composition_rel? I thought parties were supposed to be a super-set of groups. 
dave: let me explain :) 
dave: no 
ryan: ok, thanks :) 
dave: here is how it works. 
dave: Super Admin 
dave: then we have admins_a which is a component of super admins 
dave: maybe it can work. 
dave: question is dave: can a group dave: have a composition_rel to more than one other group 
ryan: So what is the definition of a component? 
dave: lets find out. 
dave: a component 
dave: so if Admin A is a component of Super Admin 
dave: then every member of A is a member of Super 
dave: which is NOT what you want. 
dave: you want ever member of super to have permission over all the groups "inside" it right? 
dave: but in this case every member of A would have permission over all the other components etc. 
dave: group are NOT for permissions. 
dave: that is the design weirdness 
ryan: huh? 
ryan: Now I am completely confused. 
dave: you can't use groups the way you want 
ryan: isn't the whole point of groups to avoid permissioning on individual users? 
jim: but you should be able to build a page that asks for a user and puts the user into the 30 groups 
dave: ryan, yes. 
dave: you they don't inherit the way you think 
ryan: so you set permissions on a group with a set of objects, then just add/remove users from the group, right? 
dave: its backwards to what you are thinking. 
dave: yes dave: that works 
dave: perfectly 
jim: so you can get what you want (convenience, non-tedium) but have to do it another way 
dave: but composition_rels dave: behave backwards 
dave: they are not useful for org chart models 
ryan: ah ok. 
dave: but I think it can work 
ryan: What is an application of composition_rels? 
dave: here is what you would do 
dave: if it works 
dave: create all your groups 
dave: Admin A, Admin B etc 
ryan: done. 
dave: then make one group 
dave: and give it a composition rel to all of those groups. 
dave: its upside down. 
dave: then if I am in the one group, i am in all of those other groups 
jim: so you're putting the one group into all the groups 
jim: that should work :) 
dave: yes d
ave: b/c its not _in_ 
dave: its a component. d
ave: i think that will trigger the correct permissions. 
ryan: how do components work in the data model - I want to understand this better. 
dave: well jim: it' dave: then I recommend you 1) read the acs-kenrel sql files 
jim: s a special kind of acs_rel 
dave: 2) run alot fo experiments in psql 
dave: 3) find a bug in the triggers 
dave: :) 
dave: that is how I figured it out. 
dave: sucks huh. 
dave: seriously the comments in the SQL files in acs-kernel are very illuminating. 
dave: also have you read permissions tediously explained? 
ryan: but you're it'll work? ryan: Yes. d
ave: i am not sure it'll work 
dave: but jim: we think it will work r
yan: but I could re-read it a fourth time 
dave: i don't see any rule 
dave: that disallows a group being a component of more than one group 
dave: if there is such a rule, it won't work. 
ryan: but compositions typically extend 'up' the chain of groups? 
dave: yes dave: that is what its for 
dave: so for example 
ryan: what is a practical example? 
dave: I have Main Subsite 
dave: and several other subsites 
dave: wait 
dave: actually this is an example of why it doesn't work :) 
dave: hmmm actually I have to check 
dave: not sure if susbsite groups are components of main subsite or not. 
dave: .... 
ryan: You see, I want to create this super group and then let the client admin the members... 
dave: ok there are no rel_constraints on a default install. so that should be safe. 
dave: yes d
ave: but its really a sub-group 
jim: try it with two groups and another group be a component of both groups... give each of the first two groups two different permissions... put a user into the component group... 
dave: a super group would not work the way you want. 
dave: here i what you do 
jim: see if the user has both perms 
dave: 1) create two groups 
dave: 2) create another group 
dave: 3) make the third group a component of the first two 
dave: 4) add someone to the third group 
dave: 5) check if they are a member of 1 and 2 
dave: for extra credit 
dave: apply a permission to 1 and 2 
dave: check if the members of 3 have permission on those things 
dave: if this works 
jim: 1-4 and the extra credit are what I just sed :) 
dave: i just solved the oldest OpenACS 4 riddle 
joe: As a topical aside, we changed the way we use groups in our subsites for dotcommunity. One for admins and one for members (so we don't use admin_rels). Then we use a composition rel to make admins of top level sites also admins of lower level sites, and to compositions in the opposite direction to make members of lower level sites members of the higher level ones too. 
dave: jim, yes :) 
jim: 5 is a good idea too 
ryan: ok, sounds good. Will test and get back to you. That would be very cool if it could work both ways. Obviously it is important to be able to have groups of groups... 
dave: joie: you could still use admin_rels to do that 
dave: it would work the same way. 
dave: ryan, yes if that works the way I expect it would be cool. 
dave: joie, so is the lower level admin group a component of the higher level admin group? 
joe: The problem with admin rels was that an admin of a subsite became an admin of the supersite, which isnt what we wanted. 
dave: or the other way around? 
dave: joie: yes dave: that is what I just said 
dave: the component rels go the wrong way 
dave: than what you would think intuitively 
dave: although mathematically they work correctly as specified. 
dave: damn PhDs 
dave: basically we need to write high-level functional wrappers over all this crap 
joe: So we have a composition rel going "down" for admins, and "up" for members. So the supersite admin group is a component of the subsite's admin group, and the subsite's members group is a component of the supersites members group. 
dave: so you can just call a tcl proc that tells you what happens (instead of what is does in the database) dave: joie: ah so it _does_ work. that is just what I told ryan-g to do 
dave: we need to write a tcl api to do that that is clear what is happening. 
jim: so members of the subsite become also members of the supersite 
dave: yes dave: which makes sense 
joe: Indeed. Then we frigged the acs-subsite members pages to do the "right thing". 
dave: but then admins of the subsite become admins of the supersite (if you use admin_rels) 
dave: which is why you don't want to do that. 
dave: joie: but you are right 
dave: and openacs is wrong 
dave: except I doubt there is an upgrade script that would work 
dave: damn PhDs 
dave: joie: 
why the hell didn't you tell us this before? :) 
dave: i have been trying to figure that out for 4 years 
joe: We have an upgrade script that does it somewhere. Rob wrote it. 
dave: you rock. 
joe: We weren't sure the new way was "right". 
dave: yeah dave: it is dave: b/c it makes sense dave: well 
dave: except dave: no its right. 
joe: We then got rid of admin_rels completely. 
joe: and only use membership_rels 
dave: b/c everyone expects it to work that way 
dave: yeah see 
dave: the problems is 
dave: all this stuff was experimental 
dave: and no one every finished it jim: you would need to be careful when deleting certain objects 
dave: except you did. 
dave: so now we can say "this is the way its supposed to work' We can say that because that is the way every one has expected it to work, but it never did 
dave: wow 
jim: make sure to remove all rels first then delete 
dave: i am so surprised. 
joe: The code is in the dotCommiunity download on The upgrade scripts aren't there though. 
dave: this is so cool. 
dave: get them! 
dave: :) 
joe: Heh. I'll talk to Rob about it tomorrow, as not sure what he implemented.


Next Page
previous December 2019
Sun Mon Tue Wed Thu Fri Sat
1 2 3 4 5 6 (1) 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 1 2 3 4

Popular tags

17 , 5.9.0 , 5.9.1 , ad_form , ADP , ajax , aolserver , asynchronous , bgdelivery , bootstrap , bugtracker , CentOS , COMET , compatibility , CSP , CSRF , cvs , debian , emacs , engineering-standards , fedora , FreeBSD , guidelines , host-node-map , hstore , includelets , install , installation , installers , install-ns
No registered users in community xowiki
in last 30 minutes