用户
 找回密码
 入住 CI 中国社区
搜索
查看: 9471|回复: 6
收起左侧

[分享][翻译]官方教程第四篇:Creating a Virtual Database Page System

[复制链接]
发表于 2007-12-27 09:44:56 | 显示全部楼层 |阅读模式
说明:
1、第一次尝试翻译资料,有些词自己也看不懂,我就会把原文单词附上。
2、翻译是以段为单位,并且没有严格的按照字面顺序来翻译,但并不影响在原文中找到相应的词,只是修改了一下义节顺序以符合中文习惯。
3、对于我自己的一些说明而非原文翻译的文字我都加上一个标记[注],如果我写错了,还请指正,不要责怪原作者。
4、原文中有些代码的前后并未添加 <?php ?> 标签,是我自己为了在编辑器下面高亮php语法加上去的。
5、原文地址:http://kohanaphp.com/tutorials/page.html

补充一下:这是官方教程的第四篇,前面两篇是视频的,我已经发了出来,第三篇过于简单,我就不翻译了。尽快放出第五篇教程的翻译,呵呵:)

Creating a Virtual Database Page System
创建一个模型化的(virtual)数据库页面系统

Please note that this tutorial assumes that the user has a bit of experience setting up Kohana 2 websites.
请注意,这个教程假定学习者有一定的使用 Kohana 2 架设网站的经验。

This tutorial level is Medium to Advanced.
这个教程的级别是中等到高级。

Here we will show a short example of many of the features of Kohana:
这里我们将展示一个拥有很多 Kohana 特性的简短案例。

·Setting up templates using Views within Views
·Create a virtual, database storage page system
·Create a simple authentication library for admins to edit pages
·通过使用VWV(views within views)设置模板
·创建一个模型化的数据库存储页面系统
·为实现管理员编辑页面而创建一个简单的身份认证程序(库)

Starting Out
开始
To start we will create a file to hold our controller:
我们以创建一个装载控制器的文件开始:
PHP复制代码
 
application/controllers/page.php
<?php
class Page_Controller extends Controller {
 
        function __construct()
        {
                parent::__construct();
        }
 
        function index()
        {
 
        }
}
?>
 
复制代码

[注] __construct() 的作用是实例化三个类,Loader() ,URI() , Input() ,创建三个对象。以后看到的 $this->XXX->XX() 的中间同名部分就来源于此。具体的看 /system/libraries/Controller.php

Next we will set up the files and code to run our views using an area for a header, content and footer:
接下来我们要创建一些文件和代码通过设置头部、内容、底部区域来运行我们的样式。
[注]这里的样式不是css,更趋向于类似于外观主题模板的意思。


application/views/layout.php
PHP复制代码
 
<?= $header ?>
<?= $content ?>
<?= $footer ?>
 
复制代码



application/views/header.php
PHP复制代码
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
        <head>
                <title><?=$title?></title>
                <?=html::stylesheet('css/layout.css')?><!--[注]生成css文件的链接-->
                <?=html::stylesheet('css/style.css')?>
                <?=html::stylesheet('css/menu.css')?>
 
                <?=html::script('js/jquery.js')?><!--[注]生成js文件的链接-->
                <?=html::script('js/jquery.livequery.js')?>
                <?=html::script('js/effects.js')?>
        </head>
        <body>
                <div id="menu">
                        <ul class="nav">
                                <?php foreach ($menu["menu"] as $url => $title):?><!--[注]生成主菜单和次级菜单的链接-->
                                <li><?=html::anchor($url, htmlentities($title))?><!--[注]这个htmlentities() 将所有$title中的字符都转义成能通过浏览器显示的形式,比如"<" 转换成 < -->
                                        <?php if (isset($menu["submenu"][$url])):?><ul>
                                                <?php foreach ($menu["submenu"][$url] as $child_url => $title):?>
                                                <li><?=html::anchor($child_url, htmlentities($title))?></li>
                                                <?php endforeach; ?>
                                        </ul><?php endif; ?>
                                </li><?php endforeach; ?>
                        </ul>
                </div>
                <div id="content">
 
复制代码



application/views/footer.php
PHP复制代码
 
 
<?php
 
$no_edit = array("add", "edit", "details");
 
/* Set this page for the login redirections */
/*设置这个页面为登录后跳转到的页面*/
if ($this->uri->segment(1) != "user" and !in_array($this->uri->segment(1), $no_edit))      //[注]判断第一个字符段不是user且不属于操作方式
{
        $this_page = $_SERVER["REQUEST_URI"];                       //[注]这里应该是提交常规浏览页面的地址,即用户只能浏览该网页
        $this->session->set(array("last_page" => $this_page));      //[注]在session中记录当前页的uri
}
if ($this->session->get("loggedin") and !in_array($this->uri->segment(1), $no_edit))       //[注]判断用户已登陆且第一个字符段不属于操作方式
        echo html::anchor((($this->uri->rsegment(1) != '') ? $this->uri->rsegment(1) : 'page') . '/edit/' . $this->uri->segment(1) . (($this->uri->segment(2) !== false) ? ('/' . $this->uri->segment(2)) : ''), 'Edit this page');    //[注]返回一个指向编辑页面的伪静态地址的链接,最终地址应该是 [/page][$this->uri->rsgement(1)]/edit/page_level1_id[/page_level2_id] 形式,具体的我也没看懂$this->uri->rsgement(1)的意义是什么,是 “user”么?。
 
?>
</div>
<div id="footer">
        <p>© Copyright 2007 Kohana</p>
</div>
 
<?php if (!$this->session->get("loggedin")):?><h3><?=html::anchor("user/login", "LOGIN")?><?php endif; ?>
<?php if ($this->session->get("loggedin")):?><h3><?=html::anchor("user/logout", "Logout")?></h3>
        <h3><?=html::anchor("page/list_pages", "Page Administration")?></h3><?php endif; ?>
</body>
</html>
 
 
复制代码


Just glance over those files, they contain some things we will finalize later in the tutorial.
看看那些文件,它们包含了一些我们将在此次教程最后计划完成的的东西。
Next we will set up the view for displaying our main content:
接下来我们要设置显示我们主体内容的模板。

application/views/page/index.php
PHP复制代码
 
 
<?=$content->content?>
 
 
复制代码



Wasn't that easy? ;)
它不是很简单么?:)
Now that we have all the view files set up, we will set up our controller to use them. This will use Views in Views to create a basic templating system:
现在我们已经设置好了所有的模板文件,我们接着要设置控制器来使用他们。这会使用到嵌套样式来创建一个基础的模板系统:

application/controllers/page.php
PHP复制代码
 
<?
function index()
{
        $this->layout->header = $this->load->view("header", array_merge($this->header, array("title" => $page->title)));
        $this->layout->content = $this->load->view("page/index", array("content" => ""));
        $this->layout->footer = $this->load->view("footer.php");
        $this->layout->render(TRUE);
//[注]关于layout的作用,我还不是很明了,呵呵。是将几个模板部件整合到一个模板文件中么?再有就是layout文件放在什么地方?
//[注2]原来是文件的名字,真是不好意思。。前面有一个文件名为layout.php
}
?>
 
复制代码

[ 本帖最后由 cchaha 于 2007-12-27 10:16 编辑 ]
 楼主| 发表于 2007-12-27 09:46:01 | 显示全部楼层
一帖居然发不完,再来一贴。。

Here we are just passing an empty page into the view, so we will have a pretty boring blank white page. This actually won't work yet, since we haven't set any pages for the menus that you see in the header file. We will get to that in a bit =)
这里我们只是添加了一个空页面到模板中。所以我们得到了一个确实枯燥无味的白屏页面,但是我们也确实没有往你在头部文件中看到的菜单里设置任何页面[链接]。我们一会就把它加上去=)
We need to set up a pages table in our database, which you can do with the following SQL:
我们要在数据库中设置一个页面的表,通过下面的SQL代码实现:

SQL复制代码
 
 
CREATE TABLE `pages` (
`id` mediumint( 9 ) NOT NULL AUTO_INCREMENT ,
`page_name` VARCHAR( 100 ) NOT NULL ,
`title` VARCHAR( 255 ) NOT NULL ,
`content` longtext NOT NULL ,
`menu` tinyint( 1 ) NOT NULL DEFAULT '0',
`filename` VARCHAR( 255 ) NOT NULL ,
`order` mediumint( 9 ) NOT NULL ,
`date` INT( 11 ) NOT NULL ,
`child_of` mediumint( 9 ) NOT NULL DEFAULT '0',
PRIMARY KEY ( `id` ) ,
UNIQUE KEY `filename` ( `filename` )
) ENGINE = MYISAM DEFAULT CHARSET = utf8 PACK_KEYS =0;
 
INSERT INTO `pages` ( `id` , `page_name` , `title` , `content` , `menu` , `filename` , `order` , `date` , `child_of` )
VALUES (NULL , 'Home', 'Home', 'Welcome', '0', 'index', '1', '0', '0'
);
 
 
复制代码

[注]这里可能需要解释一下的是menu和filename,以及为什么后面插入的date值为0。menu表示其是否为菜单,这里只有一级菜单,filename可能是用来表示链接的名字,data就不好理解了。。下次想到了再写。

Next we will set up a model to grab some pages out of our database and feed them into our controller.
接下来我们将设置一个模块从我们的数据库中抓取出页面并把它们输送给控制器。
application/models/page.php
PHP复制代码
 
<?php
class Page_Model extends Model {
 
        function get_page_id($page_name)
        {
                $query = $this->db->from("pages")->where("filename", $page_name)->get();
 
                return (count($query) > 0) ? $query->current()->id : 0;
        }
 
        function get_page($page)
        {
                if (isset($page["child"]))
                {
                        $child_id = $this->get_page_id($page["parent"]);
                        $query = $this->db->from("pages")->where(array("filename" => $page["child"], "child_of" => $child_id))->limit("1")->get();    
                }
                else
                {
                        $query = $this->db->from("pages")->where("filename", $page["parent"])->limit("1")->get();
                }
 
                /* Check to see if the page exists */
                /*检查页面是否存在*/
                if (count($query) > 0)
                        return $query->current();
                else
                        return false;
        }
?>
 
 
复制代码

[注]以上代码的用途是通过给定的filename找到其$page。
[注2]在文章的接近尾声的地方才提出$page["child"]是怎么来的,我在这卡了半天。还是不要太看重眼前不懂的地方,也许走一段就有答案了呢。

We will also add in some code into our controller constructor to fetch what page was called from the browser. Also, we will add the main view load to the constructor.
我们同样将添加一些代码到我们的控制器构架中以获取浏览器需要访问的页面。
application/controllers/page.php
PHP复制代码
 
<?php
function __construct()
{
        parent::__construct();
 
        $this->load->model("page");
        $this->header = array("menu" => $this->page->get_menu(), "title" => "example.com :: Home");
 
        /* Get the page (page or folder/page) */
        /* 获得页面的文件夹和页面文件[注]只是伪静态的文件夹和页面文件,并不是实际的文件夹和页面关系*/
        $base = ($this->uri->segment(2) == "edit") ? 2 : 0; //[注]如果uri的第二个字段是edit的则从第三个字段开始判断,如果第二个字段不是edit,说明还在浏览样式的页面下,所以从第一个字段开始判断
 
        if ($this->uri->segment((1+$base)) !== false && $this->uri->segment((2+$base)) !== false) // This is a sub page 如果uri后面有两个个字段,说明是次级页面
                $this->location = array("parent" => $this->uri->segment((1+$base)), "child" => $this->uri->segment((2+$base)));
        else if ($this->uri->segment((1+$base)) !== false && $this->uri->segment((2+$base)) === false) // This is a main page 如果uri后面只有一个字段,说明是主页面
                $this->location = array("parent" => $this->uri->segment((1+$base)));
        else // This is the home page  如果后面什么都没有,那它就是首页面
                $this->location = array("parent" => "index");
 
        $this->layout = $this->load->view("layout");
 
        $this->layout->footer = ($this->input->get("no_header")) ? "" : $this->load->view("footer"); //[注]如果不输出footer的话也不输出footer。
}
?>
 
复制代码



In this example, our site will support folder/subpage.html layout, and no deeper. You could expand this system to allow for an infinite level of "folders" if you wish. We will also support having the user add a GET parameter to not load the header and footer, useful for loading pages with ajax.
在这个例子中,我们的站点支持 文件夹/文件 的显示, 而且没有更深的目录结构。只要你愿意你可以扩展这个系统至无限级文件夹,我们同样支持了用户通过增加GET参数来禁止家在头部和底部,这样有利于通过ajax加载文件。
Now we will add this support into the index function:
现在我们增加这个支持到index函数中:

PHP复制代码
 
<?php
function index()
{
        if ($page = $this->page->get_page($this->location))
        {
                if (!$this->input->get("no_header"))
                        $this->layout->header = $this->load->view("header", array_merge($this->header, array("title" => "radd-cpa.org :: " . $page->title)));
                else
                        $this->layout->header = "";
                $this->layout->content = $this->load->view("page/index", array("page" => $page));
 
                $this->layout->render(TRUE);
        }
        else
                Kohana::show_404();
}
?>
 
复制代码



Here we load the page from the model, and also cleverly show a 404 status if the page doesn't exist (the database result would be FALSE).
这里我们通过模块加载了一个页面,而且在页面不能找到(数据库结果为FALSE)时聪明的的展示一个404状态。
I have provided a whole application for you to look at, pick apart or use on your own projects.
我一进提你正在看的供了整个应用,自己截取一部分或者直接整体应用到你自己的项目中吧。
Feel free to send any changes or improvements back to me at jeremy.bush@kohanaphp.com.
想通过jeremy.bush@kohanaphp.com通知我做了改动或者提升就随时发过来吧。
It includes a basic authentication system for administrating pages, a FCKeditor for easy editing of pages, and some basic HTML views to get you going.
它包含了基本的页面管理的验证系统,FCK编辑器和基本的HTML模板就自己弄吧。
Download Tutorial Files
教程中使用的文件下载地址:http://kohanaphp.com/tutorials/download/page_tutorial.zip

评分

参与人数 1威望 +5 收起 理由
Hex + 5

查看全部评分

发表于 2007-12-27 10:13:11 | 显示全部楼层
这。。。。。简直太强了!楼主为 Kohana 初学者有奉献了一份大餐!
发表于 2007-12-27 13:34:05 | 显示全部楼层
Codeigniter快成了kohana的天下啦。。。
发表于 2007-12-27 13:53:43 | 显示全部楼层
本是同根生,相煎何太急。
发表于 2007-12-27 13:56:54 | 显示全部楼层
还没学会走。。就想飞上天。。
发表于 2009-3-18 15:42:45 | 显示全部楼层
讨论 Kohana PHP 技术的QQ群:5898732
Kohana 是一款纯 PHP5 的框架,基于 MVC 模式开发, 它的特点就是高安全性,轻量级代码,容易使用。

本版积分规则