Tags:
create new tag
, view all tags
Proposal: Have CommonFrontEndCgiScript cover the functionality of all the CgiScripts plus the CGI part of TWikiDotPm. This includes the script to handle Plugins, as described in PluginBinNameClashes.

So, this would move from the current system off:

  • /bin/CgiScript/WebName/TopicName
To:
  • /bin/CommonFrontEndCgiScript/TWikiVerb/WebName/TopicName

Where TWikiVerb is one of view, preview, save, upload, etc. Candidates for TWikiVerbs would be as listed in CgiScripts.

Using a CommonFrontEndCgiScript we would lose being able to use the WebServer to enforce different restrictions on each CgiScript but I can't see this being a problem as long as the permissioning was enforced lower down in the stack. (And one could argue that permissions should be a function of the backend not the frontend, especially if we want WebServices do also be subject to such permission checking).

Alternate scheme would be to go OO, defaulting to view and making the verb optional:

  • /bin/CommonFrontEndCgiScript/WebName/TopicName/TWikiVerb/

This has the advantage of being able expose the urls like this, hence implementing a scheme similar to that wanted in RenameViewToAview:

  • http://SiteName/WebName/TopicName/TWikiVerb.

-- MartinCleaver - 02 Jul 2002

Interesting idea. I see some issues though:

  • The script is fat, e.g. all Perl modules are loaded regardless of the need.
    • Four things: firstly they don't have to be; we can dynamically load the modules at the time they are required. Secondly, the people who have a need for speed are typically those who load ModPerl. Thirdly, TWiki spends the vast majority of its time in view anyway and that loads everything. Fourthly, I think I should change my use of language: I meant fat as in TwoTier (func/view combined, with data separate). MC.
  • Can't use basic authentication to authenticate just edit but not view. That means, either authenticate users all the time or never. This could be solved with a non-authenticated view script that calls the fat script...
    • Comment below. MC

A better approach is to modularize the scripts, e.g. view gets split up into a skeleton view and a View.pm. Doing so gives us the flexibility of authentication for the scripts, and allows us to offer a WebServices interface like Web/Topic/verb/attributes to interact with the content programmatically.

  • I agree. Let's discuss this. MC. (see below)

-- PeterThoeny - 02 Jul 2002

I think it would be worth having a script like this that could be utilised by Plugins (rather than them adding to bin) and possibly in the future for some of the less used TWiki scripts. I would go for two scripts, one that will have authenication like the edit script and one that is equivalent to the view script.

-- JohnTalintyre - 02 Jul 2002

Would it be possible to have just two: a main script plus an authenticate script? I'm thinking that the main script could handle everything and redirect to authenticate for the moments that it needed to, then back to the main script.

-- MartinCleaver - 05 Jul 2002

I'm suggesting try out the idea of more general purpose scripts for new areas e.g. plugins requiring bin. Note that the reason for having a separate authenication script is so that the Web server e.g. Apache can do the authentication work.

I can't see the point in rederecting to an authenicate script if you know in advance (e.g. because a link is an edit link) that you'd have to do this.

-- JohnTalintyre - 05 Jul 2002

Thought I'd throw in a vote for MC's first example: In the case where we end up with a single script for all TWiki activities (verbs), I'd like to see the URL as the path to the script followed by the verb, followed by the path to the topic, followed by CGI arguments to the verb.

Also, in the case of HierarchicallyNestedTwikiWebs the web name may consist of several directory levels, which leads me to believe it'd be difficult to append any actions or verbs onto the end of the URL without using standard CGI-type argument formatting. The format I'd like to see is this:

  • [ url base ] [ verb ] [ web path ] [ topic ] [ CGI or form arguments ]

Example:

  • http://twiki.org/cgi-bin/twiki/view/Codev/Subweb/Subsubweb/CommonFrontEndCgiScript?raw=on&another=argument

Another way to achieve single script-dom and reduce the URL to the current format ( http://twiki.org/cgi-bin/verb/Path/To/Topic ) would be to make each verb a symbolic link to the main script in the CGI directory, and apply authentication to symbolic links as required. The main script could determine what verb was being requested by extracting the verb name from the URL, or the an environment variable containing the requested script name.

I'm also in favor of "dynamic loading" of verb support modules at run time, to reduce total load time for those not using ModPerl. Perl provides Autoload functionality specifically for this purpose, which prevents code from being loaded until it has been requested by the program.

-- PeterNixon - 07 Jul 2002

How about this: standardise that a webpath be specified as Web.SubWeb.SubSubWeb? This would allow the form:

  • /bin/CommonFrontEndCgiScript/WebPath/TopicName/TWikiAction/
ie. URLs could look like:
http://twiki.org/WebPath1.WebPath2.WebPath3/TopicName/ for view
http://twiki.org/WebPath1.WebPath2.WebPath3/TopicName/view for view
http://twiki.org/WebPath1.WebPath2.WebPath3/TopicName/ TWikiAction for arbitrary actions

$.02: I like the above, especially the "." as the web | subweb delimiter, and the general shortness. With respect to the first variation, is the trailing "/" required? -- RandyKramer - 08 Jul 2002

  • My $0.02 (myself, and my devil's advocate):
    • At the moment, I prefer the "/" as the web/subweb delimiter, because
      1. it currently represents the directory path of the storage for each web (subwebs are directories in their parent webs). I may not care as much once we make the data storage backend more generic, but for now, it makes more sense as "/" to the affected code and templates.
      2. In the current implementation of TWiki, the delimiter between topic and web in the URL is "/", while in the topic text Wiki notation the delimiter is ".". If we continue to use "/" as the delimiter between the elements of the web path and topic (e.g. Path/To/TopicName ) in the URL, and continue to use dots rather than slashes in the topic text's wiki notation (e.g. Path.To.TopicName ), we would remain true and consistent to the current implementation.
      3. You could also say that people worked a long time on UNIX and MSDOS (shudder) to come up with a delimiter for directory or folder names, so "/" just seems more natural to most people who think of topics as documents in a folder wink .
    • However, if the consensus is still to go with dots (".") in the URL path, I'd prefer that we use it everwhere, including the delimiter between the web name and the topic name (e.g. http://cgi-bin/twiki/action/Path.To.Web.TopicName ). The only reason I could imagine using dots as a delimiter in the URL would be to be consistent with wiki notation in the topic text (see comment #2 above). In MegaTWiki's Wiki Notation, dots and slashes are interchangable for hierarchical web paths in the topic text (to accomodate the way the %WEB% variable is used by the plugins and templates).
    • I also prefer the TWikiAction to be at the front (before the WebPath), because when I think about what I want to do, I usually my verbs before my nouns (e.g. I want to view the WebPath1/WebPath2/WebPath3/TopicName topic, optionally in raw=on mode. Blame my sisters, they were both english majors (and they gave me a load of trouble wink ). Actually, the real reason I'd have a problem with the action being at the end is that currently the topic name is already optional. I can understand why you'd want it at the end, for those who get the urge to backspace over the view action and turn it into edit in the browser's URL textbox, but there are (or should be) links for that on the page.

      -- PeterNixon - 08 Jul 2002

In fact, you could have a special case of:

http://twiki.org/TopicName for a BookView search of all public webs for that topic name

$.02: Why BookView? If some prefer BookView, why not make it a user preference? In fact, maybe the user preference should have three options, page name (topic) only, page name and summary, or BookView. -- RandyKramer - 08 Jul 2002

I'd prefer this as it keeps separate and predictable the delimiters used for parameters passed to the scripts.

Also, I now believe that where I used the term verb we should use the term action as I think that verb is best reserved for when we enrichen TWiki's linguistic capabilities.

Plugins actions

With regards to plugins, I think the above mechanism is easily extended so that TWikiActions that start with a lower case are reserved for internal use and that TWikiActions that start with an upper case name first the Plugin and then the action inside that plugin. Hence:

http://twiki.org/WebPath1.WebPath2/TopicName/QuickSavePlugin/quicksave?quickSaveParams for a much needed standard Quicksave functionality

This would then necessitate a new standard plugin method, called action and the eliminatation all CgiScripts currently added by Plugins and skins.

where:

$twikiAction quicksave
$params quickSaveParams

Separate authenticate script

With regard to John's point (he said: I can't see the point in rederecting to an authenicate script if you know in advance (e.g. because a link is an edit link) that you'd have to do this.):

  • Am I correct in thinking that you only need to authenticate once per session? If so, doesn't this mean that you don't always need to authenticate when editing? I prefer them separate because this means we can centralise all action calls.

Separatation of CgiScripts into script + module

PeterThoeny said: A better approach is to modularize the scripts, e.g. view gets split up into a skeleton view and a View.pm. Doing so gives us the flexibility of authentication for the scripts, and allows us to offer a WebServices interface like Web/Topic/verb/attributes to interact with the content programmatically.

Okay, well I question what goes in the CgiScript verses the DotPm file and whether the division of the backend modules is necessarily best served by taking the same divisions as used by the CgiScripts so far.

Let's look at the CgiScript vs DotPm file first:

I did an analysis of the first few existing CgiScripts. I conclude that the CommonFrontEndCgiScript should be responsible for:

  1. extract parameter variables from the CgiEnvironment (i.e. work out action, user, web and topic)
  2. display the skin
    • Should this read - set the skin variable? -- JT
      • No. Showing the skin is a responsibility of the render layer, in the same way DispatchDotPm would return WikiML and the CgiScript would transform this to HTML.
  3. dispatch the request to a Dispatch.pm which returns (statusCode + content in WikiML)
  4. call the RenderingPipeline to transform the WikiML into HTML

The backend could consist of a primary DispatchDotPm file plus a primary ActionDotPm. The DispatchDotPm file should have a primary flow of:

  1. see if action exists (this would require a Plugin::enquireAction), complain if not.
  2. ensure that user has permission to perform action (cause an exception if the user is not validated)
  3. log the start of the action being started (optional)
  4. call Actions::dispatch(action, user, webpath, topic) or Plugin::dispatch(....) if starts with a capital
    1. these methods return (statusCode, contentInWikiML)
  5. log the end of the action being run
  6. return statusCode, contentInWikiML

This DispatchDotPm can then be called from SubmitTopicByEmail or from WebServices and the WikiML can be rendered or not into the appropriate form for display.

As I say, I haven't examined all the scripts, so I am bound to be missing subtleties. (view raw, springs to mind). What I want to know is whether this could be workable.

Now, the question of how the backend modules should be divided

The most obvious way is to have a one-to-one correspondance for each of the existing CgiScripts, saving them as Actions::View Actions::Edit Actions::Preview, etc. I think there is nothing intrinsically wrong with that.

I question whether there would be advantage in combining the distinct workflows into common backends, hence we would end up with DotPms for each of:

I know that there is some state handling shared between the existing scripts, eg. edit/cancel/view causes locks to be discarded.

Comments welcome.

-- MartinCleaver - 08 Jul 2002

First, it was stated above:

  • Am I correct in thinking that you only need to authenticate once per session? If so, doesn't this mean that you don't always need to authenticate when editing? I prefer them separate because this means we can centralise all action calls.

This is not the full story. Some sites use sessions (via cookies) - TWiki does not (allow the SessionPlugin does make this an option). So if you are using basic authenication the browser sends the login details on every call to the site. So far as I know, only the scripts set up to recieve this login information will do so.

  • My thought would be that the common script would read any login details provided but if they weren't provided then it would redirect such that next time the common script was invoked they would be. I'm admittantly not sufficiently aware of what the code does to judge more than that.

My suggestion is lets not go too far too quickly. People usually provide code for TWiki when there is a specific advantage for the change - code can be improved as this is done. So why don't we first focus on removing the need for Plugins to add scripts to the bin directory. If this works, then we could consider extending it to the Twiki core.

  • Great idea, that's fine with me.

If we go this route some of the things we need to do are:

  • Decide if plugins receive all bin invocations or just those they register for.
    • I was thinking that plugin to be called would be explicit stated in the URL. Hence, rewriting my above scheme to allow for the action mechanism to co-exist with the current conventions:
http://twiki.org/cgi-bin/action/WebPath1.WebPath2/TopicName/QuickSavePlugin/quicksave?param1=value1&param2=value2
    • If the QuickSavePlugin didn't implement the quicksave action it should return a an error statusCode and some WikiML to that effect. -- MC
  • Decide on the parameters to pass to the plugins
    • I was thinking that to be extensible, they would get passed a hash of name-value pairs of all parameters passed explictly plus the standard User, WebPath & Topic. Again, TWiki reserved values would start lower case and plugin supplied ones with an initial capital letter. * Example of %params hash passed to Plugin::action($action, %params):
Name Value
user user
web webPath
topic topic
Param1 value1
Param2 value2
-- MC
  • Decide on standard so this can work for cgi and other access. For now cron type, but could include WebServices etc in the future.
    • I don't understand, can you please elaborate? -- MC
  • Decide on naming convention - I'd suggestion using the Plugin name, by adding to the Plugins web you would be registering this name for use.
    • I agee. -- MC

-- JohnTalintyre - 08 Jul 2002

See my note above about the web path delimiter, and placement of the TWikiAction in the URL (better read in context wink ). I'm still catching up.. I'll comment on the rest after I digest a bit.

-- PeterNixon - 08 Jul 2002

After a little more time to digest *burp* (pardon me!) I have a bit more input:

I thought a bit more about where the TWikiAction should go in the URL:

  • It seems to me that the action should be an argument, rather than part of the URL path (e.g. http://twiki.org/cgi-bin/twiki/Path/To/TopicName?request=edit).
  • We should also call the TWikiAction a request rather than an action or verb, because the browser is making a web service request of TWiki. I'd like to reserve verb for when we're talking about TWikiOO's nouns and verbs (objects and methods).
  • The default request would be view, which reduces the URL nicely.
    • I'm personally happy with all of this. Watch how you use the term 'web service' though - you say it as if WebServices means to make a HTTP request for a web page; WebServices is about providing programmatic access to services over the web. They are very different. -- MC
      • Well, I guess I could have said because the browser or web service client ... there; Both interactive (browser) and programmatic modes use the same method of access (via the web, using HTTP) to get to a service that the site provides via CGI, so I tend to lump them in the same category. -- PeterNixon - 10 Jul 2002

As far as the authentication issue is concerned, we could provide an AuthenticationModule (LDAP, .htpasswd-style, and other types of authentication) which uses cookies, redirection to/from an authentication request, and allows for piecemeal authentication. If the administrator desires wholesale authentication, they may use the web server's authentication facilities instead. It shouldn't be all that hard to write. I will start an investigation.

Performance related to loading of modules: Someone made the comment that if we have a CommonFrontEndCgiScript, it would actually make it fatter (even though there are only a few lines of code in the main:: package), because it must load all the support libraries and services. This is true. However, it is possible to delay compilation of un-needed code until it is requested by the program by applying the SelfLoader.pm module to each of TWiki's perl modules. Although all the code is being read in, it is not all compiled until it is required, resulting in significant reduction in overall startup time.

Parameters for plugins... Hmmm.. My first thought would be to make the CGI query object avaialble to all perl modules, so they can digest the parameters themselves using a common piece of code. No need to pass multiple arguments. KISS is the rule for me. If other parameters are required, however, I agree with MC on this: they should be passed in as a hash in order to absolve the requestor of having to know the order in which the method arguments should be placed. It's just good interface design.

  • On the contrary, I think the CGI object must not be known about by the time you get down to a plugin; CGI is only one of a variety of access routes that could used to invoke TWiki; Command Line, via mail-in and through WebServices are others. Best to have a parameter set, a la hash, that can be passed. -- MC
    • True, I was a little focused on the http-based access there. I prefer hashes anyway, so I think we're aligned. Just a note, we probably should not inherit from CGI in TWikiOO's main TWiki object in order to support non-interactive, non-http-based access methods. -- PeterNixon - 10 Jul 2002

Plugins also provide services which may be requested. Each service that can be requested via URL parameters should be registered with the plugin manager module using a registration method call. I have implemented something similar in MegaTWiki. All rendering-related services should also be registered in a similar manner. I still have not decide how to tell the plugin manager whether the plugin module is there or should be used to begin with.

I understand folks are excited about this, but we're starting to get into some sticky TWikiOO implementation issues here; I'd like this work to be applicable toward TWikiOO, if possible. Would it be useful to do a little OO UML-ish type analysis? I would suggest defining the major nouns in the system (e.g. User, Topic, Skin, Template, Attachment, Service, etc.), and then defining the verbs that will be applied to them (authenticate, lookup, get, render, display, save, rename, etc.). It might clear up the picture a bit.

  • I'd prefer we avoide the terms nouns and verbs; objects and methods are more appropriate and we will need the terms nouns and verbs later when we push up TWiki's semantic richness. -- MC
    • I was just thinking along the lines of defining the things in the system, and what's going to be done to/with them, but I guess I was mixing my diagrams a bit. We should really be developing use cases (with actors and use case relationships), and then start defining the objects and their relationships and methods, a la UML. It might be good to reverse engineer the current implementation into use cases, which we could then re-engineer into objects, methods and interfaces. We might want to move this part of the discussion back to TWikiOO. -- PeterNixon - 10 Jul 2002

I also enjoy bangin' out new perl code, but we're beginning to throw around module names and module structure a little too soon. We need to define some transactions that will clarify the work which needs to be done. Once we have a clearer picture of what's really going on, we can start worrying about implementation of interfaces and objects.

  • Indeed. I think this is entirely necessary. Maybe CharleyQuinton would like to help in this effort? -- MC

-- PeterNixon - 09 Jul 2002

Comments interspersed. MC.

-- MartinCleaver - 10 Jul 2002

More comments interspersed smile

-- PeterNixon - 10 Jul 2002

There is flexible framework to build CGI applications, called ... CGI::Application, CPAN:CGI::Application (see here for more links). Fully OO (AFAICT wink ), has also default runmode (for action=view) and could be a good base for TWikiOO.

Just a thought to keep this important, forgotten page alive.

-- PeterMasiar - 16 Jun 2003

And another perspective: in my opinion:

  1. Everything should be designed by assuming the server runs mod_perl or something like it. If it doesn't, then performance issues are moot.
    Thus there is not problem loading everything for each operation, as this is not cost (there is cost however to initialize things).
  2. The number of scripts may be more governed by www issues: authentication (e.g. view / viewauth), and indexing by Search Engines (some things must be indexed by search engines). Thus we could have 4 scripts, all being the same (symlinks or copies):
    • view
    • viewauth
    • viewnoindex
    • viewauthnoindex
-- ColasNahaboo - 17 Jun 2003

I agree with Colas 100% on the search engine issues (we should try to have only one version of a page crawled, not the print page, and view page (and skinned pages ??), ..., and we should avoid having pages with dynamic searches indexed (WebIndex, WebChanges, pages with a formatted search, etc.)

I agree in principle with the mod-perl comment (will agree completely when I learn how to get mod-perl working ;-).

-- RandyKramer - 17 Jun 2003

Whilst it would be nice not to worry about performance outside mod_perl, I suspect this is not how many users of TWiki see it.

-- JohnTalintyre - 17 Jun 2003

I have mod_perl on one of my twiki installations and the performance sucks. However, it sucks less than it does without mod_perl. Anything which improves the performance is good by my perspective.

-- MattWilkie - 17 Jun 2003

To John: On my first 2 TWiki installs I was not authorized to run mod_perl (no root access). I used speedy with good success, a standalone CGI program you can install in user mode.

-- ColasNahaboo - 20 Jun 2003

More on CPAN:CGI::Application http://perlmonks.thepen.com/202938.html

-- MartinCleaver - 13 Jan 2005

$ svn commit bin/twiki -m  "CommonFrontEndCgiScript: could eliminate all bin scripts and provide plugins bin architecture"
Adding         bin/twiki
Transmitting file data .
Committed revision 3486.

-- MartinCleaver - 14 Jan 2005

The twiki script would not be authenticated. Instead any UI delegate that needs authentication should call the special 'twikiauth' script with both a return path of how to hop back into the session and all the parameters needed to restore state.

Example: a page view ("twiki/view") is handled by a script called 'twiki' that determines the action is called 'view' and thus calls the 'TWiki::UI::View::cgi' method. This can be extended to plugins.

-- MartinCleaver - 20 Jan 2005

I just submitted the following as bin/twiki. It is designed to be duplicated as bin/twikiauth permitting all the other cgi-scripts (except testenv) in bin to be deleted.

  • permissioning in .htaccess becomes then just an entry, for twikiauth.
  • scripturlpath becomes this script, instead of the bin directory.

# /cgi-bin : cgi-bin URL path for TWiki: $scriptUrlPath = "/twiki/bin/twiki";

The code is pasted here only for discussion. I got lambasted on #twiki for it not being a solution for everything, (in particular old URLs), but its in line with what was discussed above so I think it has merits.

It generally works for me for GET requests. POST requests (e.g. for bin/twiki/save) don't work: they are currently redirected as GETS to bin/twikiauth/save; http://ppewww.ph.gla.ac.uk/~flavell/www/post-redirect.html#sum has some solutions to that and another was mentioned on TWikiIRC.

Like Lynnwood I'm interested paring down an install to the minimum needed for SharingInstallFilesBetweenSites. Reducing the BinDirectory chaff is a subgoal towards complexity minimisation.

Existing bin scripts could be supported too, its just a case of mapping the 'op not found' scenarios. I'd especially welcome suggestions about what to do about legacy URLs, e.g. http://twiki.org/cgi-bin/view/Web/Topic instead of http://twiki.org/Web/Topic, not for my sake (ShorterURLs work for me) but for those who can't implement that.

The code probably won't stay here for long, and will probably be out of date WRT subversion by the time you read it. In the meantime...

#!/usr/bin/perl -wT
#use strict;
my $debuganon = 0;
my $debugauth = 0;
use CGI::Carp qw(fatalsToBrowser);
#
# TWiki Collaboration Platform, http://TWiki.org/
# http://twiki.org/cgi-bin/view/Codev/CommonFrontEndCgiScript
# (c) Martin at Cleaver.org 2005
#
# For licensing info read license.txt file in the TWiki root.
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details, published at
# http://www.gnu.org/copyleft/gpl.html

=pod
Examination of a TWikiRoot/bin/ finds that the files are practically identical.

This script goes one step further: it replaces the whole of the bin
directory with a single CommonFrontEndCgiScript. It checks PATH_INFO,
extracts the op, (e.g. op=view) and rewrites PATH_INFO without the
op. (op was named verb in my original proposal). It then looks up
the op using the table below to work out which TWiki::UI:: method to call,
and delegates control, going via twikiauth if needauth=1.

This implementation eliminates all the bin scripts: the URL changes from
    * bin/view to bin/twiki/view and
    * bin/edit to bin/twiki/edit . if needauth = 1 and REMOTE_USER = "" this redirects to:
       * bin/edit to bin/twikiauth/edit

This leads the way for a general method for e.g. plugins requiring bin
I suspect that I've just reimplemented the core of CGI::Application, but
we'll see.

I have not yet considered what to do about setlib.cfg, etc.

=cut


BEGIN {
    # Set default current working directory (needed for mod_perl)
    if( $ENV{"SCRIPT_FILENAME"} && $ENV{"SCRIPT_FILENAME"} =~ /^(.+)\/[^\/]+$/ )
 {
        chdir $1;
    }
    # Set library paths in @INC, at compile time
    unshift @INC, '.';
    require 'setlib.cfg';

    # 'Use locale' for internationalisation of Perl regexes -
    # main locale settings are done in TWiki::setupLocale
    # Do a dynamic 'use locale' for this module
    if( $TWiki::useLocale ) {
        require locale;
        import locale ();
    }
}
use TWiki::UI;

my %ops = (
             'attach' => [ "TWiki::UI::Upload", "attach", 1 ],
             'changes' => [ "TWiki::UI::Changes", "changes", 0 ],
             'edit' => [ "TWiki::UI::Edit", "edit", 1 ],
             'manage' => [ "TWiki::UI::Manage", "manage", 1 ],
             'oops' => [ "TWiki::UI::Oops", "oops_cgi", 0 ],
             'passwd' => [ "TWiki::UI::Register", "passwd_cgi", 0 ],
             'preview' => [ "TWiki::UI::Preview", "preview", 0 ],
             'rdiff' => [ "TWiki::UI::RDiff", "diff", 0 ],
             'register' => [ "TWiki::UI::Register", "register_cgi", 0 ],
             'rename' => [ "TWiki::UI::Manage", "rename", 1 ],
             'resetpasswd' => [ "TWiki::UI::Register", "resetPassword", 0 ],
             'save' => [ "TWiki::UI::Save", "save", 1 ],
             'search' => [ "TWiki::UI::Search", "search", 0 ],
             'statistics' => [ "TWiki::UI::Statistics", "statistics", 0 ],
             'upload' => [ "TWiki::UI::Upload", "upload", 1 ],
             'view' => [ "TWiki::UI::View", "view", 0 ],
             'viewfile' => [ "TWiki::UI::View", "viewfile", 1 ]
           );

my $op;
my $originalpathinfo = $ENV{PATH_INFO};
($ENV{PATH_INFO}, $op) = take_op($ENV{PATH_INFO});
my ($lib, $entrypoint, $needauth) = find_op($op);

my $script = $ENV{SCRIPT_URI};
my $inauth = $script =~ m!bin/twikiauth!;
my $debug = $inauth ? $debugauth : $debuganon;
my $remoteuser = $ENV{REMOTE_USER};

print "Content-type: text/html\n\n" if $debug;
if ($entrypoint eq "") {
    html_error();
} else {
    html_diagnose($op, $lib, $entrypoint, $needauth, %ENV) if $debug;
    print "<LI>needauth = $needauth; inauth = $inauth; remoteuser = $remoteuser\
n" if $debug;

    if ($needauth) {
        if (!$inauth) {
            if (!defined($remoteuser)) {
                print "<LI>remoteuser: ".$remoteuser if $debug;
                my $authscript = $script;
                $authscript =~ s!bin/twiki/!bin/twikiauth/!;
                print "<h2>Redirecting to $authscript</h2>\n" if $debug;
                use CGI;
                my $query = new CGI;
                print $query->redirect($authscript);
                exit 0;
            }
        }
    }

    {
        no strict 'subs';
        eval "TWiki::UI::run(\'$lib\', \'$entrypoint\')"; # unless $debug;
    };
    if ($@) {
        die "couldn't run ${lib}::${entrypoint} $debug\n\t$@";
    }
}

=pod
Currently this only takes the hardcoded table of inbuilt TWikiOps.
However, there is nothing to stop us adding a syntax:
    /view => ...
    /plugins => delegate according to some table
    /bunch-of-legacy-files

Now we just need to determine how to carve out the ops namespace.
=cut
sub find_op {
    my $op = shift;
    my $ref = $ops{$op};
    my ($lib, $entrypoint, $needauth) = @$ref;
    print "A: $lib, $entrypoint, $needauth\n" if $debug;
    return ($lib, $entrypoint, $needauth);
}

sub take_op {
    my $path = shift;
    $path =~ m!/(.*?)/.*!;
    my $op = $1;
    $path =~ s!/$op!!;
    #$op =~ s!/.*?!!;
    #print "P: ".$path."\n";
    #print "O: $op\n";
    return ($path, $op);
}

sub html_error {
    print "<html><head><title>TWiki</title></head>\n";
    print "<body>\n";
    print "<h1>".$op." is not valid</h1>\n";
    print "<LI>".show_ops("\n<LI>");
    print "</body></html>\n";
}

sub html_diagnose {
    my ($op, $lib, $entrypoint, $needauth, %ENV) = @_;

    print "<H1> For '$op'- running ${lib}::${entrypoint}</H1>";
    print "<h2>".join("\n<LI>",@INC)."</h2>";
    print "<h2>auth=$needauth</h2>\n";
    foreach my $key (sort keys %ENV) {
        print "<LI> $key = $ENV{$key}\n";
    }
}

sub show_ops {
    my ($delim) = @_;
    for my $key (sort keys %ops) {
        print $delim, $key;
    }
}

-- MartinCleaver - 21 Jan 2005

As I mentioned in the ShorterURLs topic, the TWikiVerb should be assumed to be "view" if it is absent. Placing it in every URL is like a clerk at McDonalds asking you if you want meat on your hamburger--of course you do! If you didn't, you'd be sure to let him/her know.

Here is a notation I like:

This is also consistent with other wiki applications such as Media Wiki.

-- KevinCraft - 29 Jun 2006

Edit | Attach | Watch | Print version | History: r32 < r31 < r30 < r29 < r28 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r32 - 2008-09-14 - TWikiJanitor
 
  • Learn about TWiki  
  • Download TWiki
This site is powered by the TWiki collaboration platform Powered by Perl Hosted by OICcam.com Ideas, requests, problems regarding TWiki? Send feedback. Ask community in the support forum.
Copyright © 1999-2017 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.