Re: [cgiapp] mod_perl + CAP::AutoRunmode not working
Hi Giannis, Just moved a C::A under mod_perl 2 and CAP::AutoRunmode is not working. Runmodes defined by CAP::AutoRunmode are not recognized. The runmodes can not be found / seem not registered. In plain cgi and persistentperl runmodes are ok. I hope to have fixed this issue in the 0.14 release of CAP::AutoRunmode. http://search.cpan.org/~thilo/CGI-Application-Plugin-AutoRunmode-0.14/ Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] CAP::AutoRunmode::FileDelegate
All runmodes including start rm into ./runmodes folder: Error executing class callback in prerun stage: could not evaluate runmode in file ./runmodes/start.pl: Bad file descriptor at C:/usr/local/site/lib/CGI/Application/Plugin/AutoRunmode.pm line 220. I have seen that error message when the runmode file had syntax errors, but you say they pass perl -cw. Could you send me start.pl ? Start runmode in main app module and all the rest in ./runmodes folder: Error executing class callback in prerun stage: Insecure dependency in require while running with -T switch at C:/usr/local/site/lib/CGI/Application/Plugin/AutoRunmode/FileDelegate.pm line 21. Ouch. Taint checking will break the run-time evaluation the module does. I have to think about how to solve that (but there is no good way to untaint the file, as it can obviously contain anything). Though I cannot reproduce it at the moment, the error message seemed to depend whether I called $self as '$self = shift' or '$self = @_' - I've never seen $self called by the latter expression before, though it shows that for setup() in the documentation. $self = @_; is bogus. It has to be $self = shift; or ($self) = @_; (with brackets). I could not find that particular typo in the module documentation. A broken $self could well explain the error message. Also the method themselves seem to require 'my ($app, $delegate) = @_', though $delegate isn't used again anywhere. the $delegate is optional. my ($app) = @_; my ($app, $delegate) = @_; my ($self) = @_; should all work. Sorry for all the trouble you are having, I hope you give it another try before switching to a more fully thought-out server page system like Mason ;-) Thilo
Re: [cgiapp] ideas for limiting delegates in the AutoRunmode plugin
Hi Mark, I'd like to discuss possibilities to make this more flexible. Right now it considers every method in a delegate class to be a run mode. I would like a way to mark only some of the methods for use. Hmm. My concept for the module was that a delegate is a class that only contains runmodes. So the way to mark methods as run-modes is to group them in a package and use that package as a delegate. Anything that is not a runmode must not be in that package. I would like to stick with this approach as it is very clear-cut and easy to understand. Introducing more complexity also increases the potential for usage errors that can lead to unintentional runmodes. 1. Respect the :Runmode attribute on these run modes. I'm not sure if that would work. If you want that, you can just declare :Runmode in the original CGI::App. If you want to re-use them in more then one application, you can declare them :Runmode in a shared package and export them (I think that would work, though I have not tried it). Thilo
Re: [cgiapp] CGI::Application performance alternatives
I have not used Persistent Perl, but FastCGI is quite stable in my experience. Can it cache DB connections, or is a connection made per request? Except for not being able to access Apache internals, PPerl and FastCGI should not be much different than mod_perl in this respect. You can cache anything that you want by stuffing it into a global variable. I think you can even use Apache::DBI, if you want. This could be another advantage of using FastCGI/PPerl: You need only one DB connection per perl process, not one per Apache process, which might free some resources on the DB server. Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] A question on cgiapp_init
Hi, Does this cgiapp_init get called for each run mode. I put a database query into this and the resultant strings were put into params. This slowed down the entire application. Every stage in CGI::App is executed for every request: 1) create the $app instance 2) run setup, init, prerun, the runmode, teardown You can think of CGI::App as a HTTP request controller that dispatches to a certain runmode. There is no application-level setup phase, that would be executed only once (before the first request). Such a phase has no meaning in traditional CGI, but is of course very useful in FastCGI or mod_perl. If you want such a phase, (for example to read config files, or query the database for some initial settings) you have to use other mechanisms in addition to what CGI::App supplies. Singleton objects that initialize themselves upon first request and then maintain their state as package globals are an option here. Again, this is not within the scope of CGI::Application. Hope that helps, Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] RFD: Developer mailing list?
Exactly my point. This list /is/ a developers list, and newbies are welcome. So why do we need 2 lists? Because newbies are turned off by mostly dev talk. If CGI::App wants to attract new users, why not create a forum geared for them? How many forums do we need ? Does not this just fragment the user community to the point where the forum becomes deserted? I think it is perfectly acceptable (and probably most productive) for newbies to post on Perlmonks. Just my two yen, Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] :StartRunmode
sub first : StartRunmode { my $self = shift; return $self-forward('second'); } The current AutoRunmode plugin does not support StartRunmode, but since you really seem to like that feature, I guess I should try to implement it ... I have put something together now. It works by basically creating a method start_mode in your CGI::App subclass that will always return just one name (the name of the StartRunmode). This means that it will not be possible to mix the class-based :StartRunmode with the traditional instance-based $app-start_mode(new_name). You will not be able to change the start_mode from an instance script. I think this is an acceptable limitation, and it will be pointed out in the documentation. While it is unfortunate, it simplifies both the implementation, and more importantly understanding how the implementation works. Trying to mix both styles leads to very complicated situations, and the module documentation would quickly become incomprehensible. What does work is subclassing. A :StartRunmode in a subclass will be properly recognized. Also, this simplified approach does not depend on callback_hooks, so that it will work with pretty old versions of CGI::App as well. Barring objections, I will upload the module to CPAN over the weekend (the other change is that the method attributes are now case-insensitive). Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] :StartRunmode
This means that it will not be possible to mix the class-based :StartRunmode with the traditional instance-based $app-start_mode(new_name). You will not be able to change the start_mode from an instance script. I think that is acceptable. I don't think it would be advisable to mix the styles in a single class. However, I think it is important that it work with a base-class that may use the standard CGI::App system, and a sub-class that uses the attributes method. From the sounds of it, it should work. Yes, that should be fine. Not the other way around, though (at least not concerning the start runmode). I have another question for you about the plugin. I noticed in the current version, if I put the use CGI::Application::Plugin::AutoRunmode in my base class, I don't automatically have the ability to use the Runmode attributes in my subclasses, and I have to add the 'use' statement again. That is weird, it is supposed to work and I have cases like that in the test suite that do work. Are you using use base or some @ISA magic that probably gets executed too late (outside of a BEGIN block) ? Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Re: RFC: CAP::Plugin::PathInfo
Ideally there would need to be a runmode evaluator in the pre_run method that examined the requested URL and/or PATH_INFO in addition to the HTTP method of the request. So it would not be enough to say a PATH_INFO value of /article means I can method view_article. Chances are you would want to run a different method if a /article request was received using a DELETE, POST or PUT. How I do this (with TemplateRunner and AutoRunmode) is that a URL like my.cgi/article/index.html will display a list of articles, using the template /article/index.html. To write an article I use my.cgi/article/index.html?rm=writetitle=blahcontent=foo (as a POST, of course). This results in 1) calling the run-mode write to create the article in the database, but not outputting anything, and then 2) redirecting to the URL mycgi/article/index.html (which displays the list of articles including the new one). I case of errors, it redirects somewhere else. The redirect has the effect of making all pages reloadable and prevents accidental re-posts. Run-modes are only used to update data, and can be combined with any template (I think the word here is orthogonal). Since both run-modes and templates (plus data files for them) are defined in external files, this system can be easily extended by adding extra run-modes and templates without touching the Perl modules, which is good if you work in a team on a site with many pages. Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Getting more out of CGI::App with less syntax.
Hi Mark, sub first : StartRunmode { my $self = shift; return $self-forward('second'); } The current AutoRunmode plugin does not support StartRunmode, but since you really seem to like that feature, I guess I should try to implement it ... AnyTemplate can figures out the file name for you, and uses the template engine of your choice, or if you are distributing your app, your users can choose! That second part (about the users choosing the template engine) has not occurred to me yet. That is indeed cool. Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] college_application_form : StartRunMode
Hi Mark and Cees, How about this: sub my_run_mode : DefaultRunmode { # do something here } If I saw this I would know what the run mode does, /and/ that is the default: college_application_form : StartRunMode I started to work on this, but I am afraid it is not so easy. The concept of the AutoRunmode plugin is that it works in addition to the built-in workflow of CGI::App. So, if a runmode is requested, that has not been registered in the traditional way, the module tries to resolve that. This will not work very well with start_mode(), because start_mode() is always defined (at least with the built-in default), and the plugin cannot know if it is supposed to override that definition or not. The only thing I can think of right now is to have the plugin act only if the default setting ( start ) is still in place. I am not sure I like that limitation, mainly because this extra caveat, along with the necessary explanations and the possible bugs that any kind of additional complexity introduces, would make the plugin much clumsier to use than the traditional way, thus negating the benefit of having a plugin. Any ideas? Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Re: Class::Trigger [was Hooks, HTML::Tidy plugin]
Hi Rhesa, - add_callback() accepts both a coderef and a string. Class::Trigger only accepts coderefs. Why did you decide to accept sub names as well? The whole system of overloadable methods in sub classes depends on that. So an alternate implementation had better preserve it. Cheers, Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] ANNOUNCE: Plugin::AutoRunmode 0.06 (with hooks support)
How about this: sub my_run_mode : DefaultRunmode { # do something here } That looks entirely doable, and not even too difficult, but I am not sure if I want to implement it, mostly because the functionality is already in CGI::App, which defines a default run-mode named start. So you can just do sub start : Runmode { # do something here } Or am I missing something ? But thanks for the suggestion, I will at the least document this behaviour in the next release. Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
[cgiapp] AutoRunmode and default run mode
Cees, it seems my assumption earlier today, that sub start : Runmode { } would work as a default run mode, was partly mistaken. It does work, but only if you override the setup in CGI::App, because the default setup registers a start runmode as method dump_html. Since start is then registered already, AutoRunmode will not do anything about it (it only works if nothing is registered so far). In order to make above code work, you need to at least do sub setup{} which is a little silly. On the other hand, most people already have a setup(). In that case, it would work, too. (In fact, if you do not override setup(), you end up with the dump_html runmode in your application, which you probably do not really want to have) I am now thinking whether AutoRunmode should override runmodes that have been explicitly registered (would fix the start problem, but is probably a bad idea in general), and I am also reconsidering your DefaultRunmode suggestion. Cheers, Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Re: ANNOUNCE: Plugin::AutoRunmode 0.06 (with hooks support)
I thought of the same idea as Cees independently and would also like to see this happen. Okay, I'll work on that. Also, is there a particular reason to use StudlyCaps when this_style is the convention for names in CGI::App? If you refer to the Runmode attribute, all-lower-case attribute names are reserved for Perl internal use (same as all-lower-case module names). Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
[cgiapp] ANNOUNCE: Plugin::AutoRunmode 0.06 (with hooks support)
I am in the process of updating the AutoRunmode plugin to use the new hook interface. Unfortunately, it seems that CGI::App prerun will always run after all the hooks. I am not sure how to resolve this without requiring additional hooks such as 'after_prerun'. I will probably just point out the problem in the documentation and advise the users of the non-elegant work-around. The problem only occurs in the presence of a prerun method that actually changes the runmode. I think that is a good solution and may be a good enough solution. Let's see. OK. http://search.cpan.org/~thilo/CGI-Application-Plugin-AutoRunmode-0.06/ AutoRunmode.pm The new version, which by using the hook interface in CGI::App 4, becomes as simple to use as package MyApp; use base 'CGI::Application'; use CGI::Application::Plugin::AutoRunmode; sub my_run_mode : Runmode { # do something here } sub another_run_mode : Runmode { # do something else } # you now have two run modes # my_run_mode and another_run_mode (no need to import a cgiapp_prerun method anymore, this is done via a hook now). The module is also compatible with CGI::App 3.x (exporting cgiapp_prerun is still supported). Cheers, Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Global default for Templates
Dan, I guess the other benefit I'm looking to receive is the caching of templates. But I don't want to go through all of my modules adding the cache option to load_tmpl. Can I set this somehow in my base class's prerun or init methods? You can override your base class's load_tmpl method (now inherited from CGI::App). Have a look at the source of CGI::App's load_tmpl , copy that code into your base class and just add the cache option. Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] A couple of questions
Hi Peter, About question one: sub cgiapp_init { $self-tmpl_path('/Library/WebServer/CGI-Executables/kartingdata/ templates/'); } sub logon { my ($self, @args) = @_; my $page = HTML::Template-new(filename = 'logon.tmpl'); I get the error . . .Cannot open included file logon.tmpl . . . the CGI::App template path is only used by CGI::App. HTML::Template does not know or care about this at all. If you want the template path to have any effect, you have to let CGI::App create the template for you: my $tmpl_obj = $webapp-load_tmpl('some.tmpl'); NOT: my $tmpl_obj = HTML::Template-new ( filename = 'some.tmpl' ); Cheers, Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] XMLHTTPRequest / Remote Scripting / AJAX
Hi all, If you haven't heard of XMLHTTPReqeust aka Remote Scripting aka AJAX it's basically a way for web pages to communicate with the server and return information through JavaScript without having to refresh the page. For those interested in using JavaScript to update parts of the page (rather that refreshing it completely) here is a whole (CGI::App-derived) framework built on that idea: http://search.cpan.org/~eric/OpenThought-0.71/lib/OpenThought.pm http://search.cpan.org/~eric/OpenPlugin-0.11/OpenPlugin/Application.pm It uses a hidden frame to communicate with the server (which is what people did before the advent of XMLHTTPRequest, but the idea is the same). I have not used OpenThought, just stumbled upon the link. And since we are at it, has anyone done experiments with building CGI::Apps for Mozilla XUL that they want to share? (This is of course totally non-cross-browser, so not useful for web sites, but could be worth a look for Intranet applications) Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Bug Report: CGI::Application/CGI::A::Plugin::TT
Adding an attribute is as simple as this: sub my_runmode : RunMode { ... } Well, not quite. In order to be able to set attributes, you have to write some code. Without it, the sample above will just produce: Invalid CODE attribute: RunMode at /tmp/t.pl line 7 BEGIN failed--compilation aborted at /tmp/t.pl line 7. You would have to create subroutines called MODIFY_CODE_ATTRIBUTES and FETCH_CODE_ATTRIBUTES. This is not entirely trivial. Check the documentation perldoc attributes if you want to go there. If you use the CGI::Application::Plugin::AutoRunmode it will install handlers for an attribute Runmode into the CGI::Application package ( I am not totally comfortable with this, it should install these in the sub-class that you are actually using to reduce potential clashes with other attributes, but this is how it works now). Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Bug Report: CGI::Application/CGI::A::Plugin::TT
If you use the CGI::Application::Plugin::AutoRunmode it will install handlers for an attribute Runmode into the CGI::Application package ( I am not totally comfortable with this, it should install these in the sub-class that you are actually using to reduce potential clashes with other attributes, but this is how it works now). Well, that simplifies things. As for writing directly into the CGI::App namespace, could you not export those methods? I could, but at the time I wrote the plugin my lack of experience with how Exporter works prevented me from even having this idea :-) I guess I will fix it in one of the next releases... Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Autodiscovery of run modes using delegates
Hi all, thanks for the feedback. this would be especially useful if you were allowed to have more than one delegate...as it would open the way for run-mode reuse across applications. You can have delegates that inherit from (possibly multiple) other (delegate) classes. That should solve the multiple delegate problem. I want to avoid multiple delegates as such, because it makes the interface more complex. One would have to think about order of precedence as well, which is already well established using multiple inheritance for the delegate object. Thilo, is there a way to use the AutoRunmode plugin in conjunction with a run_mode() command in my setup() subroutine? The AutoRunmode only has any effect if the requested run mode cannot be resolved with what has already been set up in the normal way (using runmode() ) Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Autodiscovery of run modes using delegates
Wow, that's a great idea. In fact, what would be more useful for me would be a way to mix-in runmodes from other classes (or delegates). Also note that you can already do the following in CGI::App to access runmodes defined in other packages: sub setup{ my ($self) = @_; $self-run_modes( 'start' = 'MyRunModes::blah' ); } Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Autodiscovery of run modes using delegates
Also note that you can already do the following in CGI::App to access runmodes defined in other packages: sub setup{ my ($self) = @_; $self-run_modes( 'start' = 'MyRunModes::blah' ); } To spare me digging into the code, what does the above actually do? Sorry for the brevity of the example. For above case you would have to have a module with a subroutine blah that implements the run-mode. package MyRunModes; sub blah{ my ($app) = @_; # implement the run mode here (as usual) my $p = $app-param('foo'); return 'some html'; } is 'MyRunModes::blah', purely a set of runmodes that don't do anything unless they are loaded into a CGI::App module? No, it is just a single runmode. And you would have to load the module yourself before trying to use it. Is it a CGI::App module? No, it is something you have to write yourself, and it does not have to be a CGI::App subclass. I just wanted to show that if you want to break out the implementation of the run mode into different modules, you can already do this in CGI::App. My AutoRunmode plugin is just about discovering those run modes, so that you do not have to manually register them. Another (probably better) way to do the same thing would be this pattern (using multiple inheritance): package MyTestApp; use base qw[ CGI::Application MyRunModes ]; sub setup{ my ($self) = @_; $self-run_modes( 'start' = 'blah' ); # this works because MyTestApp inherited blah from MyRunModes } Finally I would like to point out that these run mode subroutines (no matter where you place them in your module hierarchy) should in my opinion be small wrappers around some back-end modules that do the real work. CGI::App is just the controller in the MCV framework, the business logic should be in other modules (not in the CGI::App subclass) where they can also be accessed outside of the web context. Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
[cgiapp] Autodiscovery of run modes using delegates
Hi all, here is another take on one of my favourite topics, the automatic discovery of run modes. Basically, I want to have CGI::App to look at my application instance and call a method of the same name as the requested run-mode. Because of the security problem inherent in this approach, some care has to be taken. One way to mark the appropriate subroutines as run modes is to use subroutine attributes. I implemented that in the CGI::App plugin AutoRunmode: package MyApp; use base 'CGI::Application'; use CGI::Application::Plugin::AutoRunmode qw [ cgiapp_prerun]; sub my_run_mode : Runmode { # do something here } This works well, but now I have another idea, using a delegate object that implements all the run-modes. I got this idea from working with Objective-C/Cocoa, which makes use of delegation (rather than inheritance) a lot. So, you can set up a delegate object, all of which methods are run-modes. It is important that it has not other methods, since these methods will be directly accessible via the web (they are all considered run modes). I have extended the AutoRunmode plugin to support this new approach as well. Have a look if you want: Docs: http://perl-pad.sourceforge.net/cgiapp/AutoRunmode.html Module: http://perl-pad.sourceforge.net/cgiapp/CGI-Application-Plugin- AutoRunmode-0.03.tar.gz Assuming there are no grave mistakes, the module is on its way to CPAN. Thilo PS: The plugin has support for the Callbacks extension, which is not on CPAN. I think the latest version is here: http://cees.crtconsulting.ca/perl/modules/CGI-Application-Callbacks -0.01/ Two questions: 1) What happened to the callback idea? 2) There seems to be a bug in Callbacks, as it tries to croak without loading the Carp module first. - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Seeing source rather than the page
Hi Dan, For some reason, one of my CGI::Application modes outputs the source in Firefox instead of the formatted HTML itself (it works fine with MS Internet Explorer) That sounds a lot like a wrong content-type header (which MSIE seems to ignore). Before trying to find out what is causing this, you should check if it is really the case. I recommend the excellent LiveHttpHeaders plugin for Firefox, it is very useful for wire-level-debugging as it shows you all HTTP headers as they are sent or received (both request and response). http://livehttpheaders.mozdev.org/ In case the header wasn't being generated correctly, I also tried adding $self-query-header to the output but to no avail - I just get Content-Type: text/html; charset=ISO-8859-1 added to the output Any ideas? Yeah, if the header has already been sent, this is not going to work. Are you printing anything directly before CGI::App has a chance to send the headers (although that should result in an internal server error)? Are you manipulating the headers (via $self-header_type or $self-header_props) in any way (cookies, content-types) and maybe introduced a mistake there? Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
[cgiapp] Patch: DBH plugin configuration
Hi Mark, I think I would accept a patch for this functionality to '::Plugin::DBH' if you wanted to make it work. I can't say I'm excited enough to code it myself, though. :) I'll take your word on that :-) Below is a patch. It still passes the the current test suite and I can make additional tests for the new functionality if the patch gets accepted. The syntax changed a little from my previous post, here is the POD I wrote automatic configuration using CGI::App instance parameters An alternative to explicitly calling dbh_config in your application is to rely on the presence of specific instance parameters that allow the plugin to configure itself. If you set the CGI::App parameter ::Plugin::DBH::dbh_config to an array reference the contents of that array will be used as parameters to dbh_config (if it has not been explicitly called before). The code in the synopsis can be rewritten as use CGI::Application::Plugin::DBH (qw/dbh/); # no longer a need to import dbh_config sub cgiapp_init { # you do not need to do anything here } sub my_run_mode { # this part stays unchanged } and in the instance script ( or instance configuration file, if you have) $app-param('::Plugin::DBH::dbh_config' = [ $data_source, $username, $auth, \%attr ] ); If you want to configure more than one handle, set up a hash with the handle names as keys: $app-param('::Plugin::DBH::dbh_config' = { my_handle = [ $data_source, $username, $auth, \%attr ] , my_other_handle = [ $data_source, $username, $auth, \%attr ] } ); Cheers, Thilo diff output against CPAN 2.00 version == croak must call dbh_config() before calling dbh(). unless $self-{__DBH_CONFIG}{$name}; --- unless ($self-{__DBH_CONFIG}{$name}){ __auto_config($self, $name); croak must call dbh_config() before calling dbh(). unless $self-{__DBH_CONFIG}{$name}; } 68a72,100 sub __auto_config { # get parameters for dbh_config from CGI::App instance parameters my $app = shift; my $name = shift; my $params = $app-param('::Plugin::DBH::dbh_config'); return unless $params; # if array reference: only one handle configured, pass array contents to dbh_config if (UNIVERSAL::isa($params, 'ARRAY')){ # verify that we really want the default handle return unless $name eq dbh_default_name($app); dbh_config($app, @$params); return; } # if hash reference: many handles configured, named with the hash keys if (UNIVERSAL::isa($params, 'HASH')){ $params = $params-{$name}; return unless $params; dbh_config($app, $name, $params); return; } croak Parameter ::Plugin::DBH::dbh_config must be an array or hash reference; } 167a200,242 =head3 automatic configuration using CGI::App instance parameters An alternative to explicitly calling Cdbh_config in your application is to rely on the presence of specific instance parameters that allow the plugin to configure itself. If you set the CGI::App parameter C::Plugin::DBH::dbh_config to an array reference the contents of that array will be used as parameters to Cdbh_config (if it has not been explicitly called before). The code in the synopsis can be rewritten as use CGI::Application::Plugin::DBH (qw/dbh/); # no longer a need to import dbh_config sub cgiapp_init { # you do not need to do anything here } sub my_run_mode { # this part stays unchanged } and in the instance script ( or instance configuration file, if you have) $app-param('::Plugin::DBH::dbh_config' = [ $data_source, $username, $auth, \%attr ] ); If you want to configure more than one handle, set up a hash with the handle names as keys: $app-param('::Plugin::DBH::dbh_config' = { my_handle = [ $data_source, $username, $auth, \%attr ] , my_other_handle = [ $data_source, $username, $auth, \%attr ] } ); 200a276,278 Autoconfig Support added by: Thilo Planz [EMAIL PROTECTED] - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
[cgiapp] DBH plugin configuration
Hi all, I am just looking at the DBH plugin and how it is used: use CGI::Application::Plugin::DBH (qw/dbh_config dbh/); sub cgiapp_init { my $self = shift; # use the same args as DBI-connect(); $self-dbh_config($data_source, $username, $auth, \%attr); } Since you need to get $data_source from somewhere, this might actually be more like: use CGI::Application::Plugin::DBH (qw/dbh_config dbh/); sub cgiapp_init { my $self = shift; # get the params my $data_source = $self-param('data_source'); my $username = $self-param('data_source_user'); my $auth = $self-param('data_source_pass'); # use the same args as DBI-connect(); $self-dbh_config($data_source, $username, $auth. { SomeAttr = 1}); } I think it should be possible to completely get rid of all this code by having some naming conventions for the CGI::App instance parameters. The plugin could then bootstrap itself from the parameters of the instance. my $app = new MyCGIApp; $app-param ( '::Plugin::DBH' = { data_source = [ 'dbi:...', 'blah', 'blah' ] } ); dbh_config could use these parameters to connect to the DB. It would only do this unless explicitly configured, which makes this a backwards-compatible feature. The ::Plugin::DBH data_source parameter could also take a hash of arrays to accomodate named handles. Not everyone is setting parameters in the instance script. Some people are using configuration files in various formats that get more or less automagically (code-free) included. This kind of plugin autoconfiguration would also integrate nicely with those. Am I making sense to anyone? Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] load_tmpl question/suggestion
This should work ok with H::T. But, the only way I can make it work with C::A is if I write my own load_tmpl method to distinguish between the first load from file and second load from scalar. If C::A used H::T's -new method, the source of the template could be passed as a parm on load_tmpl (filename =, or scalarref =). What are the chances of getting this more flexible interface to H::T? I do not think load_tmpl needs to support loading the template from a scalar. The only extra functionality it provides over the raw call to HTML::Template-new is that it figures out the path where to load the file from. It does nothing else. So if you do not want to load from a file, you should not use this method, but instantiate. HTML::Template directly. Cheers, Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
[cgiapp] new competition: CGI::Prototype
Hi all, I just saw that Randal L. Schwartz published CGI::Prototype on CPAN yesterday. http://search.cpan.org/~merlyn/CGI-Prototype-0.90/lib/CGI/Prototype.pm The more, the merrier I suppose... Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] A runmode for every page ?
What I'm looking for is a method which i cause use 1 single runmode to display any page in my system, [and let the pages more or less draw them selves.] then other runmodes would only be used for doing business logic, adding things to a database etc.. I thought of using embedded perl with this.. but I'm not to sure if this is the right solution.. I am doing things like that, and I tried to make the code I wrote for that useful to other people by putting it into http://search.cpan.org/~thilo/CGI-Application-Plugin-TemplateRunner -0.03/TemplateRunner.pm What this module gives you is a runmode show_tmpl that extracts the page name for the URL (path_info), loads a template of the same name and an associated datafile, which gets the data for the template, so that it can more or less draw itself. If you do not want to use path_info, you can still use the method prepare_tmpl() to load the template (including the data file) from within your own runmode. Please have a look, Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] error handling in callbacks
Agreed, though I wish CGI::App would provide a means of catching that and displaying it to the browser rather then throwing up a 500 error and forcing a tail through the server error log. For errors that occur in the run_mode itself, CGI::App has much improved recently by allowing an error_mode that can handle the exception. Unfortunately, this does not cover exceptions before or after the run_mode, such as in one of the hooks or callbacks. Maybe it could be modified to somehow use error_mode here as well. If you can provide some code that uses a cleaner error handling mechanism we could look at incorporating it. Ideally though, I would love to see CGI::App implement a scheme like this by using Class:ErrorHandler as its base (which gives all objects from subclasses the error and errstr methods) and make sure all methods return at least a null string unless something has gone wrong. Just like HTML templating, exception handling is a topic were everyone has his favourite methods and modules, so it is very unlikely that we can agree on something more elaborate than the plain die(). Again, CGI::App has greatly improved recently, in that it no longer stringifies the exceptions that your code dies() with, so that if you want, you can throw hashrefs or Class::Exceptions. In earlier versions, CGI::App would flatten them to strings, but now it just passes them through, and you can handle them somewhere else ( for example in the error_mode, or your instance script, or a custom run() method that wraps around the original one) Thilo - Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Re: feedback on ::Plugin::ConfigAuto update (a use for register_hook?)
Once these features are moved into CGI::App, I see the documentation appearing a little out of the way in a section on WRITING PLUGINS or Advanced Usage. There is no need for new users to be trying to figure out if they need these features, in my opinion. The whole WRITING PLUGINS sections could be moved into a separate POD altogether... perldoc CGI::Application::Callbacks would bring it up. I think having a development version available for several weeks would be useful for folks to test with existing applications. It seems that we can already use Cees' module for that. It works as a drop-in replacement for CGI::App and all you have to change is the name of the module in your use base line. (Or Cees could rewrite C::A::Callbacks to work as a plugin, exporting all its methods ) Thilo - Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
[cgiapp] AutoRunmode plugin updated to use callbacks
Hi, It is unfortunate that it needs to be implemented using the prerun hook, but I can see your reasons for not rewriting the 'run' method in CGI::Application. This module also shows a very good example of the potential usefulness of the callbacks patch as well. I updated the AutoRunmode plugin to use the callback interface (optionally, the Exporter interface still works, as does explicitly calling the method) http://perl-pad.sourceforge.net/cgiapp/AutoRunmode.html http://perl-pad.sourceforge.net/cgiapp/CGI-Application-Plugin- AutoRunmode-0.02.tar.gz So now you can do this: package MyApp; use base 'CGI::Application::Callbacks'; use CGI::Application::Plugin::AutoRunmode (); sub setup{ my $self = shift; install CGI::Application::Plugin::AutoRunmode($self); } sub do_something : Runmode{ # } At the moment, the callback interface is a little verbose, you have to first use the module, and then install the callbacks. Maybe if callbacks and plugins become popular, we could come up with something more concise, for example sub setup{ my $self = shift; $self-use_plugin('::AutoRunmode'); } where use_plugin() would use the plugin and call some install method to let it set itself up. Thilo - Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] AutoRunmode plugin updated to use callbacks
sub setup{ my $self = shift; $self-use_plugin('::AutoRunmode'); } where use_plugin() would use the plugin and call some install method to let it set itself up. I like the idea of making it less verbose. I haven't actually looked at the callback implementation, but is it not possible to have the used plugin just install itself? Why can't use CGI::Application::Plugin::AutoRunmode; just do the right thing and install all of the hooks, callbacks, etc that it needs to do? This would be really non-verbose. That would be the Perl way, yes. I tried to do that actually. But use happens at compile time, whereas $self-add_callback is called on the CGI::App instance at runtime (and cannot be done with a use -- at least as far as I can see). Should we have support for compile-time add-callbacks? I think not. Things are already getting a little more complex and we do not want to add a steep learning curve to CGI::App, I hope. So I think having a install method that plugin writers can supply and that gets called automatically, would be a good compromise. (It is really only a problem for plugin writers, if you want to add callbacks to your own application, you can just do so in setup(), no need to make extra code disappear with some behind-the-scenes magic) Thilo - Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
[cgiapp] Re: redirects in form processing
It's just that I've never needed a redirect in my life. I'm curious as to how you've worked redirects into your way of thinking of them as being part of your solution. I have taken up the practice of ALWAYS redirecting after successfully processing a POST request (to a page that shows the result). This prevents the situation that users can (not always accidentally) repost stuff by using the famous F5 key. Successfully means that the form does not have to be returned to the user to fix invalid input. Just a thought, Thilo - Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
[cgiapp] Re: CGI-compatible wrapper for Apache::Request
it would be nice to have a wrapper around Apache::Request that supplies the missing methods. That wrapper would function like a normal CGI.pm object for all the CGI::App cares. I like this idea. It seems like there would be some edge cases, though. If you set something with 'param' with one object, you would want it to appear in the other ones. It seems that to be truly transparent, you have to sync the params back and forth between the objects each time you switch from one to the other. Could be a real pain. Well, by wrapping I mean, the param() will just call the underlying method of Apache::Request. It will not keep any state itself. It would work as a drop-in replacement, just like CGI::Simple. CGI::Simple is only a replacement for /most/ methods. It has several documented differents. I believe it handles file uploads a little diferently, not to mention missing of all the HTML generation methods. ( I still use popup_menu() ). Sure. Not doing all the HTML stuff (and having to load it) is I think the main motivation for CGI::Simple. But CGI::Simple is compatible enough to work with CGI::App (and other modules if they are coded liberally, unlike CGI::Session as recently discussed). It would be nice to have something similar for Apache::Request. Thilo - Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
[cgiapp] Re: HTML select lists
HtmlTemplate looked easy enough, but mentions problems with select constructions. Does TT treat these more gracefully? Just to remind everyone of our excellent Wiki, which has a whole page on this topic: http://twiki.med.yale.edu/twiki2/bin/view/CGIapp/SettingDropDownValues I prefer Alternative One: Just make the first item dynamic select name=episode tmpl_if episode/value option value=tmpl_var episode/valuetmpl_var episode/name/option option disabled-/option /tmpl_if option value=1Episode I/option option value=2Episode II/option option value=3Episode III/option option value=4Episode IV/option /select Cheers, Thilo - Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
[cgiapp] ANN: Plugin::AutoRunmode
Hi all, here is another plugin to discuss: http://perl-pad.sourceforge.net/cgiapp/AutoRunmode.html http://perl-pad.sourceforge.net/cgiapp/CGI-Application-Plugin- AutoRunmode-0.01.tar.gz The plugin lets you flag methods as Runmode and then you can call them without setting up the usual name mapping table via $self-run_modes : package MyApp; use base 'CGI::Application'; use CGI::Application::Plugin::AutoRunmode qw [ cgiapp_prerun]; sub my_run_mode : Runmode { # do something here } sub another_run_mode : Runmode { # do something else } # you now have two run modes # my_run_mode and another_run_mode Feedback, as usual, highly appreciated, Thilo - Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
[cgiapp] Re: ANN: CGI::Application::Plugin::HtmlTemplate
However, I strongly recommend a different name. :) The current name sounds like you are adding support for HTML::Template to CGI::App as a plugin...which doesn't make sense. Yeah, I am not so happy about the name myself. But I could not come up with anything better. TemplateDispatcher? TemplateRunner? Ideas anyone? - A new and novel way of managing HTML::Template input: keeping the input for each template in it's own file. I don't really see the use of this. :) Well, it does away with the need to know anything about the templates in your runmodes, not even what kind of data they need/want. Simple example: You have a common page header, which makes a page title like this: tmpl_var page_title. Where do you set the page title, which is arguably a presentational issue. You cannot set parameters from with your HTML::Template, so you have to do it in the run mode that calls the template. Which means the designer cannot easily change the page title. Another example: If you have a page that displays a BBS, you can have your bbs/index.html and bbs/index.html.pl which gathers the data for the template. You do not need to write a runmode to display that page. The data file is the mapping file between the template and your DB access modules. You still need to write a runmode to edit a BBS message, but that runmode does not have to do anything related to producing output. It can just forward to the runmode show_tmpl. Now, if we have a way to auto-discover runmodes (using same kind of naming convention) you would not have to write a CGI::App subclass-module at all. You just write your business logic modules and very small dynamically included Perl files (like the data files in my plugin) that pull things together. Thilo - Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Re: ANN: CGI::Application::Plugin::HtmlTemplate
The best name depends on what you consider the primary function: Is the it the ability to handle nearly static pages easily, or the 'show_tmpl' system of handle data passed to the template? I guess the runmode that automatically dispatches to your templates is the main thing. The system to handle data is just a consequence of wanting to this. If you are going to write your own runmode just to load a template and stuff data in it, you do not need the whole data file thing (or even the path_info mapping). - A new and novel way of managing HTML::Template input: keeping the input for each template in it's own file. I don't really see the use of this. :) Well, it does away with the need to know anything about the templates in your runmodes, not even what kind of data they need/want. Perhaps you have a system where you have moved 95% of your functionality into DB Access modules and other Model modules, so your CGI::App run modules are virtually shells. I have. Actually, I moved almost all of the functionality into stored procedures of the database, and the Perl part is really just a shell to call those procedures from the web. Basically, my Perl DB access code just looks like my $result = MyDB::run_query ( $procedure_name, $app, qw[ list of parameters ] ); where the parameters for it are taken from the CGI query string. For example http://mydomain/bbs/index.html?rm=delete_bbs_message;msg_no=1234 uses my $result MyDB::run_query( 'bbs.delete_message', $app, qw[ sessionid msg_no ] ); and gets turned into begin :r := bbs.delete_message (:sessionid, :msg_no ); end; The $result that is returned is an error code. If there is no error, the application dispatches to the template indicated in the URL (bbs/index.html). If there is an error, an approriate error message is displayed instead (or in addition). The advantage is that I can access the application logic not only from within the webapp, but also from other Perl code, or from Java code, or using the SQL command line. That's the great thing about a flexible plug-in system-- We can each plug-in the pieces that work best for us. If this system works well for you, chances are that someone else will appreciate it as well. I will upload it to CPAN once it has a proper name :-) Cheers, Thilo - Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Hybrid static/dynamic site
Joel, You might also look at using Template Toolkit (see site http://template-toolkit.org). It has scripts to allow whole websites to be built with the invocation of a single script. My favourite static renderer at the moment is HTML::Webmake. http://webmake.taint.org/ It can also build/refresh whole sites from a single script. Thilo - Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Setting HTML::Template options
Is there a way to globally set the HTML::Template options when using CGI::Application? TMPL_PATH allows you to set the template directory, but there are other application-wide setting like caching etc that I would like to set, but don't want to do it eveytime I call load_tmpl You can have a method in your CGI::Application class that calls load_tmpl with the appropriate parameters. You then call this method instead of load_tmpl. You could even give it the same name load_tmpl to avoid having to change existing code but I find this confusing. I always have a prepare_tmpl that looks like this: sub prepare_tmpl{ my ($self, $name, @extras) = @_; my $cache = 'cache'; $cache = 'shared_cache' if $IPC::SharedCache::VERSION; my $tmpl = $self-load_tmpl($name, die_on_bad_params = 0, loop_context_vars = 1, global_vars = 1, $cache = 1, ); $tmpl-param(@extras) if @extras; return $tmpl; } Cheers, Thilo - Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Splitting large projects [again]
I am starting a new project today which is going to have more 200 run modes, and I would like to break things up. Next. I suppose I will have one base class which will be called form CGI script. This class will have only one run-mode, which will load config and determine, which module to load and which sub to execute. And here I get stuck... I'm not sure how to do that. You can load modules at run-time (rather than compile time) by using require(); If you have the module name in a variable you can do eval require $module; Loading modules only when you need them reduces the startup time for CGI scripts, but if you are using mod_perl or FastCGI, you can probably ignore this and go for the normal use(). You can invoke a sub whose name is in a variable with code like this: my $name = 'mypackage::mysub'; my $result; { no strict; $result = $name('parameter'); } You have to use no strict because Perl will not allow you to call a subroutine like this otherwise. The curly brackets limit the effect of no strict to just the part that needs it. If you do not like no strict, have a look at the Symbol module. Thilo - Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Measuring the time taken by the CGI...
Fred, I'd like to measure the time taken to execute each particular hit to cgi::app and display the result. My thoughts on how to implement this are roughly: * get the time $T1 in cgiprerun - store in $self * get the time $T2 in cgipostrun and compute the difference * output the result as a template param. (is my output out already?) Anyone done this or something like it already? Thoughts? 1) use Time::HiRes. It gives you milliseconds. You want that. 2) if you do not want to change your templates to output the time, you can just print your timing message after the output has been sent, for example in teardown(). (in cgipostrun the output has not been sent yet, but it will most likely have been flatted into a string by $tmpl-output(), so you will have trouble putting in more parameters... ) Thilo - Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Re: CGI::App 3.2 proposed release available
Solution 1. We could simply remove the catch/rethrow altogether, and leave it up to Perl to say that the method can't be dispatched if that's the case: Solution 2. Slightly nicer than that: Pick off those cases where the run mode method dispatch might fail and use the catch/rethrow to give a nice error in those cases. Don't use it otherwise. Solution 3. Retain the exception catching in all circumstances, but provide (yet another) overridable method, cgiapp_exception(), to deal with the exception that we've just caught. The default implementation of the new method would, of course, be the current behaviour. Which solution do you prefer? What other solutions are there? I like solution 1 over solution 2. Solution 2 has the same problems as the current implementation in that it treats exceptions returned from auto-loaded methods as strings. I never thought of auto-loading in the first place, but if we are to support it, we should do it properly (including allowing it to die with exceptions). I see your problem with solution 3, in that cgiapp_exception adds an additional stack frame if it dies. However, cgiapp_exception does not necessarily have to die at all. It could just produce a nice error page, and then return to let run() finish its work (headers, teardown and all) What I am currently doing is an extended version of solution 3. Solution 4 cgiapp_exception is allowed to return a result, which is then sent to the client (instead of the normal runmode output). # Process run mode! my $body = eval { $autoload_mode ? $self-$rmeth($rm) : $self-$rmeth() }; -die Error executing run mode '$rm': $@ if $@; +if ($@) { +$body = $self-cgiapp_exception($rm, $@); # in case cgiapp_exception does not die +} We could solve the stack frame thing by not having cgiapp_exception defined in the base class, and only calling it if we can() (because it has been defined in subclasses). If it is not defined, we just die as in solution 1 # Process run mode! my $body = eval { $autoload_mode ? $self-$rmeth($rm) : $self-$rmeth() }; -die Error executing run mode '$rm': $@ if $@; +if ($@) { + if ($self-can('cgiapp_exception'){ + $body = $self-cgiapp_exception($rm, $@); + } + else{ + die $@; + } +} Thilo - Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] concerns with new header_props
Cees, Mark, and I are in a conversation regarding changes to the functionality of header_props() in version 3.2. Before I reply to Cees' message, I wanted to forward it to the list to get your input. Regarding the cookie functionality: I would rather not fix problems in CGI.pm. That said, how does CGI.pm handle this situation? If I call $query-header(-cookie={...}) multiple times does it aggregate your cookies? If not, than it's not a CGI-App problem -- it's a CGI.pm problem. The CGI.pm header() function is a onetime use function. It doesn't store the headers, it will return the requested headers immediately including any extra required headers to make up a valid request. This is not so much a problem with CGI.pm as it is more a design decision that made sense in a function based module. I agree with Cees here. This is not a CGI.pm problem. CGI::App should provide an interface for setting cookies one by one ( rather than all at once). Cees gave some very good examples why that is useful. The same goes for all the other headers. header_props - works as is Keeping header_props unchanged sounds like a good idea in order not to break things. header_add- add a header of this type to the current list I think adding a header of this type to the current list makes sense only for cookies. Passing a list (arrayref) to CGI-header does not work with other headers than cookies: CGI::header(-expires = [1,2], -cookie = [1,2]); results in Set-Cookie: 1 === array ref working (two cookie headers) Set-Cookie: 2 Expires: ARRAY(0x1a264a0) === array ref not working Date: Sun, 09 Nov 2003 12:54:25 GMT Content-Type: text/html; charset=ISO-8859-1 so we could just call the function add_cookie (and it does not take a type anymore, just a list of cookies). For maximum compatibility with the many tools people use, the cookies are passed in as plain strings (with their encoded value). This precludes us from eliminating duplicate cookies (with the same name) but if we remember the order in which the cookies are added, that should be okay (second cookie header wins over first header) header_set- replace the current header of this type okay. Just my two yen, Thilo - Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] cgi_minimal compatible?
I do not know CGI::Minimal, but CGI::Application does not use the HTML-producing functions of CGI.pm. Thanks. CGI::Minimal is just a way to get access to CGI vars without accepting all the more popular things CGI.pm gives. $q-header(%header_props) I'm *very* weak with Perl's object programming. Can you tell me how I would wrapper CGI::Minimal and add the header() method? Three options (in recommended order): a) use CGI.pm. I cannot really believe that the overhead of its additional features is significant in any way. It does load most of its features on demand anyway. b) Add the header() function to CGI::Minimal. You do not need to make a wrapper class (unless you want to put in more stuff). Since this is Perl, you can just add methods to classes at runtime: sub CGI::Minimal::header{ my ($self, %params) = @_; ... } (in your CGI::Application subclass) c) Tell CGI::Application not to output headers, but print them yourself $app-header_type('none') Thilo - Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Perl CGI authentication and session management
Question: are the HTTP requests (with CGI fields and values, including session_id) encrypted when using https? Everything you send or receive via https is encryted. This even includes the HTTP headers, which is why name-based virtual hosting does not work with https. Cookies are a bit more insecure because they are stored on the client machine in uncrypted format. Okay. Yes, but since you only store a session ID (at least this is what you should do) which is a random number that also expires after some time, that is not such a big problem. Also, session cookies are usually not stored on disk in the client machine, but just in the browser's memory and go away if you close the browser. Depending on how paranoid you are you can also set the secure connection flag on the cookie, so the cookie will only be send via encrypted connections. Cheers, Thilo PS: I suspected as much. The only solution I could think of was digital signatures on both the client and the server. Well, the real high-end solution would be to use SSL client authentication. This is a feature of SSL, that you can use when connecting via https. I have no idea how to do that in Perl, but if you find a way you can retrieve the client SSL certificate and verify his identity that way. The advantage is that you do not need any other authentication mechanisms (no passwords, single sign-on). The drawback is that you need a full-fledged public key infrastructure, including client certificates for ALL your users. - Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
[cgiapp] Re: Perl CGI authentication and session management
Depending on how paranoid you are you can also set the secure connection flag on the cookie, so the cookie will only be send via encrypted connections. Does this work using http? (A given session may go back and forth between http and https.) In that case, you should not use this flag. A cookie will normally be sent back to servers in the domain that created it by both http and https. This is the behavior that you want if your sessions go back and forth between the protocols (for example if you only secure the login page to protect the password) . If you enable the secure connection feature, the cookie will only be returned to servers by https. It will be ignored for normal http. You might want to check the perldoc for CGI::Cookie, it explains all the options for cookies. Thilo - Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] putting together the output of multiple parts
i have a couple of html-templates, which i would like to fill in with their appropriat backend functions. e.g. i have a search template, where one can enter search terms and submit a query. Then there is the major part of the page, which should be used to display stuff, mostly the search results. i would like to have those two be filled in and be run in seperate functions. I think frames would make that possible, but frames are evil and i would like to avoid those. It absolutely makes sense to me to have separate functions to fill in different parts of the template. is it possible and recommended to hop from one mode to the next with $self-newrunmode, filling in one bit at a time? But why to you want these (backend) functions to be runmodes as well ? Why not have functions like fill_in_seach_box and fill_in_search_results that take a template as a parameter (and probably more parameters, depending on what they need to do) and set the appropriate parameters in the template. You would call these functions from your runmode functions. Pseudocode: sub runmode_search { my ($self) = @_; my $tmpl = get_template_from_somewhere; fill_in_search_box($tmpl) fill_in_search_results($tmpl) return $tmpl-output; } sub fill_in_search_box{ my ($self, $tmpl) = @_; $tmpl-param( SOME_PARAMETER = 1234); } sub fill_in_search_results{ my ($self, $tmpl) = @_; my $data = get_search_data_from_somewhere; $tmpl-param( SOME_RESULT = $data); } Try to keep the runmode methods as slim as possible and move all the business logic (such as gathering search results) into other methods or even other packages. That way you have a maintainable CGI::App module that acts as a controller for a collection of business logic functions that you can also use in different contexts (such as from the command line for quick checks, or in other applications) Just my two yen, Thilo - Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] directory structure and static pages
2. for a large project, not all of the pages have to be dynamic obviously. How do people deal with static pages that you want to still share the look of your dynamic pages that you are using HTML::Template for? I was considering creating a commandline tool to generate the static pages from the HTML::Templates or creating a module just for serving static pages (not that they would be static anymore) and wrapping the header and footer, setting the title, etc. but each of these have downsides. How do the experts do it? Now that is a good question. I have spent some time looking for just such a command line tool that renders a whole tree of HTML::Templates into static HTML files, but could not find anything. The closest thing I found was WebMake (http://webmake.taint.org/)., but it uses its own templating syntax. Anyone know a nice static HTML renderer for HTML::Template ? Thilo - Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] CGI::Application with fastcgi
Has anyone tried to use CGI::Application with fastcgi? When I try, my script runs, but it does not switch between the runmodes correctly. You probably have problems with the CGI object not being initialized properly (thus retaining values from a previous request). The CGI::Fast module worked for me. Try this in your instance script: use CGI::Fast(); while (my $q = new CGI::Fast){ my $app = new MyCGIApplication(QUERY = $q); # this is your CGI::App module $app-run(); } Cheers, Thilo - Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Global configuration
In the recent best practices document that Mark started, he mentions configuration information that is global, i.e. is needed by more than one cgi script. What CPAN configuration modules are people using in their CGI::Apps? Hi, I am not using any CPAN module, but wrote a small module myself. You can see it below (comments appreciated). Features: - configuration files usually are just Perl files, returning a hashref example: { tmpl_path = '/path/to/templates', log_level = 3, } using Perl files gives maximum flexibility, with security problems pointed out elsewhere. (I am thinking of using the Safe module to check these) - configuration files can be in other formats by providing an input processor, which is just a coderef (see method get_raw below for an example) - the data read from the files is cached, but reloaded if the file is changed (with a 5 second delay to minimize stat() calls) this makes it very efficient in mod_perl Synopsis: my $config = My::Configuration-get('/path/to/config.pl'); $config is a hashref with parameters. Cheers, Thilo == CODE BELOW === package My::Configuration; use strict; use FileHandle; # global config file cache my %CACHE = (); # modification times of the data in the caches my %MOD_TIMES = (); # get the raw contents of a file # as an array(ref) of lines sub get_raw{ my ($class, $filename) = @_; return My::Configuration-get($filename, sub{ my $fh = shift; my @result = $fh; $fh-close; return \@result; } ); } # get the contents of a configuration file # # the file will be 'done', unless an optional # processor subref is specified, in which case # the processor gets to read the file # and return a reference to something sub get{ my ($class, $filename, $processor) = @_; unless (defined $filename){ warn cannot load configuration without a filename!; return; } my $ref; # try to use the cached version my $cache_age = $MOD_TIMES{$filename}; if ($cache_age and time - $cache_age 6){ # check only every five seconds return $CACHE{$filename}; } my $mod = (stat($filename))[9]; # file exists if ($mod){ if ($cache_age and $mod == $cache_age){ # cached data has not changed return $CACHE{$filename}; } } else{ warn missing configuration file $filename \n; } $ref = ref $processor eq 'CODE' ? $processor-(new FileHandle $filename, 'r') : do $filename; unless (ref $ref){ $ref = defined $ref ? '$ref' : 'undef'; my $message=broken configuration file $filename:\n; $message .= parse error: $@\n if $@; $message .= load error: $!\n if $!; $message .= returned not a ref, but $ref\n unless $@ || $!; # die if no previous configuration exists $CACHE{$filename} ? warn ($message) : die ($message); return $CACHE{$filename}; } $CACHE{$filename} = $ref; $MOD_TIMES{$filename} = $mod; return $ref; } - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] checking passwords using SQL
A little bit of an optimization and security check - if all you are doing is comparing if the username and password match, why not let SQL do it? my $query = SELECT count(*) FROM user WHERE USER_ID = ? and USER_PASSWORD = ?; my $sth = $dbh-prepare($query); $sth-execute($user_ID, $pass_word); my ($valid_login) = $sth-fetchrow_array ();#This could also be changed Good call, but one caveat: SQL is case-insensitive. So the password and userid will be compare case-insensitively as well. (I found out about this the hard way...) You could fix this by declaring the columns or the comparison as binary (at least in MySQL). Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] returning HTML::Templates from runmodes?
Since most of us use HTML::Template, how about allowing runmodes to As one of those that don't use H::T (and I'm not alone), I'd be unhappy with tightening the bonds between them. Well, it would just be an option. No one is forced to use it, but it would benefit those who do use H::T. Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Preventing _send_header from running
Hi, In order for this to work I need to prevent the CGI::header from printing automatically. What's the best way to do this? You could overload run(), set the env variable, call SUPER::run() and grab the output, filter it, or delay printing for stdout for later. Note that this is the only print in the entire module. This seems programmatically more clean than cutting your program short at 'exit' and luckily doesn't require any changes to the standard CGI::App code. Good luck! I think the easiest way is to just overload _send_headers() like this: sub _send_headers{ return ''; } in your application module. Cheers, Thilo - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] exception handling? Re-iterated Patch Request
Hello, (1) That error (line #156, CGI::Application 2.4) only happens when you map your run modes like so: 'select_document', = 'select_document', but will not occur if the run mode is directly mapped (this holds the method to the current package I believe.) 'select_document', = \select_document, Thanks for the hint, that would have worked for me. But note that this part has changed in CGI::Application 2.6. It is now: # Process run mode! my $body = eval { $autoload_mode ? $self-$rmeth($rm) : $self-$rmeth()}; die Error executing run mode '$rm': $@ if $@; So, it will eval and die (in a way useless to me) in both cases. (2) You _might_ be able to modify the suggested code (in the above mailing list reference) to place that data INTO the hash, and then directly propagate that error. In my other post, I suggest : die ($@ . Error executing run mode '$rm'. Eval of code '$meth_call' resulted in error.) if ($@); For you to keep your hashref exception object intact, you could die ( $@ ) if ($@); Yes, this is what I do now. But I am not happy with overloading (and duplicating) the whole run() method to just change a single line. I really think the cleanest way is to have the additional callback method cgiapp_exception. === PATCH REQUEST # Process run mode! my $body = eval { $autoload_mode ? $self-$rmeth($rm) : $self-$rmeth()}; die $self-cgiapp_exception($rm, $@); Default would be sub cgiapp_exception{ my ($self, $rm, $exception) = @_; die Error executing run mode '$rm': $exception; } == Cory would have used sub cgiapp_exception{ my ($self, $rm, $exception) = @_; die $exception Error executing run mode '$rm'. ; } I would use sub cgiapp_exception{ my ($self, $rm, $exception) = @_; # exception handling } Jesse, can I please have this method ? I can pay with a postcard from Tokyo ;-) Cheers, Thilo PS: patch file for 2.6 attached cgiapp_exception.patch Description: application/text - Web Archive: http://www.mail-archive.com/cgiapp;lists.vm.com/ To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: RE: [cgiapp] exception handling?
Hi, I am using CGI::Application for all my CGI scripts now, and only have one issue with it at the moment: Exception handling. CGI::Application handles its own exceptions with a simple die(), but that's no reason you need to use die(). In your code you could call something completely different which outputs to STDERR anything you like. The thing is that I am not so much concerned with printing something to STDERR but with aborting whatever the program was doing and passing control to some other part of the program, that can handle the situation according to its needs. Since the code that dies has no idea what action would be appropriate to amend the situation (it will most likely be located in a completely different package, doing something like database access, not even aware of running under CGI at all) it can not just call a 'my_die()'. I believe exceptions (including simple 'die error43 ') are the best way to implement this kind of control flow. There is no need to modify the core CGI::Application base class to allow you to do this. Simply implement your own exception handling method and call that in places you would normally catch fatal exceptions. Since this handling method would want to handle all run-modes I think it is easiest to let any unresolved exception propagate all the way through by letting the run-mode die and having the eval-block (that is already there in CGI::Application) take care of it. If you create a custom parent class (a descendant of CGI-App which is a parent for all your applications) you could effect a change globally to all your applications: package My::CGI::Application; use base 'CGI::Application'; sub my_die { # Do something special } package My::Widget::Manager; use base 'My::CGI::Application'; sub some_run_mode { my_die(An error has occurred!); } In my case, it would be more like this: package My::Widget::Manager; use base 'My::CGI::Application'; sub some_run_mode { eval{ process_cgi_vars(); do_some_file_stuff(); do_some_database_stuff(); fill_template(); } my_die($@) if $@; } And every run_mode would have the same eval block ! (Wrapped into CGI::Application's eval block) I am reluctant to add special exception handling to CGI::Application now, because Perl itself has not yet implemented uniform exception handling. But replacing the original error message with Error executing run mode '$rm': $exception is already special handling. I would really appreciate the additional callback method, although I can see why the default implementation I provided (with dumping any refs) meets opposition. If that is not possible, how about just letting the original error/exception pass through? # Process run mode! my $body = eval { $autoload_mode ? $self-$rmeth($rm) :$self-$rmeth() }; warn Error executing run mode '$rm': $exception if $@; die $@ if $@; or just # Process run mode! my $body = $autoload_mode ? $self-$rmeth($rm) :$self-$rmeth(); In latter case I could implement my handler by overriding run() in the custom parent class for all my applications: package My::CGI::Application; use base 'CGI::Application'; sub run { my ($self, @args) = @_, eval{ $self::SUPER-run(@args) } $self-exception_handler($@) if $@; } Please excuse my insistence, Thilo Keine verlorenen Lotto-Quittungen, keine vergessenen Gewinne mehr! Beim WEB.DE Lottoservice: http://tippen2.web.de/?x=13 - Web Archive: http://www.mail-archive.com/cgiapp;lists.vm.com/ To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]