m_shige1979のときどきITブログ

プログラムの勉強をしながら学習したことや経験したことをぼそぼそと書いていきます

Github(変なおっさんの顔でるので気をつけてね)

https://github.com/mshige1979

cakephp2.5系のブログチュートリアル+Twigテンプレート組み込み

最近は3系の検証ばかり

日本語のマニュアルもあるので多少わかりやすくなっているけど簡単なアプリはどんな感じか確認

インストール

clone
mkdir cakephp2.5.x
git clone https://github.com/cakephp/cakephp.git -b 2.5.3
cd cakephp/
git submodule add https://github.com/cakephp/debug_kit.git app/Plugin/DebugKit
core.php
<?php

/**
 * A random string used in security hashing methods.
 */
	Configure::write('Security.salt', 'なんか適当に');

/**
 * A random numeric string (digits only) used to encrypt/decrypt strings.
 */
	Configure::write('Security.cipherSeed', 'なんか適当に');

※認証情報を隠蔽する

database.php
<?php
class DATABASE_CONFIG {

	public $default = array(
		'datasource' => 'Database/Mysql',
		'persistent' => false,
		'host' => 'localhost',
		'login' => 'ユーザーid',
		'password' => 'パスワード',
		'database' => '使用するデータベース名',
		'prefix' => '',
		//'encoding' => 'utf8',
	);
} 

※適当にデータベースを用意して接続情報を設定

bootstrap.php
<?php
CakePlugin::loadAll();
CakePlugin::load('DebugKit');

※debugkit取り込み

AppController.php
<?php

class AppController extends Controller {
    public $components = array('DebugKit.Toolbar');
}

※DebugKit.Toolbarのコンポーネントを取り込み

起動
sh app/Console/cake server -H 192.168.33.10 -p 1234

※簡易コマンドで起動

f:id:m_shige1979:20140726094218p:plain

サンプル作成

posts
CREATE TABLE posts
(
    id INT UNSIGNED PRIMARY KEY NOT NULL AUTO_INCREMENT,
    title VARCHAR(50),
    body LONGTEXT,
    created DATETIME DEFAULT CURRENT_TIMESTAMP,
    modified DATETIME
);
bake
sh app/Console/cake bake controller posts
sh app/Console/cake bake model posts
sh app/Console/cake bake view posts
再起動して確認

f:id:m_shige1979:20140726095750p:plain
f:id:m_shige1979:20140726095800p:plain
f:id:m_shige1979:20140726095811p:plain
f:id:m_shige1979:20140726095824p:plain

テンプレート切り替え

プラグインインストール
git submodule add git://github.com/predominant/TwigView.git app/Plugin/TwigView
cd app/Plugin/TwigView
git submodule update --init

※twigのライブラリもダウンロードする

使用するViewを変更
<?php

App::uses('Controller', 'Controller');

class AppController extends Controller {
    public $components = array(
        'DebugKit.Toolbar',
        'Session',
    );
    public $viewClass = 'TwigView.Twig';
    public $ext = '.twig';
    public $helpers = array('Html', 'Form');

    public function beforeFilter() {
        parent::beforeFilter();
    }

}

※ここでtwigファイルの拡張子を指定する

bootstrap.phpプラグインを追加
<?php

いろいろ…

CakePlugin::load('TwigView');

いろいろ…

※追加

PostsControllerを修正
<?php
App::uses('AppController', 'Controller');
/**
 * Posts Controller
 *
 */
class PostsController extends AppController {

/**
 * Scaffold
 *
 * @var mixed
 */

    public function index(){
        $this->paginate = array(
            'limit'=>10
        );
        $this->set('posts', $this->Post->find('all'));
    }

    public function view($id) {
        if (!$id) {
            throw new NotFoundException(__('Invalid post'));
        }

        $post = $this->Post->findById($id);
        if (!$post) {
            throw new NotFoundException(__('Invalid post'));
        }
        $this->set('post', $post);
    }

    public function add() {
        if ($this->request->is('post')) {

            if ($this->Post->save($this->request->data)) {
                $this->Session->setFlash(__('Your post has been saved.'));
                return $this->redirect(array('action' => 'index'));
            }
            $this->Session->setFlash(__('Unable to add your post.'));
        }
    }

    public function edit($id = null) {
        if (!$id) {
            throw new NotFoundException(__('Invalid post'));
        }

        $post = $this->Post->findById($id);
        if (!$post) {
            throw new NotFoundException(__('Invalid post'));
        }

        if ($this->request->is(array('post', 'put'))) {
            $this->Post->id = $id;
            if ($this->Post->save($this->request->data)) {
                $this->Session->setFlash(__('Your post has been updated.'));
                return $this->redirect(array('action' => 'index'));
            }
            $this->Session->setFlash(__('Unable to update your post.'));
        }

        if (!$this->request->data) {
            $this->request->data = $post;
        }
    }

    public function delete($id) {
        if ($this->request->is('get')) {
            throw new MethodNotAllowedException();
        }

        if ($this->Post->delete($id)) {
            $this->Session->setFlash(__('The post with id: %s has been deleted.', h($id)));
            return $this->redirect(array('action' => 'index'));
        }
    }
}

※bakeで作成していたのですが手動で作成しなおし
※Scaffoldingを使用した場合は暫定のViewなどを使用するのでカスタムテンプレートを使用できない

各テンプレートを修正

phpでの記法があるけどテンプレートでは使用できない場合は手動で書き直し

index.twig

<div class="posts index">
    <h2>Posts</h2>
    <table cellpadding="0" cellspacing="0">
        <tbody>
        {% for post in posts %}
            <tr>
                <td>{{ post.Post.id }}</td>
                <td>{{ post.Post.title }}</td>
                <td>{{ post.Post.body }}</td>
                <td>{{ post.Post.created }}</td>
                <td>{{ post.Post.modified }}</td>
                <td class="actions">
                    {{ html.link('View', {'controller': 'posts', 'action': 'view/'~post.Post.id}) }}
                    {{ html.link('Edit', {'controller': 'posts', 'action': 'edit/'~post.Post.id}) }}
                    {{ form.postLink(
                        'Delete',
                        {
                            'action': 'delete/'~post.Post.id
                        },
                        'Delete'
                    ) }}
                </td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
</div>
<div class="actions">
    <h3>Action</h3>
    <ul>
        <li>
            {{
            html.link('New Post', {'action': 'add'})
            }}
        </li>
    </ul>
</div>

add.twig

<div class="posts form">
{{ form.create('Post') }}
	<fieldset>
		<legend>Add Post</legend>
		{{ form.input('title') }}
		{{ form.input('body') }}
	</fieldset>
{{ form.end('Submit') }}
</div>
<div class="actions">
	<h3>Actions</h3>
	<ul>
		<li>
            {{
            httml.link('List Posts', {'action': 'index'})
            }}
        </li>
	</ul>
</div>

view.twig

<div class="posts view">
<h2>Post</h2>
	<dl>
		<dt>Id</dt>
		<dd>
			{{ post.Post.id }})
			&nbsp;
		</dd>
		<dt>Title</dt>
		<dd>
			{{ post.Post.title }}
			&nbsp;
		</dd>
		<dt>Body</dt>
		<dd>
			{{ post.Post.body }}
			&nbsp;
		</dd>
		<dt>Created</dt>
		<dd>
			{{ post.Post.created }}
			&nbsp;
		</dd>
		<dt>Modified</dt>
		<dd>
		    {{ post.Post.modified }}
			&nbsp;
		</dd>
	</dl>
</div>
<div class="actions">
	<h3>Actions</h3>
	<ul>
		<li>{{ html.link('Edit Post', {'action': 'edit/'~post.Post.id}) }}</li>
		<li>{{ form.postLink('Delete Post', {'action': 'delete/'~post.Post.id}, 'Delete') }}</li>
		<li>{{ html.link('List Posts', {'action': 'index'}) }}</li>
		<li>{{ html.link('New Post', {'action': 'add'}) }}</li>
	</ul>
</div>

edit.twig

<div class="posts form">
{{ form.create('Post') }}
	<fieldset>
		<legend>Edit Post</legend>
		{{ form.input('id') }}
		{{ form.input('title') }}
		{{ form.input('body') }}
	</fieldset>
{{ form.end('Submit') }}
</div>
<div class="actions">
	<h3>Actions</h3>
	<ul>
		<li>{{ form.postLink('Delete', {'action': 'delete/'~form.value('Post.id')}, 'Delete') }}</li>
		<li>{{ html.link('List Posts', {'action': 'index'}) }}</li>
	</ul>
</div>

まとめ

以前使用していたのは2.3までなのでいくつかの機能は変わっている感じはする。
今回、簡単にtwigを使用してみたけどいろいろ面倒な感じはした。(´・ω・`)

<?php
$cakeDescription = __d('cake_dev', 'CakePHP: the rapid development php framework');
$cakeVersion = __d('cake_dev', 'CakePHP %s', Configure::version())
?>

こんな感じの__d関数などを使用することができなかったりといくつかの不便な感じはした。

まあ、そのあたりはコントローラーやモデルなどで対応していくことで対応出来そう。

ヘルパー機能は使わないほうが吉な感じです。
cssスクリプトをどうしても読み込みたい場合などは使用する必要がありそうですけど…