Forum OpenACS Development: Relative Links Work (maybe)

Collapse
Posted by Ola Hansson on
I have come up with a solution to make relative linking work, but it is a kludge and it may have problems with scalability.

I modified the fs_mount_point/download/index.vuh so that it supports retreiving live revisions from a virtual url which is put together by the file's folder path and the filename like this:

http://example.com/fs_mount_point/download/folder-a/folder-aa/filename.html

The index.vuh still supports the old "?version_id=blah" style of retreiving content because in the "view details" page, where all the revisions of a file are listed, it's the only way I know of that you can retrieve a non-live revision. Pages retreived this way won't support relative linking of course (better suggestions are welcome) ... (BTW, there doesn't seem to be any way to set which version should be live - we should fix this sometime)

If the code below looks about right - and these are the main changes - I can try to make it work on Oracle, too, and produce upgrade scripts. What do you think?

download/index.vuh:


# packages/file-storage/www/download/index.vuh

ad_page_contract {

    Virtual URL handler for file downloads

    @author Kevin Scaldeferri (kevin@arsdigita.com)
    @author Don Baccus (simplified it by using cr utility)
    @author ola@polyxena.net (resolution of live revision from virtual url)
    @creation-date 18 December 2000
    @cvs-id $Id: index.vuh,v 1.3 2001/10/31 20:42:07 donb Exp $
} {
    version_id:optional
}

if { ![info exists version_id] } {

    set extra_url [ad_conn extra_url]
    set virtual_url [string range $extra_url [expr [string first / $extra_url] + 1] end]

    set folder_path [string range $virtual_url 0 [expr [string last / $virtual_url] - 1]] 
    set filename [string range $virtual_url [expr [string last / $virtual_url] + 1] end]

    set package_id [ad_conn package_id]
    set version_id [db_exec_plsql get_live_revision_from_url {
	select fs_get_live_revision_from_url(:package_id, :folder_path, :filename);
}]

    if { [empty_string_p $version_id] } {
	ns_returnnotfound
    }

}


ad_require_permission $version_id "read"

cr_write_content -revision_id $version_id

/packages/file-storage/sql/postgresql/file-storage-package-create.sql - new function:

create or replace function fs_get_live_revision_from_url (integer, varchar, varchar) returns integer as '
declare
	p_package_id 		alias for $1;
	p_folder_path 		alias for $2;
	p_filename 		alias for $3;
	v_folder_id 		cr_folders.folder_id%TYPE;
        v_folder_seq 		integer default 1;
	v_folder 		varchar;
	v_live_revision 	integer;
begin

  v_folder_id := file_storage__get_root_folder (p_package_id);

  v_folder = split(p_folder_path, ''/'', v_folder_seq);
  while v_folder is not null loop
    
	select folder_id into v_folder_id
	from   fs_folders
	where  parent_id = v_folder_id
	and    name = v_folder;

	v_folder_seq := v_folder_seq + 1;	
	v_folder = split(p_folder_path, ''/'', v_folder_seq);

  end loop;

  select live_revision into v_live_revision
  from   cr_items 
  where  parent_id = v_folder_id 
  and name = p_filename;

  return v_live_revision;

end;' language 'plpgsql';


I told you it was a kludge! 😊

If it can be used, though, could the function be cached with "iscachable"?

/Ola