Dive into Dancer’s code: core and extensions

The discussion that is rising these days about frameworks and libraries reminds me I did not even take the time to talk about the last version of Dancer.
I should have, hence this post.

Last version of Dancer, 1.130, is the first version which is “plugin-aware”.
That means since 1.130 anyone can write their own template, logger or session engine and rock the app by just setting the appropriate value to the corresponding setting.

The plugins that existed before the split have been extracted from the core distribution in order to be shipped separately, that’s much clean and makes more sense that way:

If you have a template, logger or session engine you’d like to see in Dancer’s ecosystem, I invite you to take a look at the corresponding interfaces you have to implement, it’s pretty straight forward.

The concept is pretty easy, basically, here are the steps to follow to add a new engine:

  • choose a setting name that is available for template, session or logger, according to what you’re doing.
  • implement the interface of the engine you like (Dancer::Template::Abstract, Dancer::Session::Abstract, Dancer::Logger::Abstract)
  • Name your class with a camelized version of the setting name

Here is an example, let’s say you have a great template engine you’d love to use for rendering your views in your Dancer app, let’s name it “HTML::IronMark”.

  • First of all, create Dancer::Template::Ironmark which implements the interface Dancer::Template::Abstract
  • Then change the setting template to "ironmark"

And well, you’re done. This is pretty much the same job for logger and session engines.

Feel free to contact me if you want to write your own and need more precisions.

620 views · Tags: , · Both comments and pings are currently closed.

7 Comments

  1. Nice work.

    Did I tell you that Plack 1.0 / PSGI 1.1 (in dev process, close to be done) are defining interfaces for Session and Logger though? They are all accessible through psgix.session and psgix.logger in $env, so if you go PSGI all the way, we wouldn’t need to duplicate our effort of writing all of those session managers and Logger extensions for each framework.

    At least you can create Dancer::Session and Dancer::Logger subclasses to interface with those $env values, so if you run Dancer in the psgi mode, users can chose whatever sessions and loggers that are supported as Plack middleware.

    (Well, Templating would be another thing which would be interesting to add to Plack middleware stack so most frameworks can share, but that’s another story :))

    You’ve been mentioning Sinatra to defend Dancer a lot, which is reasonable, but if you really want to clone Sinatra, you should go Plack all the way, like Sinatra does for Rack :)

  2. @miyagawa: You’re right, my work on Dancer is heavily based/inspired on Sinatra, from the Ruby world. You’re also right when you say that Sinatra does rely entirely on Rack. This being said, I have some divergence with Sinatra that I’d like to explain.

    But first, I want to underline that I’m a big fan of PSGI/Plack, this is maybe one of the best thing that happened in the Perl ecosystem regarding web applications.

    My point of view on Dancer is that it should behave like a cameleon, I see Dancer as a step-by-step framework that can be used alone at first, and will evolve with the developer according to their needs. That means of course, relying on Plack when necessary.

    But I still want that a Dancer app can be developed without installing Plack. This should be an option for the developer, not a development-dependency. I hope you can see what I mean.

    There is absolutely nothing against Plack here, but more something about how can I use the goodness of PSGI/Plack, provide it to my users and still, let them discover/use Dancer as a standalone framework if they like.

    I could say that’s a matter of user-freedom, in a way.

    On the other hand, as I said, Plack is a kickass rock to build upon, and be sure as soon as Plack provides logger and session support, I’ll write the corresponding Dancer classes. Then on PSGI mode, a Dancer app will be able (or may defaults to) Plack::* engines.

    I think both approaches can coexist.

  3. Yes I understand what you mean. I’m *NOT* saying Dancer should depend on Plack and do nothing else. It makes sense to have a development option without relying on Plack, but can use the full Plack/PSGI middleware stack if developers want to. Perfectly reasonable, especially considering Plack isn’t 1.0 yet.

    And yeah, having Dancer logger/session adapters and even default to Plack backends in PSGI mode sounds like an excellent solution.

    The great thing about PSGI/Plack is, though, while using Plack means you go PSGI-only, the other way round is not necessarily true. i.e. You can still implement everything to interface with PSGI, without relying on Plack at all. (examples are Web::Simple, or CGI::Application::PSGI)

    So one thing you can do in the near future, even without waiting for Plack 1.0, is to update the Dancer::Handler::Standalone to still use HTTP::Server::Simple but run the app in an PSGI mode, which is probably a modified version of Plack::Server::ServerSimple. Since your standalone server (Handler::Standalone) is HTTP::Server::Simple, the code change should be fairly minimal. And that wouldn’t add any new dependencies and developers can run Dancer app without installing Plack.

  4. OK, I’m glad we share a common view here. Your idea regarding supporting PSGI even without depending on Plack makes sense, but I’m not sure I follow you on the technical details.

    What do you mean by saying “update the Dancer::Handler::Standalone to still use HTTP::Server::Simple but run the app in an PSGI mode” ? I’m not sure I see what’s behind this idea.

    Is it about supporting all PSGI $env keys, or is it something more than that?

    Thanks a lot for the precisions.

  5. Yeah, your Dancer::Request accepts PSGI $env, which is good, but Dancer::Handler::Standalone doesn’t use that interface but instead accepts CGI.pm object by using HTTP::Server::Simple::CGI. You can just eliminate this abstraction by writing your own HTTP::Server::Simple-based PSGI handler (just like Plack::Server::ServerSimple but without Plack dependency).

    The change would not really be huge — since you already abstract out the Standalone – PSGI difference in some way. The proposal is to step the abstraction further down to the lower layer (i.e. PSGI).

    The benefit is that the developers can assume it’s always running in PSGI mode and has access to PSGI $env. There won’t be any gotchas like “This plugin only works / doesn’t work if you run in PSGI mode” etc.

    I’m happy to help — actually I plan to ship the HTTP::Server::Simple::PSGI which doesn’t depend on Plack at all.

  6. HTTP::Server::Simple::PSGI sounds pretty good. I like that idea. If I can help in a way or another, tell me!

  7. [...] my last post about Dancer, Tatsuiko Miyagawa suggested to build Dancer's standalone server upon a PSGI-aware [...]

Get Adobe Flash playerPlugin by wpburn.com wordpress themes