Don't you speak portuguese? Translate this site with Google Translator

Pensamento do Dia

A tua única obrigação durante toda a tua existência é seres verdadeiro para contigo próprio. (Richard Bach)

5.1 - Uso dos templates do bake no CakePHP 3

5.1 - Uso dos templates do bake no CakePHP 3

 

A causa da derrota, não está nos obstáculos, ou no rigor das circunstâncias, está na falta de determinação e desistência da própria pessoa. (Buda)

 

Na pasta dos fontes do CakePHP 3 temos:

vendor/cakephp/bake/src/Template/Bake

vendor/cakephp/bake/src/Template/Bake/Element

vendor/cakephp/bake/src/Template/Bake/Form

vendor/cakephp/bake/src/Template/Bake/Controller

vendor/cakephp/bake/src/Template/Bake/Model

Entre outras pastas.

 

Desde a versão 0.1.0 usa-se as tags do ASP no template do bake do CakePHP, que ainda são aceitas na versão 3, mas com previsão de serem removidas na versão 4:

• <% A Bake template php open tag

• %> A Bake template php close tag

• <%= A Bake template php short-echo tag

• <%- A Bake template php open tag, stripping any leading whitespace before the tag

• -%> A Bake template php close tag, stripping trailing whitespace after the tag

 

Adiconar também login e logout na geração de código com o Bake.

Para isso mude o arquivo config/bootstrap_cli.php

E deixe assim:

<?php

use Cake\Core\Configure;
use Cake\Core\Exception\MissingPluginException;
use Cake\Event\Event;
use Cake\Event\EventManager;

Configure::write('Log.debug.file', 'cli-debug');
Configure::write('Log.error.file', 'cli-error');

try {
    $this->addPlugin('Bake');
} catch (MissingPluginException $e) {
// Do not halt if the plugin is missing
}

EventManager::instance()->on(
    'Bake.beforeRender.Controller.controller',
    function (Event $event) {
        $view = $event->subject();
        if ($view->viewVars['name'] == 'Users') {
// add the login and logout actions to the Users controller
            $view->viewVars['actions'] = [
                'login',
                'logout',
                'index',
                'view',
                'add',
                'edit',
                'delete',
            ];
        }
    }
);
$this->addPlugin('Migrations');

 

Agora, ao gerar código com o bake assim:

bin/cake bake all users

Ele gerará também os actions login() e logout() e também o template login.ctp

 

O Bake usa em seus templates atualmente, na versão 3.7.8, a sintaxe do twig, inclusive seus arquivos tem extensão twig.

Veja por exemplo, parte do código do arquivo vendor/cakephp/bake/src/Template/Bake/Element/form.twig abaixo:

 

{% set fields = Bake.filterFields(fields, schema, modelObject) %}
<nav class="large-3 medium-4 columns" id="actions-sidebar">
<ul class="side-nav">
<li class="heading"><?= __('Actions') ?></li>
{% if strpos(action, 'add') is same as(false) %}
<li><?= $this->Form->postLink(
__('Delete'),
['action' => 'delete', ${{ singularVar }}->{{ primaryKey[0] }}],
['confirm' => __('Are you sure you want to delete # {0}?', ${{ singularVar }}->{{ primaryKey[0] }})]
)
?></li>
{% endif %}
<li><?= $this->Html->link(__('List {{ pluralHumanName }}'), ['action' => 'index']) ?></li>
{{- "\n" }}

 

A versão atual (3.7.8) ainda aceita a sintaxe abaixo:

• <% A Bake template php open tag

• %> A Bake template php close tag

• <%= A Bake template php short-echo tag

• <%- A Bake template php open tag, stripping any leading whitespace before the tag

• -%> A Bake template php close tag, stripping trailing whitespace after the tag

Com estes a extensão deve ser .ctp

 

A partir da versão 2.0.0 do Cake a sintaxe passou a usar Twig, inclusive na extensão dos arquivos:

• {% A Bake template php open tag

• %} A Bake template php close tag

• {%= A Bake template php short-echo tag

• {%- A Bake template php open tag, stripping any leading whitespace before the tag

• -%} A Bake template php close tag, stripping trailing whitespace after the tag

 

Usa também para as seções de comentários:

{#

e

#}

 

Agora veja o arquivo form.ctp usado no plugin ribafs/admin-br em sua versão 1.8, onde adicionei suporte para o Bootstrap 3:

<%
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* Slightly modified by Òscar Casajuana for the twbs-cake-plugin
* also under the MIT license.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since 0.1.0
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
use Cake\Utility\Inflector;

$fields = collection($fields)->filter(function($field) use ($schema) {
return $schema->columnType($field) !== 'binary';
});

$pk = "\${$singularVar}->{$primaryKey[0]}";
%>

<div class="container">
<div class="actions columns col-lg-2 col-md-3">
<h3><?= __('Ações') ?></h3>
<ul class="nav nav-stacked nav-pills">
<% if (strpos($action, 'add') === false): %>
<li class="active disabled"><?= $this->Html->link(__('Editar <%= $singularHumanName %>'), ['action' => 'edit', <%= $pk %>]) ?> </li>
<li><?= $this->Form->postLink(__('Excluir'),['action' => 'delete', <%= $pk %>],['confirm' => __('Deseja realmente excluir # {0}?', $<%= $singularVar %>-><%= $primaryKey[0] %>), 'class' => 'btn-danger'])
?></li>
<li><?= $this->Html->link(__('Novo(a) <%= $singularHumanName %>'), ['action' => 'add']) ?></li>

 

Dica - Quando eu estava alterando uma view gerada pelo bake original para uso com Bootstrap, troquei uma tag inicial <nav> por <div> mas esqueci de trocar a tag </nav> final então ao visualizar pelo navegador a view apareceu em apenas uma coluna. Então devemos ficar bem atentos quando alterarmos o código de um template do bake. Um detalhe importante é que a sintaxe do twig pode ser detectada pelo VSCode ao instalar a extensão abaixo:

vscode-twig

 

Isso já ajuda, pois o VSCode já mostra o código colorido, separado em seções e até autocompleta o código e não mais todo em cinza.

Veja o início do form.ctp do tempalte do bake no plugin:

https://github.com/elboletaire/twbs-cake-plugin

 

Agora vejamos como vem o template do bake na versão atual (3.7.8) do Cake:

vendor/cake/php/bake/src/Template/Bake/Element/form.twig

{#
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since 2.0.0
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
#}
{% set fields = Bake.filterFields(fields, schema, modelObject) %}
<nav class="large-3 medium-4 columns" id="actions-sidebar">
<ul class="side-nav">
<li class="heading"><?= __('Actions') ?></li>
{% if strpos(action, 'add') is same as(false) %}

 

Veja que a extensão é twig e a sintaxe não mais usa as tags ASP, mas a sintaxe do twig.

Então, se queremos criar um template para o bake que será suportado pela versão 4 do Cake, não devemos usar as tags do ASP mas as do twig.

 

Customizar o template do bake do CakePHP 3 para usar o Twitter BootStrap.

Idealmente não devemos alterar o core do Cake. Para isso é importante criar plugins, helpers, componentes, behaviors, etc. Mas para facilitar e apenas exemplificar iremos alterar o core e ao final indicarei um plugin que foi criado para esta finalidade.

 

Minha fonte de consulta para a documentação do BootStrap 4 é o:

https://www.w3schools.com/bootstrap4/default.asp

 

Vou criar o aplicativo financas

Com o banco financas e duas tabelas despesas e receitas

Configurar a rota default para Despesas/index para facilitar o acesso

Após configurar o banco gerar o código com o template default do bake:

bin/cake bake all despesas

bin/cake bake all receitas

 

Visualizar pelo navegador

http://localhost/financas

Deixe esta aba do navegador aberta e vamos customizar o template default.

Para facilitar, primeiro vamoms customizar o template das views geradas e depois customizaremos o templae do bake.

 

Comecemos por baixar o BootStrap 4:

https://getbootstrap.com/docs/4.3/getting-started/download/

Após descompactar copiamos os arquivos:

bootstrap-reboot.min.css

bootstrap.min.css

bootstrap-grid.min.css

 

Para webroot/css

Manterei o CSS default e adicionarei o do BootStrap abaixo para que tenha prioridade.

E alteramos o src/Template/Layout/default.ctp para que fique assim:

<!DOCTYPE html>
<html>
<head>
<?=$this->Html->charset()?>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CakePHP 3 com BootStrap 4</title>
<?=$this->Html->meta('icon')?>

<?=$this->Html->css('base.css')?>
<?=$this->Html->css('style.css')?>
<?=$this->Html->css('bootstrap-reboot.css')?>
<?=$this->Html->css('bootstrap.min.css')?>
<?=$this->Html->css('bootstrap-grid.min.css')?>

<?=$this->fetch('meta')?>
<?=$this->fetch('css')?>
<?=$this->fetch('script')?>
</head>
<body>
<nav class="top-bar expanded" data-topbar role="navigation">
    <ul class="title-area col-md-d columns">
        <li class="name">
        <h1><a href="/portal/">CakePHP 3 com BootStrap 4</a></h1>
        </li>
    </ul>
</nav>
<?=$this->Flash->render()?>
<div class="container clearfix">
<?=$this->fetch('content')?>
</div>
<footer>
</footer>
</body>
</html>

 

Alterar src/Template/Despesas/index.ctp

Vamos por partes. Primeiro o sidebar:

<nav class="large-3 medium-4 columns" id="actions-sidebar">

<ul class="side-nav">

<li class="heading"><?= __('Actions') ?></li>

 

Troquemos por:

<div class="actions columns col-lg-2 col-md-3">

<h3><?= __('Actions') ?></h3>

<ul class="nav nav-stacked nav-pills">

 

Ao final o index.ctp de Despesas usando o Botstrap ficará assim:

 

<div class="actions columns col-lg-2 col-md-3">
<h3><?=__('Actions')?></h3>
<ul class="nav nav-stacked nav-pills">
<li><?=$this->Html->link(__('New Despesa'), ['action' => 'add'])?></li>
<li><?=$this->Html->link(__('List Receitas'), ['controller' => 'Receitas', 'action' => 'index'])?></li>
<li><?=$this->Html->link(__('New Receita'), ['controller' => 'Receitas', 'action' => 'add'])?></li>
</ul>
</div>
<div class="despesas index col-lg-10 col-md-9 columns">
<h3><?=__('Despesas')?></h3>
<table class="table table-hover table-stripped">
<thead>
<tr>
<th scope="col"><?=$this->Paginator->sort('id')?></th>
<th scope="col"><?=$this->Paginator->sort('descricao')?></th>
<th scope="col"><?=$this->Paginator->sort('valor')?></th>
<th scope="col"><?=$this->Paginator->sort('mes')?></th>
<th scope="col"><?=$this->Paginator->sort('created')?></th>
<th scope="col"><?=$this->Paginator->sort('modified')?></th>
<th scope="col"><?=$this->Paginator->sort('receita_id')?></th>
<th scope="col" class="actions"><?=__('Actions')?></th>
</tr>
</thead>
<tbody>
<?php foreach ($despesas as $despesa): ?>
<tr>
<td><?=$this->Number->format($despesa->id)?></td>
<td><?=h($despesa->descricao)?></td>
<td><?=$this->Number->format($despesa->valor)?></td>
<td><?=h($despesa->mes)?></td>
<td><?=h($despesa->created)?></td>
<td><?=h($despesa->modified)?></td>
<td><?=$despesa->has('receita') ? $this->Html->link($despesa->receita->id, ['controller' => 'Receitas', 'action' => 'view', $despesa->receita->id]) : ''?></td>
<td class="actions">
<?=$this->Html->link(__('View'), ['action' => 'view', $despesa->id])?>
<?=$this->Html->link(__('Edit'), ['action' => 'edit', $despesa->id])?>
<?=$this->Form->postLink(__('Del'), ['action' => 'delete', $despesa->id], ['confirm' => __('Are you sure you want to delete # {0}?', $despesa->id)])?>
</td>
</tr>
<?php endforeach;?>
</tbody>
</table>
<div class="paginator">
<ul class="pagination">
<?=$this->Paginator->first('<< ' . __('first'))?>
<?=$this->Paginator->prev('< ' . __('previous'))?>
<?=$this->Paginator->numbers()?>
<?=$this->Paginator->next(__('next') . ' >')?>
<?=$this->Paginator->last(__('last') . ' >>')?>
</ul>
<p><?=$this->Paginator->counter(['format' => __('Page {{page}} of {{pages}}, showing {{current}} record(s) out of {{count}} total')])?></p>
</div>
</div>

 

E assim procedi com as outras 3 views restantes até concluir.

Crédito:

As classes que estou usando do Bootstrap 4, as encontrei no plugin twbs-cake

https://github.com/elboletaire/twbs-cake-plugin. Como este plugin é para o Bootstrap 3 eu converti algumas classes que mudaram para o Bootstrap 4 com ajuda do

https://www.w3schools.com/bootstrap4/default.asp

 

Detalhes

Plugin que usa o BootStrap 3 com CakePHP 3 e já com Twig:

https://github.com/ribafs/admin-br

 

Comments fornecido por CComment

Novo Testamento

Então pegaram em pedras para lhe atirarem; mas Jesus ocultou-se, e saiu do templo, passando pelo meio deles, e assim se retirou.
(Jo, 8:59)

Rotas no Mapa do Google

© 2015 Ribamar FS. All Rights Reserved. Designed By JoomShaper