Ngu ngơ học làm web (x46) - CakePHP2 - CKEditor, block, lọc dấu tiếng Việt, folder

Tiếp theo của: Ngu ngơ học làm web (x45) - CakePHP2 – Tạo helper, Admin books
-----

Phần x46. CakePHP2 – CKEditor, block, lọc dấu tiếng Việt, folder


Tích hợp CKEditor vào trang ‘edit một cuốn sách’:

Vào trang http://ckeditor.com để tải mã nguồn của CKEditor về máy, chọn bản standard.

Sau khi tải về máy, giải nén và chép vào thư mục webroot\js của dự án.

Khai báo sử dụng CKEditor trong layout admin:

[Layouts\admin.ctp]

echo $this->fetch('script');
echo $this->Html->script('ckeditor/ckeditor');

Nhúng CKEditor vào input:

[View\Books\admin_edit.ctp]

echo $this->Form->input('image');
echo $this->Form->input('info', ['label' => 'Nội dung', 'class' => 'ckeditor']);
echo $this->Form->input('price');

Khắc phục lỗi hiển thị tiếng Việt khi xem ở chế độ source của CKEditor:

[js\ckeditor\config.js]

config.entities = false;
// The toolbar groups arrangement, optimized for two toolbar rows.
config.toolbarGroups = [

Sửa lỗi hiển thị thẻ html trong view View\Books\view.ctp:

[View\Books\view.ctp]

<h4>Giới thiệu:</h4>
<p>
<?php echo $book['Book']['info']; ?>
</p>

Thêm nút New Book cho trang [admin_index.ctp]

<h2><?php echo __('Sách'); ?></h2>
            <div class="actions">
            <ul>
                        <li><?php echo $this->Html->link(__('New Book'), array('controller' => 'books', 'action' => 'add')); ?> </li>
            </ul>

Đổi view [View\Books\add.ctp] thành [View\Books\admin_add.ctp].

Đổi action [ControllersBooks.php add()] thành [ControllersBooks.php admin_add()]

Thực hiện thêm CKEditor cho chức năng ‘thêm một quyển sách’:

[View\Books\admin_add.ctp]

echo $this->Form->input('image');
echo $this->Form->input('info', ['label' => 'Nội dung', 'class' => 'ckeditor']);
echo $this->Form->input('price');

Sửa lại một chút action admin_add() để hiển thị danh mục sách theo cấu trúc cây:

[BooksController.php action admin_add()]

$categories = $this->Book->Category->generateTreeList();
$writers = $this->Book->Writer->find('list');
$this->set(compact('categories', 'writers'));

Để gọi một khối lệnh (block) (ví dụ: đoạn mã javascript) trong view sử dụng cú pháp:

<?php
$this->start(‘script);
            // khối lệnh
$this->end();
?>

Ví dụ,

[admin_edit.ctp]

<?php
            $this->start('script');
                        echo $this->Html->script('ckeditor/ckeditor');
            $this->end();
?>

Và [admin_add.ctp]

<?php
            $this->start('script');
                        echo $this->Html->script('ckeditor/ckeditor');
            $this->end();
?>

Xem (clip số 45a – chickenrainshop):

- Tạo link thân thiện (slug) (45a) 

- Sử dụng novalidate (2":01)

- Chuyển kí tự có dấu thành không dấu stripUnicode, preg_replace, Inflector, slug (4":08)

- Tạo thư mục trong cakePHP sử dụng Folder (9":02)

- Lấy đường dẫn tuyệt đối - APP (10":51)

Tạo slug tự động, thực hiện trên view Categories\admin_add.ctp:

Sửa lại view admin_add.ctp, thiết lập hai thuộc tính required và novalidate:

[View\Categories\admin_add.ctp]

<div class="categories form">
<?php echo $this->Form->create('Category', ['novalidate' => true]); ?>
            …
                        echo $this->Form->input('name');
                        echo $this->Form->input('slug', ['required' => false, ]);
            …
</div>

[Controller\CategoriesController.php action admin_add()]

public function admin_add() {
                        if ($this->request->is('post')) {
                                    if (empty($this->request->data['Category']['slug'])) {
                                                $this->request->data['Category']['slug'] = $this->Tool->slug($this->request->data['Category']['name']);
                                    } else {
                                                $this->request->data['Category']['slug'] = $this->Tool->slug($this->request->data['Category']['slug']);
                                    }
                                    $this->Category->create();

[Component\ToolComponent.php]

// lọc dấu tiếng Việt
                        public function stripUnicode ($string) {
                                    if (!$string) return false;
                                    $unicode = array(
                                                'a'=>'á|à|ả|ã|ạ|ă|ắ|ặ|ằ|ẳ|ẵ|â|ấ|ầ|ẩ|ẫ|ậ|Á|À|Ả|Ã|Ạ|Ă|Ắ|Ặ|Ằ|Ẳ|Ẵ|Â|Ấ|Ầ|Ẩ|Ẫ|Ậ',
                                                'd'=>'đ|Đ',
                                                'e'=>'é|è|ẻ|ẽ|ẹ|ê|ế|ề|ể|ễ|ệ|É|È|Ẻ|Ẽ|Ẹ|Ê|Ế|Ề|Ể|Ễ|Ệ',
                                                'i'=>'í|ì|ỉ|ĩ|ị|Í|Ì|Ỉ|Ĩ|Ị',
                                                'o'=>'ó|ò|ỏ|õ|ọ|ô|ố|ồ|ổ|ỗ|ộ|ơ|ớ|ờ|ở|ỡ|ợ|Ó|Ò|Ỏ|Õ|Ọ|Ô|Ố|Ồ|Ổ|Ỗ|Ộ|Ơ|Ớ|Ờ|Ở|Ỡ|Ợ',
                                                'u'=>'ú|ù|ủ|ũ|ụ|ư|ứ|ừ|ử|ữ|ự|Ú|Ù|Ủ|Ũ|Ụ|Ư|Ứ|Ừ|Ử|Ữ|Ự',
                                                'y'=>'ý|ỳ|ỷ|ỹ|ỵ|Ý|Ỳ|Ỷ|Ỹ|Ỵ'
                                    );
                                    foreach ($unicode as $nonUnicode => $uni) {
                                                $string = preg_replace("/($uni)/", $nonUnicode, $string);
                                    }
                                    return $string;
                        }

                        public function slug($string, $character = '-') {
                                    // chuyển kí tự có dấu thành không dấu
                                    $string = $this->stripUnicode($string);
                                    App::uses('Inflector', 'Utility');
                                    $string = inflector::slug($string, $character);
                                    return strtolower($string);
                        }

Có thể tách đoạn mã tạo slug thành một hàm riêng, đặt tại AppController để sử dụng lại:

[AppController.php]

public function checkSlug($data, $model, $name, $slugField = 'slug') {
                        if (empty($this->request->data[$model][$slugField])) {
                                                $this->request->data[$model][$slugField] = $this->Tool->slug($this->request->data[$model][$name]);
                                    } else {
                                                $this->request->data[$model][$slugField] = $this->Tool->slug($this->request->data[$model][$slugField]);
                                    }
            }

Sửa lại một chút mã của admin_add():

[Controller\CategoriesController.php action admin_add()]

public function admin_add() {
                        if ($this->request->is('post')) {
                                    // if (empty($this->request->data['Category']['slug'])) {
                                    //          $this->request->data['Category']['slug'] = $this->Tool->slug($this->request->data['Category']['name']);
                                    // } else {
                                    //          $this->request->data['Category']['slug'] = $this->Tool->slug($this->request->data['Category']['slug']);
                                    // }
                                    $this->checkSlug($this->request->data, 'Category', 'name');
                                    $this->Category->create();

Tạo thêm một danh mục sách, đồng thời phải tạo luôn thư mục để lưu hình ảnh của sách thuộc danh mục này:

[Controller\CategoriesController.php action admin_add()]

public function admin_add() {
                        if ($this->request->is('post')) {
                                    // if (empty($this->request->data['Category']['slug'])) {
                                    //          $this->request->data['Category']['slug'] = $this->Tool->slug($this->request->data['Category']['name']);
                                    // } else {
                                    //          $this->request->data['Category']['slug'] = $this->Tool->slug($this->request->data['Category']['slug']);
                                    // }
                                    $this->checkSlug($this->request->data, 'Category', 'name');
                                    App::uses('Folder', 'Utility');
                                    $folder = new Folder();
                                    if ($folder->create(APP.'/webroot/files/'.$this->request->data['Category']['slug'])) {
                                                $this->Category->create();
                                                if ($this->Category->save($this->request->data)) {
                                                            $this->Flash->success(__('The category has been saved.'));
                                                            return $this->redirect(array('action' => 'index'));
                                                } else {
                                                            $this->Flash->error(__('The category could not be saved. Please, try again.'));
                                                }
                                    } else {
                                                $this->Flash->error(__('Không tạo được thư mục. Vui lòng thử lại sau.'));
                                    }
                                   

                        }
-----------
Cập nhật 27/7/2017
-----------
Xem thêm:
Tổng hợp các bài viết về Ngu ngơ học làm web