Rodhos Soft

備忘録を兼ねた技術的なメモです。Rofhos SoftではiOSアプリ開発を中心としてAndroid, Webサービス等の開発を承っております。まずはご相談下さい。

View

rederによってViewがレンダリングされる。その部分をみてみる。

public function render($view = null, $layout = null)
    {
// すでにレンダリングされているなら終わり
        if ($this->hasRendered) {
            return null;
        }

// レイアウトがメソッドの引数に指定されているならそれをレイアウトとして使う
        $defaultLayout = null;
        if ($layout !== null) {
            $defaultLayout = $this->layout;
            $this->layout = $layout;
        }

        $viewFileName = $view !== false ? $this->_getViewFileName($view) : null;

        if ($viewFileName) {
            $this->_currentType = static::TYPE_TEMPLATE;
/// レンダリングイベント通知
            $this->dispatchEvent('View.beforeRender', [$viewFileName]);

/// _render関数でレイアウトし、ブロックのcontentとしてsetする。
            $this->Blocks->set('content', $this->_render($viewFileName));

/// レンダリング終了通知
            $this->dispatchEvent('View.afterRender', [$viewFileName]);
        }

/// レウアウトがあるならrenderLayoutでレンダリングし、ブロックのcontentとしてセットする。
        if ($this->layout && $this->autoLayout) {
            $this->Blocks->set('content', $this->renderLayout('', $this->layout));
        }
        if ($layout !== null) {
            $this->layout = $defaultLayout;
        }

        $this->hasRendered = true;

/// ブロックのcontentを取得し返却する。
        return $this->Blocks->get('content');
    }


_render関数、ここが本体になる。テンプレートの継承などもここで解決する。

    protected function _render($viewFile, $data = [])
    {
// 引数で$dataが指定されていなければviewVarsを$dataとして使う。
        if (empty($data)) {
            $data = $this->viewVars;
        }
        $this->_current = $viewFile;
        $initialBlocks = count($this->Blocks->unclosed());

// イベント通知
        $this->dispatchEvent('View.beforeRenderFile', [$viewFile]);

// テンプレートを_evaluateする。ここでファイル内のコードが実行される?
        $content = $this->_evaluate($viewFile, $data);

// イベント通知
        $afterEvent = $this->dispatchEvent('View.afterRenderFile', [$viewFile, $content]);
        if ($afterEvent->getResult() !== null) {
            $content = $afterEvent->getResult();
        }

// ここで継承しているテンプレートがあればアサインし
        if (isset($this->_parents[$viewFile])) {
            $this->_stack[] = $this->fetch('content');
            $this->assign('content', $content);

//  親のレンダリング
            $content = $this->_render($this->_parents[$viewFile]);
            $this->assign('content', array_pop($this->_stack));
        }

        $remainingBlocks = count($this->Blocks->unclosed());

        if ($initialBlocks !== $remainingBlocks) {
            throw new LogicException(sprintf(
                'The "%s" block was left open. Blocks are not allowed to cross files.',
                $this->Blocks->active()
            ));
        }

        return $content;
    }


$this->Blocksのところ、ビューブロックをおさえる必要がある。