Welcome Guest, Not a member yet? Register   Sign In
extend layout
#1

Hi, I'm wondering if a layout can define a default behavior that is used when the section is not defined in the view extension.

it's possible?

thanks, Paolo
Reply
#2

Sure use an if else statement.
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#3

(This post was last modified: 11-11-2021, 07:37 AM by nemesis.)

I am sorry, I'll be more precisely with some examples. this is my view:
Code:
<?= $this->extend('default'); ?>

<?= $this->section('theBody') ?>
<b>This is my body, as I write in my view</b>
<?= $this->endSection() ?>
and this is my default.php, as suggest from user guide:
Code:
<!doctype html>
<html>
<head>
    <title>My Layout</title>
</head>
<body>
    <?= $this->renderSection('theTitle') ?>
    <?= $this->renderSection('theBody) ?>
</body>
</html>
since renderSection return nothing, how can I test if it's used by a view?

I've try to change system\View.php from
Code:
public function renderSection(string $sectionName){
  if (! isset($this->sections[$sectionName])) {
      return;
  }
  foreach ($this->sections[$sectionName] as $key => $contents) {
      echo $contents;
      unset($this->sections[$sectionName][$key]);
  }
}

to:
Code:
public function renderSection(string $sectionName){
  if (! isset($this->sections[$sectionName])) {
      return true;
  }
  foreach ($this->sections[$sectionName] as $key => $contents) {
      echo $contents;
      unset($this->sections[$sectionName][$key]);
  }
}

so that my layout become:
Code:
<!doctype html>
<html>
<head>
    <title>My Layout</title>
</head>
<body>
    <?php if ($this->renderSection('theTitle')): ?>
        <h1>default header</h1>
    <?php endif ?>
    <?php if ($this->renderSection('theBody)): ?>
        <p>default body</p>
    <?php endif ?>
</body>
</html>

this work fine but it isn't the right way! I will not change system source code... more over, it do a wrong render when I use multiple times (one inside another)...
Reply
#4

(This post was last modified: 11-11-2021, 09:51 AM by ikesela.)

layout.php (in App\VIew folder)
Code:
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0,shrink-to-fit=no">
    <title><?=Lang('Lang.app')?></title>
    <link href=...css.css" rel="stylesheet" type="text/css" />   
  </head>
<body> 
<div class="container"> 
<main role="main"> 
<?= view($config->views['direct_view']) ?> 
<?= $this->renderSection('main') ?>
</main>  
</div>  
<script src=".....js"></script>

some_file.php
Code:
<?= $this->extend($config->viewLayout) ?>
<?= $this->section('main') ?>
.. YOUR CONTENT HERE ...
<?= $this->endSection() ?>

your_controller
Code:
public function your_function()
{
              $config = config('YourConfig'); // can do this in contructor instead

return view($config->views['your_view'],[
'config' => $config,
                      'data' => $any_data_to_pass,
]);
}

YourConfig.php (in App|config folder)
Code:
namespace App\Config;

use CodeIgniter\Config\BaseConfig;

class YourConfig extends BaseConfig
{
 
    // you can have multiple view setting here
    public $views = [
         'direct_view' => 'App\Views\some_folder\direct_render_file_in_layout'
        'your_view' => 'App\Views\some_folder\some_file', // link to real file with extension .php 
    ]; 
  public $some_parameter = 'your_value';
    // Layout for the views to extend
    public $viewLayout = 'App\Views\some_folder\layout';
}

Routes.php
 
Code:
$routes->get('/', 'YourController::your_function');
 

I hope this can give you hint how the layout basic work and load it as single page web

You can edit file App\View\errors\html\error_404.php for custom not found page and remove default message.
Reply
#5

(11-11-2021, 09:45 AM)ikesela Wrote:
Code:
...

I hope this can give you hint how the layout basic work and load it as single page web

You can edit file App\View\errors\html\error_404.php for custom not found page and remove default message.

thanks for the reply, but I can't understand what it has to do with my problem.. 

I would like to be able to define a layout that generates a complete view (with basic html for all sections), which can possibly be (partially or even totally) redefined by the view.

I await suggestions!
Reply
#6

Do you render the View file, not the Layout in your controller?

PHP Code:
public function index()
{
    echo view('some_view');

Reply
#7

(11-12-2021, 11:33 PM)kenjis Wrote: Do you render the View file, not the Layout in your controller?

PHP Code:
public function index()
{
    echo view('some_view');


yes, but I think a layout could be used as a standard view as well
Reply
#8

(This post was last modified: 11-15-2021, 10:24 AM by nemesis.)

(11-11-2021, 03:12 AM)InsiteFX Wrote: Sure use an if else statement.

could you explain me in detail? I have described my implementation, but as of now I have not yet found an elegant solution - thanks!
Reply
#9

Without the change of system\View.php, doesn't your layout work?
Reply
#10

(This post was last modified: 11-16-2021, 01:01 AM by nemesis.)

(11-15-2021, 06:40 PM)kenjis Wrote: Without the change of system\View.php, doesn't your layout work?

does not work!


since renderSection ($sectionName) does not return any value, how does the layout file know if it has been used? that is, if section($sectionName) has been called


change was in system\View\View.php:


PHP Code:
public function renderSection(string $sectionName){
   if (! isset($this->sections[$sectionName])) 
      return false;

   foreach ($this->sections[$sectionName] as $key => $contents) {
      echo $contents;
      unset($this->sections[$sectionName][$key]);
   }
   return true;
 } 
so that I can write in any layout:


PHP Code:
<?php if (!$this->renderSection('aSection')): ?>
<b>default content</b>
<?php endif ?>


but I think it doesn't work in case of nested use
Reply




Theme © iAndrew 2016 - Forum software by © MyBB