Forum OpenACS Q&A: Development Tutorial Available

Collapse
Posted by Joel Aufrecht on
I've finished the first draft of a tutorial for new OpenACS developers. It walks you through the minimum steps to create a working, conformant package. I am looking for feedback from everybody: new developers, what can be improved? Veterans, what's wrong or misleading or not a best practice? What else should go into the advanced topics section?
Collapse
Posted by Ola Hansson on
Hi Joel,

Nice job on the docs...

- In figure 8.2 you might want to explain what the "@cvs-id $Id:$" looks like before it gets automatically filled in.

You probably want to say: select define_function_args(samplenote__new title,body,object_type;samplenote,creation_date,creation_user,creation_ip,contect_id);

(immedeately before the parameter list). I think it is wise to use this technique for all plpgsql functions, but not in (oracle) plsql. It lets you make use of the practical Tcl proc "package_instantiate_object" when you create an instance of your object type. This way it is possible to write a very clean Tcl API for object creation.

- In figure 8.3 I think there is an easier way to drop the functions of a package; simply call "select drop_package('samplenote');" and be done with it.

I'll see if there are more things I can nit-pick on 😉

/Ola

Collapse
Posted by Alfred Werner on
Comments on database page:

The way people read a page, I would break the following text out from the grey box its in because its not logically related, it really goes with the next chunk:

[service0@yourserver sql]$ cd postgresql/
[service0@yourserver postgresql]$ emacs samplenote-create.sql

either put it in its own gray box, add it to the next one or do it in the whitespace between ..

Just a nit :)

Nice work!

Collapse
Posted by Jade Rubick on
Joel, great work! This is probably the most important development in OpenACS in a while, in my opinion. Anything that makes it easier for new developers to get involved in the project helps us all out in the long run. Thank you!

I'm also really happy to see that you're using ad_form.

I liked how you incrementally built the tutorial, starting with the index page and later adding in other features. I think it was also a good idea to use ad_table.

You might want to explain what the APM is on the second page. Just say Automatic Package Manager or something.

You might also include a sentence explaining what ad_form is.

I really like the way you're doing documentation, Joel. Kudos!

Collapse
Posted by Jade Rubick on
Other nitpicks:

I wasn't able to figure out how to get the documentation portion working. I didn't seem to have the right files. Perhaps that's because I've already installed, using the older documentation.

I still would like to use the "approved" way of documenting my packages, but I'm not sure where to proceed. Could there be a link somewhere to the files I would need if I had installed without using your documentation earlier?

(Hope I expressed this well -- Joel, I'm totally ecstatic you've taken the time to write this documentation.)

Collapse
Posted by Joel Aufrecht on
What errors are you getting? there are a few rough edges:
  • Different installations of DocBook put necessary stylesheets in different places. You'll see a 'not found' and you can then locate the file on your system and replace the path in the Makefile.
  • Missing files. I'm still learning how to work with the OpenACS CVS repository. As of today, I think everything is present and in sync in the oacs-4-6 branch and at my site. But the 4.6.2 beta tarball is out of whack.

Everybody, thanks for your tips. I'll incorporate them as soon as I can.

Ola, when would one "make use of the practical Tcl proc 'package_instantiate_object'?" Is that something I should change the basic tutorial to reflect? Or is that an advanced topic?

Collapse
Posted by Ola Hansson on
Joel,

You'd use "package_instantiate_object" from a library proc that in this case ought to be called "samplenote::new" and ought to exist in a file named "samplenote/tcl/samplenote-procs.tcl" (see https://openacs.org/api-doc/proc-view?proc=forum::new&source_p=1 for an example from "forums").

This should go after creating the datamodel but before you describe how to write web pages, I think.

IMO we should almost always aim towards mirroring a package's PL[PG]SQL API in a Tcl API - as OF did throughout the forums package for instance (Thanks for teaching us that too, Ben!). Besides taking slightly longer to write a package, promoting this approach in general will not only result in reusable code (saves a lot of .xql file writing because queries in .xql files can't be reused in different places - it is not recommended, at least) but will also yeild code that's easier to read and has better self-documentation available from the Api Browser.

Whether this should be reflected in the basic tutorial or in  the advanced section, I don't know... Presumably we'd want all packages to be written as similar to one another as possible, stylewise. So it would probably be better to teach this as part of the general/basic package development section ... What do others think?

Oh yes, I found one small thing; every occurrence of "timestamp" should be changed to "timestamptz" which is an alias for "timestamp with timezone" (which should not be used IIRC).

/Ola

Collapse
Posted by Joel Aufrecht on
I'm concerned about the amount of overhead required to create and use a table:
  • set up a package and sql directory tree
  • create an acs object type
  • CREATE TABLE
  • set up three plpgsql functions, all hard to debug
  • create an order-sensitive drop script
  • and now, create a tcl directory and tcl wrapper function
I know it all pays off down the road, but we're up to three files in two directories with perhaps 200 lines of code just to get started. Since most of this is boiler-plate, are there any plans to automate some of this, either through auto-generation or functions?
Collapse
Posted by Jade Rubick on
I agree, Joel. While porting our company's packages to OpenACS 4, I'm finding this to be very high "overhead".

Perhaps one way to do it would be to provide a "package-template" package. This would be the basic structure, and when you're creating a new package, you could just copy the whole directory and modify as needed.

So you'd:

cd web/packages
cp -a package-template mynewpackage
cvs add mynewpackage
(etc)
cd mynewpackage

then edit all the files.

I'm not sure if that's much of an improvement, though.

Thanks for the notes about DocBook. I'll look into that when I have some free time.

Collapse
Posted by Char Wang on
Hi Joel, I am trying to create a package by following your document.
I am now at the "Write the Requirements and Design Specs" section, but I can't find the file "package-documentation-template.xml".
According to your documentation, it should be in the directory "/web/openacs-dev/packages/acs-core-docs/xml/docs/xml/", but there is no such directory.
It must because I am not using the same version of OpenACS as you did, so I tried to download the newest version from this site, yet it isn't exist either.
Could you give me some hint that where can I find that file? Or, if you are feeling fine, could you mail it to me?
I'll be very appreciate for that :)
Collapse
Posted by Dave Bauer on
Joel,

You might want to link to https://openacs.org/doc/tcl-doc.html (or the local copy) from the tcl pages part of your tutorial. http://aufrecht.org/doc/tutorial-pages.html

Collapse
Posted by Joel Aufrecht on
Oops. Use this example xml file for now and I'll fix the docs shortly.
Collapse
Posted by Randy O'Meara on
This is excellent, Joel.

In addition to the doc xml template, the doc Makefile is missing too.

Randy

Collapse
Posted by Randy O'Meara on
correction:

Figure 8.2. Database Creation Script
...
  function samplenote__new
  ...
        PERFORM acs_permission__grant_permission(
          v_samplenote_id,
          >>>>p_owner_id,<<<<
          ''admin''
    );
  ...
...

<blockquote>>>>p_owner_id<<<< should be p_creation_user?
</blockquote>

Randy

Collapse
Posted by Randy O'Meara on
Another correction:

in note-delete.tcl:

set title "Delete Note"

if {[exists_and_not_null >>>>confirm<<<<]} {
    # if confirmed, call the database to delete the record
    db_1row do_delete { *SQL* }
...

<blockquote>>>>confirm<<<< should be confirm_p
</blockquote>

In addition, I see a complaint in the log when this first portion of the conditional is invoked (after the confirmation dialog) indicating that form "note-del-confirm" is not defined. This makes sense in that the adp file is referencing this form and it really hasn't been defined by the tcl file. How is this normally handled?

Randy

Collapse
Posted by Randy O'Meara on
The answer to my previous question is, of course, to add "ad_script_abort" just after the note is deleted. So, this call should be added to your example.

Randy

Collapse
Posted by Gabriel Ricard on
I'm getting this error when loading the data into postgresql:

psql:samplenote-functions-create.sql:22: ERROR:  Attribute 'samplenote__new' not found

any ideas?

Collapse
Posted by Joel Aufrecht on
The error in line twenty-two is because samplenote__new is a string to be passed in, not a function to be called, and so needs to be in single quotes:
select define_function_args('samplenote__new','note_id,title,creation_date,creation_user,creation_ip,context_id'); 

Question for people: I omitted the object type, both in the __new function and in the wrapper for the __new function. My reason is that the object type is constant for the function samplenote__new. So there's no reason for it ever to be passed in, so I'll just hard-code it into the plpgsql. Is this okay or did I miss something?

Collapse
Posted by Gabriel Ricard on
In the advanced section there's a bit about adding comments to the notes themselves. This part of the document references certain notes scripts that weren't mentioned (notes.tcl, notes.adp, notes.xql) in the rest of the tutorial. I managed to create the scripts myself, and modify the index scripts to link the title of the notes to the view page. I can post those scripts if you want to include/modify them.

After I added the links to comments though, I could no longer delete the notes due to a foreign key reference (my guess is the comments linked to the note required the note to exist...). Anyways, the constraint that postgresql complained about was acs_obj_context_idx_anc_id_fk. If you want I can post the full error message.

Collapse
Posted by tammy m on
On the Creating Web Pages part of the tutorial, when I get to the section to create the note-edit.adp:

[service0@yourserver www]$ emacs note-edit.adp

<master>
<property name="title">@title@</property>
<property name="context">{@title@}</property>
<formtemplate id="note"></formtemplate>

The property tags are passed to the master template, which uses their values to set the page title and context bar (breadcrumb trail). We use the same variable, title, for both variables but wrap it in curly brackets for context so that the spaces aren't interpreted separators. The formtemplate tag outputs the form html with the matching name.
If I leave the context with the {} around it, they show up on the final displayed page, with the title in actual brackets. If I remove the brackets, the title shows up on the final page just fine. Are these brackets really needed and if so, is there an option to not have them displayed on the final HTML page that gets displayed to the end user's browser?
Collapse
Posted by tammy m on
One more note, on the same page I mentioned before Creating Web Pages where it says Go to the APM as before and scan for new files and add your new work. Then test all this by going to the package home page and adding and editing a few records. I had to restart my aolserver for this to work, otherwise I got a db error stating that the sql for do _insert could not be found, even after I added the new files via the APM.
Collapse
Posted by Peter Marklund on
Tammy,
you no longer need to (as of 4.6.2) add files to a package, the APM finds them automatically. A better alternative to restarting the server after you've added files is to click on "watch all files" next to the package in the APM UI.