We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Layout is rendered twice

Hi evryone,

In one of my multi-modules project I have shared catalog with all layouts. In action I change the layout using:

$this->view->setTemplateAfter('name_OF_layout');

and it's work fine but in one action in output I have rendered double layout. In my layout file I have:

        ...
        <div>

        {{ content() }}

        </div>.
        ..

and in this one action content method is generating all html including layout. What's going on?



43.9k
edited Dec '14

Hi,

Do you call your controller action via an ajax request?



12.8k

No, it's not ajax... render level is default.



43.9k

so your faulty controller action isn't called by an ajax request ... So far as I understand, there is only one action that behaves like this. Could you show us the corresponding code.



12.8k
edited Dec '14

action

/**
 * Remind password action
 * 
 * @return remind Action
 */
public function remindAction() {

    $this->view->layout = 'frontend';
    $this->view->setTemplateAfter('user');

    $form = new \User\Forms\Remind();
    if ($this->request->isPost()) {
        $post = $this->request->getPost();
        if ($form->isValid($post)) {
            $email = $this->request->getPost('email','email');

            //@to_do Automatic route name
            $resp = $this->servicesManager->get('user')->remindPassword($email, '/confirm-password-change/');
            $this->view->resp = $resp;

            if($resp->getStatus()){
                $this->flash->success($this->_('ok'));
            }else{
                $this->flash->error($this->_($resp->getStatusMessage()));
            }
        } else {
            $this->flash->error($this->_('Incorrect data'));
        }
    }
    $this->view->form = $form;
}

layout user

<html class="no-js"> <!--[if gt IE 9]><!--> <html class="no-js" lang="{{ lang }}" itemscope itemtype="https://schema.org/Product"> <!--<![endif]--> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />

        <meta name="keywords" content="{{ head.keywords }}" />
        <meta name="description" content="{{ head.description }}" />

        <meta property='og:title' content='{{ head.og.title }}'/>
        <meta property='og:image' content='{{ head.og.image }}'/>
        <meta property='og:description' content='{{ head.og.description }}'/>
        <meta property='og:site_name' content='{{ head.og.siteName }}'/>
        <meta property='og:type' content='{{ head.og.type }}'/>

        <meta itemprop="name" content="{{ head.og.title }}">
        <meta itemprop="description" content="{{ head.og.description }}">
        <meta itemprop="image" content="{{ head.og.image }}">

        <link href="/favicon.ico" rel="favicon" >

        <link href='//fonts.googleapis.com/css?family=Fira+Sans:300,700&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
        {{ less
            .add("/layouts/" ~ layout ~ "/css/style.less")
            .compileAll(layout)
            .toHtml() 
        }}

        <!--<meta name="viewport" content="width=device-width, initial-scale=1">-->

        <?php $this->assets
            ->collection("out")
            ->addJs('//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js', false, false)
            ->addJs('//ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js', false, false)
        ?>
        <?php echo $this->assets->outputJs('out') ?>

        <?php $this->assets
            ->collection("footer")
            ->setTargetPath(ROOT_WEB_PATH . '/cache/'.$this->layout.'/all-user.js')
            ->setTargetUri('cache/'.$this->layout.'/all-user.js')
            ->addJs('layouts/common/js/modernizr-2.6.2.min.js')
            ->addJs('layouts/common/js/bowser.min.js')
            ->addJs('layouts/common/js/browser.version.1.0.js')
            ->join(APP_ENVIROMENT == 'production')
            ->addFilter(new \Phalcon\Assets\Filters\Jsmin())
        ?>
    </head>
    <body>
        <div id="fb-root"></div>
        <script>
            (function(d, s, id) {
                var js, fjs = d.getElementsByTagName(s)[0];
                if (d.getElementById(id))
                    return;
                js = d.createElement(s);
                js.id = id;
                js.src = "//connect.facebook.net/pl_PL/sdk.js#xfbml=1&appId=1436364816646442&version=v2.0";
                fjs.parentNode.insertBefore(js, fjs);
            }(document, 'script', 'facebook-jssdk'));
        </script>
        <!--[if lt IE 7]>
            <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="https://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
        <![endif]-->
        <!-- Add your site or application content here -->

        <div class="row navigationRow"> 
            <div class='col no-padding navigationCol'>
                <nav class="top">
                    <div class="topBg"> 
                        <div class="globe"> </div>
                        <a href='/' class='logo'><img src="/layouts/frontend/img/logoBig.png"/></a>
                    </div>
                    <a href="#" class="menu-toggle" id="menu-toggle"> </a> 
                    {{ navigation.toHtml('top') }}
                    <?php $this->assets->collection('footer')->addJs('layouts/frontend/js/mobile-menu.js'); ?>
                    <?php $this->assets->collection('footer')->addJs('layouts/frontend/js/login-form.js'); ?>
                </nav>
            </div>
        </div>

        {{ content() }}

        <div class='row bottom-menu'>
            <div class='col no-padding'>
                <div class='col-3 products'>

                </div>
                <div style='clear:both;'></div>
            </div>
        </div>
        <div class='row bDark newsletter'>
            <div class='col no-padding'>
                <div class='col-1'>  

                    <div class='newsletter-form'>
                        <input type="text" placeholder="wpisz adres email" id='newsletter-input'/><a href='#' id='subscribe-submit' class="subscribe">Zapisz siÄ™</a>
                    </div>
                    <div class='newsletter-message'><p></p></div>
                    <?php $this->assets->collection('footer')->addJs('layouts/common/js/newsletter.ajax.js'); ?>
                </div>
            </div>
        </div> 
        <div class='row bMed footer'>
            <div class='col no-padding'>
                <div class='col-1'>  
                    <div class='footer-menu'>
                        <div class='docs-menu'>
                        </div>
                        <div class='social-menu'>
                            <a href='#' class='fb'></a>
                            <a href='#' class='linkedin'></a>
                            <a href='#' class='gplus'></a>
                        </div>
                    </div>
                    <div class='footer-copyrights'>

                    </div>
                    <div style='clear:both;'></div>
                </div>
                <div class='col-1 ue'>

                </div>
            </div>
        </div> 

        <?php echo $this->assets->outputJs('footer') ?>
    </body>
</html>


43.9k

OK, you alredy have a main layout file: $this->view->layout = 'frontend';

so I imagine that you must have duplicate elements in your user.volt layout file and in your frontend.volt

btw

<?php $this->assets
            ->collection("out")
            ->addJs('//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js', false, false)
            ->addJs('//ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js', false, false)
        ?>
        <?php echo $this->assets->outputJs('out') ?>

        <?php $this->assets
            ->collection("footer")
            ->setTargetPath(ROOT_WEB_PATH . '/cache/'.$this->layout.'/all-user.js')
            ->setTargetUri('cache/'.$this->layout.'/all-user.js')
            ->addJs('layouts/common/js/modernizr-2.6.2.min.js')
            ->addJs('layouts/common/js/bowser.min.js')
            ->addJs('layouts/common/js/browser.version.1.0.js')
            ->join(APP_ENVIROMENT == 'production')
            ->addFilter(new \Phalcon\Assets\Filters\Jsmin())
        ?>

you better put that code in controller



12.8k

This problem is solved When I'm using

$this->view->setRenderLevel(\Phalcon\Mvc\View::LEVEL_LAYOUT);

LEVEL_MAIN_LAYOUT generate layout twice



12.8k

@le51 $this->view->layout = 'frontend'; this is only layout name. Less need's to know where can save compilated css file/



43.9k

This problem is solved When I'm using

$this->view->setRenderLevel(\Phalcon\Mvc\View::LEVEL_LAYOUT);

LEVEL_MAIN_LAYOUT generate layout twice

maybe because you have duplicated code in your main layout file (views/index.volt ?) and in user.volt



12.8k

I find the answer.

It was some problem with layout-name. When I change name from 'user' to 'frontend-basic' evrythink looks fine. Maybe when common folder with all layouts is sharable, names of each layout should be diffrent from module name or controller name My action is in user/user/remind (module/controller/action)



43.9k

yes, if your controller is "user", then phalcon will by default load controller template file : views/layouts/user.volt so this template is loaded twice if you use $this->view->setTemplateAfter('user');