NAME

YATT::Lite::WebMVC0::SiteApp - PSGI Handler for yatt

SYNOPSIS

# In app.psgi

use FindBin;
use YATT::Lite::WebMVC0::SiteApp -as_base;
use YATT::Lite qw/Entity *CON/;

return do {

  my $site = MY->new(doc_root => "$FindBin::Bin/html");

  #----- You can define entities here. ----
  Entity session => sub {
    my ($this, $key) = @_;
    my $sess = $CON->get_session
      or return;
    $sess->param($key);
  };

  if (YATT::Lite::Factory->want_object) {

    # When app.psgi is loaded from yatt support scripts(eg. yatt lint),
    # return bare object, not app.

    $site;

  } else {

    # Otherwise, normal PSGI. You can use Plack::Builder and/or middleware.

    $site->to_app;
  }
};

DESCRIPTION

SiteApp is a Factory of DirApp, which is a web specific subclass of YATT::Lite.

SiteApp takes a template directory tree at startup and becomes a PSGI application.

When SiteApp called for incoming request, it first determins a sub-directory for the request. Then SiteApp looks for DirApp from own cache, load/build it when necessary, and finally invoke DirApp to handle do rest of work.

CONFIGS

SiteApp accepts YATT::Lite::Object style configurations.

doc_root

Document root of this PSGI application. *.yatt should be placed under this. Usually, $FindBin::Bin/html

app_ns

Namespace of per-directory YATT::Lite class. Default is MyYATT. This will also be used as a base class of each YATT::Lite instances. This class will be loaded at startup (but can be missing). If it exists, it must be a subclass of YATT::Lite.

app_root

The application directory where app.psgi lives in. Sometime omissible, but recommended to set as $FindBin::Bin.

app_base

Base DirApp for all DirApp under doc_root. A.k.a inheritance of app-directory. Omissible. Usually, $FindBin::Bin/ytmpl.

site_prefix

If your app.psgi is located under subpath, specify this. You can refer this from *.yatt via &yatt:site_prefix();.

header_charset

Default charset for HTTP response headers. Default is utf-8.

tmpl_encoding, output_encoding

Encoding of *.yatt and HTTP response body, respectively.

XXX: should note about widechars....

no_nested_query

By default, yatt turns specific parameters into hashes/arrays like PHP and Ruby on Rails. This feature is useful(I hope), but is experimental. So if you don't want this feature, turn this config on.

psgi_static

Requests other than *.yatt, *.ytmpl, *.ydo are passed to this PSGI app. Default is:

Plack::App::File->new(root => $self->{cf_doc_root})->to_app

backend

Room for your Model instance. If it is given and it has startup method is implemented, $backend->startup($siteapp, @all_dirapps) will be called when prepare_app.

METHODS

call($env)

PSGI entry function. SiteApp uses $env as following:

PATH_TRANSLATED, REDIRECT_STATUS

If $env->{REDIRECT_STATUS} is 200 and has non empty $env->{PATH_TRANSLATED}, yatt tries to serve specified path.

PATH_INFO

Otherwise, yatt examines $env->{PATH_INFO} under doc_root and app_base, in this order.

prepare_app

PSGI startup hook.

render($path_info, $args)

Aid for batch execution.

make_connection($parent_fh, @config)

Build helper for YATT::Lite::WebMVC0::Connection object. $parent_fh can be undef. If specified, $con->flush will flush buffered contents to $parent_fh.

HOOKS

before_dirhandler($dirapp, $connection, $filename)

ENTITY FUNCTIONS

SiteApp registers following entity functions (usable in every template as &yatt:NAME(ARGS);). This section covers URL-related ones. Most of them delegate to the same-named method of $CON.

URL builders

Recommended way to build app-internal links. *_path returns a path, *_url returns an absolute url, and both respect the mount point of the site. See "URL BUILDING METHODS" in YATT::Lite::WebMVC0::Connection for details.

<a href="&yatt:site_path(/admin/);">admin</a>
<a href="&yatt:site_path(/list,[page,2]);">page 2</a>

<a href="&yatt:current_path([page,2]);">page 2 of this page</a>

&yatt:site_url(/confirm);   (absolute; for emails etc.)
&yatt:current_url();
&yatt:site_path(PATH,QUERY);
&yatt:site_url(PATH,QUERY);
&yatt:current_path(QUERY);
&yatt:current_url(QUERY);

QUERY is optional and must be [key,value,...] array form.

Redirect

&yatt:raise_redirect(URL);
&yatt:redirect(URL);

Same as $CON->raise_redirect. Html made so far is discarded and the rendering stops there. See "REDIRECT" in YATT::Lite::WebMVC0::Connection.

Location inspection

These entities answer where this page is served. As a general rule, lowercase entities return yatt-normalized values and are recommended; UPPERCASE ones return raw PSGI env values as-is (mainly for debugging).

Suppose the app is deployed at /myapp via Apache Action + AddHandler (so raw SCRIPT_NAME contains the handler script path) behind a reverse proxy which sets X-Forwarded-Proto: https, and https://example.com/myapp/auth/test?q=1 is served by auth/test.yatt:

&yatt:script_name();    /myapp
&yatt:SCRIPT_NAME();    /myapp/cgi-bin/runplack.cgi

&yatt:script_dir();     /myapp/

&yatt:script_uri();     https://example.com/myapp/auth/test
&yatt:SCRIPT_URI();     http://example.com/myapp/auth/test

&yatt:script_url();     /myapp/auth/test
&yatt:SCRIPT_URL();     /myapp/auth/test

&yatt:dir_location();   /myapp/auth/
&yatt:file_location();  /myapp/auth/test
&yatt:page_location();  /myapp/auth/test

&yatt:absrequest();     /auth/test
&yatt:abspath();        /auth/test.yatt

&yatt:request_uri();    /myapp/auth/test?q=1
&yatt:path_info();      /auth/test
&yatt:script_name();

The mount point of the site, without trailing / ($env->{'yatt.script_name'} - normalized SCRIPT_NAME; handler artifacts of Apache Action mapping are trimmed). The most basic building block for path abstraction. Note: this usually equals to &yatt:site_prefix(); (explicit "site_prefix" config wins if given).

&yatt:script_dir();

script_name + /.

&yatt:script_uri();

Absolute url of the current page. Unlike raw SCRIPT_URI, this respects X-Forwarded-Proto (GH-205).

&yatt:script_url();

Path-only version of script_uri.

&yatt:dir_location(); &yatt:file_location(); &yatt:page_location();

Mount-prefix aware location of the current directory / page. file_location follows how the request spelled the file name (with/without extension), while page_location is always the canonical (extension-less) form. Both omit the file name for index.yatt requests. See "LOCATION INSPECTION METHODS" in YATT::Lite::WebMVC0::Connection.

&yatt:abspath();

location + file (physical file name), without mount prefix.

&yatt:absrequest();

REQUEST_URI minus script_name, query string stripped. Since REQUEST_URI typically does not contain index.yatt, this is not suitable to get the physical file name.

&yatt:is_current_file(PATH); &yatt:is_current_page(PAGE);

Current page predicates, useful for navigation highlighting.

&yatt:path_info(); &yatt:request_uri(); &yatt:script_filename();

Raw PATH_INFO / REQUEST_URI / SCRIPT_FILENAME.

SEE ALSO

YATT::Lite::WebMVC0::Connection, YATT::Lite::WebMVC0::DirApp, YATT::Lite