Zend Framework教程-Zend_Layout-布局\助手Layout

一、作用

布局的作用和模版的作用类似。可以认为是把网站通用、公共的部分拿出来作为通用的页面框架。例如一个基本的web页面,可能页面的头和尾都是一样,不一样的可能只是内容body部分不一样,可以把公共的部分做成模版。不仅可以提高开发效率,也为后期的维护带来方便。

二、使用

这里举一个简单的例子。

首先用zend studio创建一个基本的zend framework项目:layout_demo1

结构大概如下“

├─.settings
├─application
│  ├─configs
│  ├─controllers
│  ├─models
│  └─views
│      ├─helpers
│      └─scripts
│          ├─error
│          └─index
├─docs
├─library
├─public
└─tests
    ├─application
    │  └─controllers
    └─library

1.加入layout功能:

应用配置文件/layout_demo2/application/configs/application.ini,加入如下配置

resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.frontController.params.displayExceptions = 0


resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"
[staging : production]


2.相应的目录和布局模版文件 /layout_demo2/application/layouts/scripts/layout.phtml

├─application
│  ├─configs
│  ├─controllers
│  ├─layouts
│  │  └─scripts
│  ├─models
│  └─views

layout.html类似如下:

<!doctype html>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
		<title>my app</title>
		<body>
			<div id="header">
				header
			</div>
			<div id="content">
				<?php echo $this -> layout() -> content;?>
			</div>
			<div id="footer">
				header
			</div>
		</body>
</html>

这里的

<?php echo $this -> layout() -> content;?>

是比较重要的。表示此处为布局的内容,也就是会动态变化的地方。


这样,运行一下程序

www.localzend.com/layout_demo1/public/

生成的html源码如下

<!doctype html>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
		<title>my app</title>
		<body>
			<div id="header">
				header
			</div>
			<div id="content">
				<style>
    a:link,
    a:visited
    {
        color: #0398CA;
    }

    span#zf-name
    {
        color: #91BE3F;
    }

    div#welcome
    {
        color: #FFFFFF;
        background-image: url(http://framework.zend.com/images/bkg_header.jpg);
        width:  600px;
        height: 400px;
        border: 2px solid #444444;
        overflow: hidden;
        text-align: center;
    }

    div#more-information
    {
        background-image: url(http://framework.zend.com/images/bkg_body-bottom.gif);
        height: 100%;
    }
</style>
<div id="welcome">
    <h1>Welcome to the <span id="zf-name">Zend Framework!</span></h1>

    <h3>This is your project's main page</h3>

    <div id="more-information">
        <p><img src="http://framework.zend.com/images/PoweredBy_ZF_4LightBG.png" /></p>
        <p>
            Helpful Links: <br />
            <a href="http://framework.zend.com/">Zend Framework Website</a> |
            <a href="http://framework.zend.com/manual/en/">Zend Framework Manual</a>
        </p>
    </div>
</div>			</div>
			<div id="footer">
				header
			</div>
		</body>
</html>

中间部分就是/layout_demo1/application/views/scripts/index/index.phtml的内容。


注入:可以通过zf的命令工具自动生成layout的配置和文件。

命令如下:

zf enable layout

可以参考命令行章节


三、配置

1.自定义存放位置和名称可以通过application.ini配置文件配置布局文件的存放位置以及布局文件的名称,例如:

resources.layout.layoutPath = APPLICATION_PATH "/mylayouts/scripts"
resources.layout.layout = "mylayout"

2.在action中使用layout对象

可以通过

$layout = $this->_helper->layout();

或者

$helper = $this->_helper->getHelper('Layout');
$layout = $helper->getLayoutInstance();

获取布局对象。


可以通过如下方式禁用当前action使用布局模式

$layout->disableLayout();


可以通过

$layout->setLayout('other');

来设置使用另一个布局文件


可以通过来传递赋值

$layout->assign('headertitle', 'app title');

$layout->somekey = "value"



3.其它获取layout对象的方法

(1)

$layout = Zend_Layout::getMvcInstance();

(2)

$layout = $bootstrap->getResource('Layout');




四、其它用法,实现原理

具体其它的使用方法可以参考

Zend_Layout_Controller_Action_Helper_Layout类,

Zend_Layout_Controller_Plugin_Layout类

Zend_View_Helper_Layout类


不言自明。


<?php


/** Zend_Controller_Action_Helper_Abstract */
require_once 'Zend/Controller/Action/Helper/Abstract.php';

/**
 * Helper for interacting with Zend_Layout objects
 *
 * @uses       Zend_Controller_Action_Helper_Abstract
 * @category   Zend
 * @package    Zend_Controller
 * @subpackage Zend_Controller_Action
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Layout_Controller_Action_Helper_Layout extends Zend_Controller_Action_Helper_Abstract
{
    /**
     * @var Zend_Controller_Front
     */
    protected $_frontController;

    /**
     * @var Zend_Layout
     */
    protected $_layout;

    /**
     * @var bool
     */
    protected $_isActionControllerSuccessful = false;

    /**
     * Constructor
     *
     * @param  Zend_Layout $layout
     * @return void
     */
    public function __construct(Zend_Layout $layout = null)
    {
        if (null !== $layout) {
            $this->setLayoutInstance($layout);
        } else {
            /**
             * @see Zend_Layout
             */
            require_once 'Zend/Layout.php';
            $layout = Zend_Layout::getMvcInstance();
        }

        if (null !== $layout) {
            $pluginClass = $layout->getPluginClass();
            $front = $this->getFrontController();
            if ($front->hasPlugin($pluginClass)) {
                $plugin = $front->getPlugin($pluginClass);
                $plugin->setLayoutActionHelper($this);
            }
        }
    }

    public function init()
    {
        $this->_isActionControllerSuccessful = false;
    }

    /**
     * Get front controller instance
     *
     * @return Zend_Controller_Front
     */
    public function getFrontController()
    {
        if (null === $this->_frontController) {
            /**
             * @see Zend_Controller_Front
             */
            require_once 'Zend/Controller/Front.php';
            $this->_frontController = Zend_Controller_Front::getInstance();
        }

        return $this->_frontController;
    }

    /**
     * Get layout object
     *
     * @return Zend_Layout
     */
    public function getLayoutInstance()
    {
        if (null === $this->_layout) {
            /**
             * @see Zend_Layout
             */
            require_once 'Zend/Layout.php';
            if (null === ($this->_layout = Zend_Layout::getMvcInstance())) {
                $this->_layout = new Zend_Layout();
            }
        }

        return $this->_layout;
    }

    /**
     * Set layout object
     *
     * @param  Zend_Layout $layout
     * @return Zend_Layout_Controller_Action_Helper_Layout
     */
    public function setLayoutInstance(Zend_Layout $layout)
    {
        $this->_layout = $layout;
        return $this;
    }

    /**
     * Mark Action Controller (according to this plugin) as Running successfully
     *
     * @return Zend_Layout_Controller_Action_Helper_Layout
     */
    public function postDispatch()
    {
        $this->_isActionControllerSuccessful = true;
        return $this;
    }

    /**
     * Did the previous action successfully complete?
     *
     * @return bool
     */
    public function isActionControllerSuccessful()
    {
        return $this->_isActionControllerSuccessful;
    }

    /**
     * Strategy pattern; call object as method
     *
     * Returns layout object
     *
     * @return Zend_Layout
     */
    public function direct()
    {
        return $this->getLayoutInstance();
    }

    /**
     * Proxy method calls to layout object
     *
     * @param  string $method
     * @param  array $args
     * @return mixed
     */
    public function __call($method, $args)
    {
        $layout = $this->getLayoutInstance();
        if (method_exists($layout, $method)) {
            return call_user_func_array(array($layout, $method), $args);
        }

        require_once 'Zend/Layout/Exception.php';
        throw new Zend_Layout_Exception(sprintf("Invalid method '%s' called on layout action helper", $method));
    }
}



<?php


/** Zend_Controller_Plugin_Abstract */
require_once 'Zend/Controller/Plugin/Abstract.php';

/**
 * Render layouts
 *
 * @uses       Zend_Controller_Plugin_Abstract
 * @category   Zend
 * @package    Zend_Controller
 * @subpackage Plugins
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: Layout.php 23775 2011-03-01 17:25:24Z ralph $
 */
class Zend_Layout_Controller_Plugin_Layout extends Zend_Controller_Plugin_Abstract
{
    protected $_layoutActionHelper = null;

    /**
     * @var Zend_Layout
     */
    protected $_layout;

    /**
     * Constructor
     *
     * @param  Zend_Layout $layout
     * @return void
     */
    public function __construct(Zend_Layout $layout = null)
    {
        if (null !== $layout) {
            $this->setLayout($layout);
        }
    }

    /**
     * Retrieve layout object
     *
     * @return Zend_Layout
     */
    public function getLayout()
    {
        return $this->_layout;
    }

    /**
     * Set layout object
     *
     * @param  Zend_Layout $layout
     * @return Zend_Layout_Controller_Plugin_Layout
     */
    public function setLayout(Zend_Layout $layout)
    {
        $this->_layout = $layout;
        return $this;
    }

    /**
     * Set layout action helper
     *
     * @param  Zend_Layout_Controller_Action_Helper_Layout $layoutActionHelper
     * @return Zend_Layout_Controller_Plugin_Layout
     */
    public function setLayoutActionHelper(Zend_Layout_Controller_Action_Helper_Layout $layoutActionHelper)
    {
        $this->_layoutActionHelper = $layoutActionHelper;
        return $this;
    }

    /**
     * Retrieve layout action helper
     *
     * @return Zend_Layout_Controller_Action_Helper_Layout
     */
    public function getLayoutActionHelper()
    {
        return $this->_layoutActionHelper;
    }

    /**
     * postDispatch() plugin hook -- render layout
     *
     * @param  Zend_Controller_Request_Abstract $request
     * @return void
     */
    public function postDispatch(Zend_Controller_Request_Abstract $request)
    {
        $layout = $this->getLayout();
        $helper = $this->getLayoutActionHelper();

        // Return early if forward detected
        if (!$request->isDispatched()
            || $this->getResponse()->isRedirect()
            || ($layout->getMvcSuccessfulActionOnly()
                && (!empty($helper) && !$helper->isActionControllerSuccessful())))
        {
            return;
        }

        // Return early if layout has been disabled
        if (!$layout->isEnabled()) {
            return;
        }

        $response   = $this->getResponse();
        $content    = $response->getBody(true);
        $contentKey = $layout->getContentKey();

        if (isset($content['default'])) {
            $content[$contentKey] = $content['default'];
        }
        if ('default' != $contentKey) {
            unset($content['default']);
        }

        $layout->assign($content);

        $fullContent = null;
        $obStartLevel = ob_get_level();
        try {
            $fullContent = $layout->render();
            $response->setBody($fullContent);
        } catch (Exception $e) {
            while (ob_get_level() > $obStartLevel) {
                $fullContent .= ob_get_clean();
            }
            $request->setParam('layoutFullContent', $fullContent);
            $request->setParam('layoutContent', $layout->content);
            $response->setBody(null);
            throw $e;
        }

    }
}




<?php


/** Zend_View_Helper_Abstract.php */
require_once 'Zend/View/Helper/Abstract.php';

/**
 * View helper for retrieving layout object
 *
 * @package    Zend_View
 * @subpackage Helper
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_View_Helper_Layout extends Zend_View_Helper_Abstract
{
    /** @var Zend_Layout */
    protected $_layout;

    /**
     * Get layout object
     *
     * @return Zend_Layout
     */
    public function getLayout()
    {
        if (null === $this->_layout) {
            require_once 'Zend/Layout.php';
            $this->_layout = Zend_Layout::getMvcInstance();
            if (null === $this->_layout) {
                // Implicitly creates layout object
                $this->_layout = new Zend_Layout();
            }
        }

        return $this->_layout;
    }

    /**
     * Set layout object
     *
     * @param  Zend_Layout $layout
     * @return Zend_Layout_Controller_Action_Helper_Layout
     */
    public function setLayout(Zend_Layout $layout)
    {
        $this->_layout = $layout;
        return $this;
    }

    /**
     * Return layout object
     *
     * Usage: $this->layout()->setLayout('alternate');
     *
     * @return Zend_Layout
     */
    public function layout()
    {
        return $this->getLayout();
    }
}






你可能感兴趣的:(function,object,layout,application,action,Zend)