17
Magento rendering system Vitaliy Golomoziy Consultant Magento Inc.

Система рендеринга в Magento

Embed Size (px)

Citation preview

Page 1: Система рендеринга в Magento

Magento rendering system

Vitaliy GolomoziyConsultantMagento Inc.

Page 2: Система рендеринга в Magento

What is rendering ?

We understand rendering as a process of generating output for the customer.

Client

Server

Web

GET index.php HTTP/1.1Host: somehos.com

HTTP/1.1 200 OK...

<html><head>

...

Page 3: Система рендеринга в Magento

Two goals of rendering output in webGenerate headersGenerate response body

How it works in magento ?

Front (Mage_Core_Controller_Varien_Front::dispatch) contoller calls $response->sendResponse()

Response object (Mage_Core_Controller_Response_Http which extends Zend_Controller_Response_Http) calls sendHeaders and outputBody

So, the main goal of rendering system is to generate html bodyand assign it to response object body variable

Page 4: Система рендеринга в Magento

Actors (Magento View Level)

Page 5: Система рендеринга в Magento

Template and layout configuration files organization

app

designarea (adminhtml or frontend)

package (default, enterprise)theme (default, mytheme)

layout

templatecage.xml, catalog.xml, etc..

template files (.phtml)

Page 6: Система рендеринга в Magento

Generating output flowController sets body directly to response object.

Example: Mage_Adminhtml_CustomerController::ordersActionpublic function ordersAction() { $this->_initCustomer(); $this->getResponse()->setBody( $this->getLayout() ->createBlock('adminhtml/customer_edit_tab_orders') ->toHtml() ); }

Controller calls loadLayout(), renderLayout()Most of controllers follows this way. For example Mage_Adminhtml_Catalog_ProductController::indexAction public function indexAction() { $this->_title($this->__('Catalog')) ->_title($this->__('Manage Products'));

$this->loadLayout(); $this->_setActiveMenu('catalog/products'); $this->renderLayout(); }

Page 7: Система рендеринга в Magento

Loading layout

Page 8: Система рендеринга в Magento

Layout configuration file structure

Layout configuration is an xml file.Root node is - <layout>First-level node is arbitrary node which named “handle”Second-level node is <block> or <reference>Block attributes: name, type, output, template, as, translateReference attributes: name

Block children: block or actionAction attributes: method, ifconfig, blockAction children: any flat node.Action children attribute: helper

Reference children: block, action

Page 9: Система рендеринга в Magento

Layout configuration file example

<layout version="0.1.0">

<default translate="label" module="page"> <label>All Pages</label> <block type="page/html" name="root" output="toHtml" template="page/3columns.phtml"> <block type="page/html_head" name="head" as="head"> <action method="addJs"><script>prototype/prototype.js</script></action> <action method="addJs" ifconfig="dev/js/deprecation"> <script>prototype/deprecation.js</script></action> <action method="addJs"><script>lib/ccard.js</script></action> ........................... </default>

Page 10: Система рендеринга в Magento

Building layout example

<block name=”root”> <block name=”head”> <action method=”doSomething> <some>_VALUE_</some> </action> </block>

<block name=”header”> </block>

<block name=”content”> ..... <block name=”somebock” type=”A”> .... </block> </block></block>

<block name=”root”> <block name=”head”> <action method=”doSomething”> <some>_VALUE_</some> </action> </block>

<block name=”header”> </block>

<block name=”content”> ..... </block></block>

<reference name=”content”> <block name=”somebock” type=”A”> .... </block></reference>

default

FullActionName catalog_product_view

$root = new Block();$head = new Block();$head->doSomething(_VALUE_);

$root->addChild($head);

$header = new Block();

$content = new Block();

$someblock = new A();$content->addChild($someblock);

Page 11: Система рендеринга в Magento

Render layout schema

Page 12: Система рендеринга в Magento

Looking for template file

1) In current theme (store config: default/design/theme/template)2) In fallback theme (store config: default/design/theme/default)3) In “default” theme4) In “base” package “default” theme

First of all package established (store config: default/design/package)

Then template file is searching in the following places:

Page 13: Система рендеринга в Magento

Block_Template fetchView method $do = $this->getDirectOutput(); if (!$do) { ob_start(); }

if ($this->getShowTemplateHints()) { ... }

try { $includeFilePath = realpath($this->_viewDir . DS . $fileName); if (strpos($includeFilePath, realpath($this->_viewDir)) === 0) { include $includeFilePath; } else { Mage::log('Not valid template file:'.$fileName, Zend_Log::CRIT, null, null, true); }

} catch (Exception $e) { ob_get_clean(); throw $e; }

if ($this->getShowTemplateHints()) { echo '</div>'; }

if (!$do) { $html = ob_get_clean(); } else { $html = ''; } ....

Page 14: Система рендеринга в Magento

Corollary

Template execution is direct include inside Block_Template fetchViewmethod. It means that “$this” inside template refers to correspondent block instance

Each template file has own block instance which extends Mage_Core_Block_Template class.

Magento (almost) never renders children of the block. Exception isMage_Core_Block_Text_List class.

There are 4 places where real template file could be located (current theme, fallback theme, default theme, base package default theme). Moreover if two appropriate file exists, first from the above list will be taken, which gives flexibility in overriding native templates.

Page 15: Система рендеринга в Magento

Root template example

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $this->getLang() ?>" lang="<?php echo $this->getLang() ?>"><head><?php echo $this->getChildHtml('head') ?></head><body<?php echo $this->getBodyClass()?' class="'.$this->getBodyClass().'"':'' ?>><?php echo $this->getChildHtml('after_body_start') ?><div class="wrapper"> <?php echo $this->getChildHtml('global_notices') ?> <div class="page"> <?php echo $this->getChildHtml('header') ?>

<div class="main-container col3-layout"> <div class="main"> <?php echo $this->getChildHtml('breadcrumbs') ?> <div class="col-wrapper"> <div class="col-main"> <?php echo $this->getChildHtml('global_messages') ?> <?php echo $this->getChildHtml('content') ?> </div> <div class="col-left sidebar"><?php echo $this->getChildHtml('left') ?></div> </div> <div class="col-right sidebar"><?php echo $this->getChildHtml('right') ?></div> </div> </div> <?php echo $this->getChildHtml('footer') ?> <?php echo $this->getChildHtml('before_body_end') ?> </div></div><?php echo $this->getAbsoluteFooter() ?></body></html>

app/desig/frontend/base/default/template/page/3columns.phtml

Page 16: Система рендеринга в Magento

Other ways for rendering childrenExtend your block from Mage_Core_Block_Text_List.

class Mage_Core_Block_Text_List extends Mage_Core_Block_Text{ protected function _toHtml() { $this->setText(''); foreach ($this->getSortedChildren() as $name) { $block = $this->getLayout()->getBlock($name); if (!$block) { Mage::throwException(Mage::helper('core')->__('Invalid block: %s', $name)); } $this->addText($block->toHtml()); } return parent::_toHtml(); }}

Call getChildHtml('') without parameters. public function getChildHtml($name='', $useCache=true, $sorted=false) { if ('' === $name) { ... foreach ($children as $child) { $out .= $this->_getChildHtml($child->getBlockAlias(), $useCache); } return $out;

} else { ... }

Page 17: Система рендеринга в Magento

The End