NAME

Jifty::Manual::Tutorial - Jifty 從零開始

DESCRIPTION

這份教學文件將�供建構第一個 jifty 應用程�所需�的技巧。

HOW TO

The requirements

é€™å°±æ˜¯ä½ éœ€è¦�安è£�的。

Installing Jifty

我們相當相信 DRY ( Don't Repeat Yourself ) 的原則,這是我們喜愛 Perl 與 CPAN 的一個很é‡�è¦�çš„åŽŸå› ã€‚

Jifty 使用了 CPAN 上許多令人驚奇的程�碼。他直接使用 60 多個來自 CPAN 的模組 。

大部分的套件都是跨平å�°ä¸”å�ªä»¥ Perl 寫æˆ�çš„æ¨¡çµ„ï¼Œä¸”èƒ½åœ¨ä½ å�¯å�–å¾— Perl 的任何平å�°ä¸Šè‰¯å¥½é�‹ä½œã€‚

æˆ‘å€‘èŠ±äº†å¾ˆé•·çš„ä¸€æ®µæ™‚é–“è®“æ‚¨èƒ½å¤ ä¸�用花上一整天的時間下載函å¼�庫以å�Šæ‰€æœ‰ç›¸é—œçš„套件。

Jifty 的安è£�程å¼�èƒ½å¤ è‡ªå‹•å�µæ¸¬æ‚¨æ©Ÿå™¨ä¸Šå°šæœªå®‰è£�的模組,並且直接下載並安è£�他們。

別擔心,Jifty 在更動之å‰�æ��é†’ä½ ã€‚

åœ¨å¤§å¤šæ•¸çš„ç³»çµ±ä¸Šï¼Œä½ å�¯ä»¥ä½¿ç”¨ Perl 所æ��供的 CPAN 模組來下載並且安è£� Jifty:

# perl -MCPAN -e"install Jifty"

å¦‚æžœä½ ä¸‹è¼‰äº† Jifty çš„ .tar.gz 檔,您å�¯ä»¥ä½¿ç”¨æ‰‹å‹•å®‰è£�:

# tar xzvf jifty-<version>.tgz
# cd jifty-<version>
# perl Makefile.PL
# make
# make test
# make install

我們會想è¦�知é�“如果單元測試沒有通é�Žçš„åŽŸå› ï¼Œå¦‚æžœæ‚¨é�‡åˆ°äº†é€™æ¨£çš„å•�題。 è«‹åŠ å…¥æˆ‘å€‘çš„ jifty-devel@lists.jifty.org ä¸¦å›žå ±ç›¸é—œçš„éŒ¯èª¤è¨Šæ�¯ã€‚ é—œæ–¼å¦‚ä½•åŠ å…¥æˆ‘å€‘ï¼Œè«‹å�ƒè¦‹ä¸‹æ–¹çš„ "GETTING HELP"

Setting up the Scaffolding

ä¸€æ—¦ä½ å®Œæˆ�了 Jifty 的安è£�ï¼Œä¾¿èƒ½é–‹å§‹æ§‹ç¯‰ä½ ç¬¬ä¸€ä»½ Jifty 應用程å¼�。

Jifty å°‡æ‰€æœ‰çš„äº‹æƒ…è¨­è¨ˆçš„ç›¸ç•¶ç°¡å–®ä½¿ç”¨ï¼Œä½ å�ªéœ€è¦�使用 Jifty æ��供的 jifty 命令列工具來啟動您的應用程å¼� ( 在您建構的應用程å¼�裡的 bin/ 資料夾內 )

請切æ�›åˆ°ä¸€å€‹ä¹¾æ·¨çš„ç›®éœ²åº•ä¸‹ä¾†å»ºç«‹ä½ çš„ Jifty 應用程å¼�。 ( Jifty 會為您建立å­�資料夾 ).

# jifty app --name MyWeblog
Creating new application MyWeblog
Creating directory lib
Creating directory lib/MyWeblog
Creating directory bin
Creating directory etc
Creating directory doc
Creating directory log
Creating directory var
Creating directory var/mason
Creating directory share
Creating directory share/po
Creating directory share/web
Creating directory share/web/templates
Creating directory share/web/static
Creating directory lib/MyWeblog/Model
Creating directory lib/MyWeblog/Action
Creating directory t
Creating configuration file MyWeblog/etc/config.yml

以下將�一解說。

bin

在 bin/ 資料夾內的便是 jifty, 是 Jifty 用來處� Jifty 指令的程� .

一些較é‡�è¦�的指令是 schema , 這個指令用來設置或更新您的資料庫。 å�ˆå¦‚指令 server , 這個指令將啟動ç�¨ç«‹çš„網é �伺æœ�器。 .

想知�其他 Jifty �供的指令,�執行:

jifty help
etc

Configuration files live in etc/, though if you don't have a config file, Jifty will supply some sane defaults.

doc

Jifty won't magically write your documentation for you, but when you write your docs, put them in doc/.

log

Jifty uses Log::Log4perl to configure its logging. By default, it dumps logs named server.log and error.log into the log directory.

share/web/templates

Jifty uses HTML::Mason as its primary templating system. Put your application's templates into share/web/templates/. Out of the box, Jifty comes with an application skeleton that it installs in share/web/templates/. This default application is a convenient way to get a basic application up and running quickly, but probably needs some customization as you build a more advanced application.

You can find where Perl stuck Jifty's default templates with:

perl -MJifty::Util -e 'print Jifty::Util->share_root'
share/web/static

Some nontrivial percentage of the stuff your web application serves out doesn't need to (or shouldn't) pass through your templating engine.

Just drop your static files into share/web/static/ and Jifty will serve them out if it can't find a template with the right name.

Out of the box, Jifty comes with a CSS style, Javascript libraries and a Pony. Look in share/web/static in the Jifty distribution, or in the same place Jifty stuck its default templates.

lib/MyWeblog

For a full treatment of the Jifty object model see Jifty::Manual::ObjectModel.

To build a basic Jifty application, you only need to worry about two sorts of classes, Models and Actions.

lib/MyWeblog/Model

The real base of your application lives in lib/ApplicationName/Model. Classes here define your application's data structures and how they relate to each other. Jifty will use your model classes to set up and upgrade your database's schema when it needs to.

lib/MyWeblog/Action

When we said you only need to worry about Models and Actions, we weren't telling the whole truth. Jifty will take care of basic database-interaction (CREATE, READ, UPDATE, DELETE) Actions for your Models, but they're there if you want to change anything.

t

Jifty starts off your application with a basic harness, but can't yet write all your tests for you. (It does, however, build simple tests for model classes you generate.)

var

Jifty stores cache files here while the server is running. You shouldn't ever have to touch this directory.

Building your data model

As you might imagine by the fact that this tutorial application is named MyWeblog, the example here is a simple weblog application. Future tutorials will add authentication, comments, and RSS and Atom feeds.

Posts

Weblogs tend to center around posts, so it's no surprise that the first model to create is the post:

# cd MyWeblog
# jifty model --name Post
Writing file /tmp/MyWeblog/lib/MyWeblog/Model/Post.pm
Writing file /tmp/MyWeblog/t/00-model-Post.t

Great! Now you have a Post model (not that it models anything yet).

Open lib/MyWeblog/Model/Post.pm in your favorite text editor.

You should see something like this:

use strict;
use warnings;

package MyWeblog::Model::Post;
use Jifty::DBI::Schema;

use MyWeblog::Record schema {

};

# Your model-specific methods go here.

1;

Now it's time to tell the model class about posts. Start by giving our post a body and a title. (In a future tutorial, the application will become fully folksonomy-compliant by adding a category and upgrading that category to a tags table.)

Position your cursor right after:

use MyWeblog::Record schema {

Add the lines:

column title =>
      type is 'text',
      label is 'Title',
      default is 'Untitled post';

column body => 
      type is 'text',
      label is 'Content',
      render_as 'Textarea';

Save your model class.

Setting up the database

Ok. It's time to initialize MyWeblog's database. By default, Jifty sets up your application with the SQLite database engine. If you'd rather use PostgreSQL or MySQL, you need to add some content to etc/config.yml. (See Jifty::Config for a bit more information).

# jifty schema --setup
INFO - Generating SQL for application MyWeblog...
INFO - Using MyWeblog::Model::Post, as it appears to be new.
INFO - Using Jifty::Model::Session, as it appears to be new.
INFO - Using Jifty::Model::Metadata, as it appears to be new.
INFO - Set up version 0.0.1, jifty version 0.80913
Jifty version 0.80913 up to date.
...
MyWeblog version 0.0.1 up to date.

Starting the Jifty application server

Ok. You have a working, if simplistic, application. Start up a webserver and have a look around. Be sure to check out the AJAX-enabled administrative UI, the online documentation browser, and the Pony.

# ./bin/jifty server
INFO - You can connect to your server at http://localhost:8888/

Please always run this command at the root directory of your Jifty applications, or you'll be caught by a lot of errors.

For many platforms, a simple "jifty server" command works too. :)

Building a user interface

The administrative web does give you everything you need to work with your application's data, but it's not much of a weblog.

Posting

Create a page to post a new weblog entry:

# cd share/web/templates/

Open a new file called post in your text editor. Make it look like this:

<%init>
my $action = Jifty->web->new_action(class => 'CreatePost');
</%init>

<&| /_elements/wrapper, title => "Post to your weblog" &>
<% Jifty->web->form->start() %>
<% Jifty->web->form->next_page( url => '/') %>
<% $action->form_field('title') %>
<% $action->form_field('body') %>
<% Jifty->web->form->submit( label => 'Post' ) %>
<% Jifty->web->form->end() %>
</&>

Yes, it's a template file in HTML::Mason syntax. If you're not familiar with Mason, we recommend you to consult its online documentation for details. Mason templates should start in the first column of the file. Particularly importantly, the <%init> and </%init> blocks must be flush left.

Viewing

It's really easy to get a basic listing of entries and a little bit more complex to get a pretty AJAXified paged list. Here's how to do both; you can decide which one works best for you.

(If you cut and paste the code in the examples below, make sure it's lined up in column 1, or it won't work.)

The quick and dirty way

Open a new file called index.html in the share/web/templates directory in your text editor. (Your webserver will treat the URL /index.html as the default page for your site). Make it look like this:

<%init>
my $posts = MyWeblog::Model::PostCollection->new();
$posts->unlimit();
</%init>

<&| /_elements/wrapper, title => Jifty->config->framework('ApplicationName') &>
<dl>
% while (my $post = $posts->next) {
 <dt><% $post->title %></dt>
 <dd><% $post->body %></dd>
% }
</dl>
</&>

(Make sure to remove that leading whitespace!)

The complex way that gets you lots of cool toys

The complex way involves using one of Jifty's advanced features: Page regions. These regions let your application reload page sections independently, either using AJAX on modern high-end browsers or regular GET requests with downlevel browsers such as lynx, w3m, or the browser on your mobile phone.

The downside of this approach is that each separate region needs to live in its own fragment file.

The complex way starts off about the same as the easy way. Open a new file called share/web/templates/index.html in your text editor. Fill it with this:

<&| /_elements/wrapper, title => Jifty->config->framework('ApplicationName') &>

<% Jifty->web->region(name => "myweblog-posts",
                      path => "/fragments/page_of_posts") %>
</&>

If you're on the ball, you've probably already guessed that you need to create a file called share/web/templates/fragments/page_of_posts containing:

<%args>
$page => 1
</%args>
<%init>
my $posts = MyWeblog::Model::PostCollection->new();
$posts->unlimit();
$posts->set_page_info( current_page => $page,
                       per_page     => 15
                     );
$m->out("No items found.") if ($posts->pager->total_entries == 0);

</%init>
% if ($posts->pager->last_page > 1) {
   Page <% $page %> of <% $posts->pager->last_page %>
% }
<dl class="list">
% while (my $post = $posts->next) {
 <dt><% $post->title %></dt>
 <dd><% $post->body %></dd>
% }
</dl>

% if ($posts->pager->previous_page) {
  <% Jifty->web->link( label => "Previous Page", onclick => { args => { page => $posts->pager->previous_page } } ) %>
% }
% if ($posts->pager->next_page) {
  <% Jifty->web->link( label => "Next Page", onclick => { args => { page => $posts->pager->next_page } } ) %>
% }

Now fire up your Jifty webserver again. Go create a post by browsing /post on your webserver. Create more than 15 posts, and notice how Jifty gives you AJAX Next Page and Previous Page buttons for you. Turn off javascript or view the page in lynx, and notice how the AJAX automatically falls-back to page loads for you. All for free, thanks to Jifty!

Hey, where'd that class come from?

If you're paying attention, you may have wondered about MyWeblog::Model::PostCollection, since there's no file called PostCollection.pm. By default, Jifty uses Jifty::ClassLoader to auto-generate a bunch of classes for you. Of course, you can override these definitions if you like. See Jifty::ClassLoader for more details.

Of course, having to remember the URL to get to the posting page is a bit annoying. To get a Post button in the menu, you need to override the default menus.

Jifty's default menus live in _elements/nav in the default application template (along with the Pony). For now, override _elements/nav. (We're working on ways to make this better.)

Inside your applications share/web/templates directory, create a directory called _elements.

mkdir share/web/templates/_elements

You may want to start with the stock jifty template, in which case you only need to add the $top->child( Post... part

cat $(perl -MJifty::Util -e 'print Jifty::Util->share_root' \
  )/web/templates/_elements/nav > share/web/templates/_elements/nav

Otherwise, inside _elements, open up a new file called nav in your text editor and insert:

<%init>
my $top = Jifty->web->navigation;
$top->child( Home => url => "/");
$top->child( Post => url => "/post", 
                     label => "Post Article");
</%init>

For more information about the menu system, see the documentation in Jifty::Web::Menu.

That's it!

That's just about everything you need to get started building Jifty applications. We're working hard to make Jifty even easier to use and to obsolete the hard bits of this tutorial as quickly as we can.

Please join us on the jifty-devel mailing list to talk about how you're using Jifty or what you find difficult or hard to use about it.

MORE TUTORIALS

GETTING HELP

Online Help

The jifty command-line application comes with builtin help.

jifty help

jifty help <command>

If your server is running with administration mode enabled (the configuration file AdminMode setting is missing or non-zero), you can click the "Online Docs" link in your browser for an extensive list of per-module Jifty documentation.

Joining the mailing list

jifty-devel@lists.jifty.org is where we discuss how we're building Jifty, what we're having trouble with and so on.

To join the list, send mail to jifty-devel-subscribe@lists.jifty.org.

Browsing the wiki

We have a wiki! (Actually, the wiki is Jifty's primary website)

Please visit http://jifty.org/, browse and contribute.

The wiki is powered by Wifty, a Wiki built on Jifty. Its code is freely available from the jifty subversion repository.

REPORTING BUGS

At this incredibly early stage in its life, please report bugs in Jifty to jifty-devel@lists.jifty.org.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 3:

Non-ASCII character seen before =encoding in '從零開始'. Assuming CP1252