Ngu ngơ học làm web (x9) - CakePHP2 - Tạo link "thân thiện"

Tiếp theo của: Ngu ngơ học làm web (x8) - CakePHP2 – Element
-----

Phần x9. CakePHP2 – Tạo link “thân thiện”


Xem (clip số 15 – chickenrainshop):

Một link (đường dẫn tới một tài nguyên trên mạng) bình thường sẽ có dạng:

http://tên_miền/controller/action/id

Ví dụ,


Một link được gọi là “thân thiện” sẽ có dạng:

http://tên_miền/ten-cua-doi-tuong

Ví dụ,

Để chuyển từ link bình thường sang dạng link “thân thiện” cần thực hiện hai việc:

- Trong link, thay thế vai trò của id bằng ten-cua-doi-tuong (trường slug trong bảng dữ liệu)

- Cấu hình route để chuyển từ  http://tên_miền/controller/action/id sang dạng http://tên_miền/ten-cua-doi-tuong

Làm theo ví dụ trong clip số 15,

Viết lại hàm view trong controller Books, thay vì tìm cuốn sách theo id, sẽ chuyển thành tìm cuốn sách theo slug.

[BooksController.php]
            public function view($slug = null) {
                        $options = [
                                    'conditions' => ['Book.slug' => $slug]
                                    ];
                        $book = $this->Book->find('first', $options);
                        if (empty($book)) {
                                    throw new NotFoundException(__('Không tìm thấy quyển sách này'));
                        }
                        $this->set('book', $book);
            }

Cấu hình route để chuyển từ  http://tên_miền/controller/action/id sang dạng http://tên_miền/ten-cua-doi-tuong:

Vào Config, mở tập tin routes.php, thêm vào dòng lệnh sau:

Router::connect('/:book_title', ['controller' => 'books', 'action' => 'view'], ['pass' => ['book_title']]);

Đọc thêm về routing tại đây: https://book.cakephp.org/2.0/en/development/routing.html để hiểu dòng mã trên.

Có thể hiểu nó như sau:

1. Khi người dùng nhập vào thanh địa chỉ của trình duyệt một đường dẫn có dạng ‘/:book_title’, ở đây:

- Dấu ‘/’ tương đương với thư mục gốc của web (ví dụ: local.chickenrain)

-  ‘:book_title’ là một chuỗi bất kì, đóng vai trò là tham số, và sẽ được sử dụng để truyền vào cho action, ví dụ ‘kham-pha-ngon-ngu-tu-duy’

2. ['controller' => 'books', 'action' => 'view']  nghĩa là website sẽ gọi action (hàm) view trong controller Books.

3. ['pass' => ['book_title'] có nghĩa là chuyển cái chuỗi book_title thành tham số cho action view.

Trong tập tin routes.php, có thể thay dòng mã:

Router::connect('/:book_title', ['controller' => 'books', 'action' => 'view'], ['pass' => ['book_title']]);

Bằng dòng mã sau:

Router::connect('/:chuoi_bat_ki', ['controller' => 'books', 'action' => 'view'], ['pass' => 
['chuoi_bat_ki']]);

Thì website vẫn chạy bình thường.

Phần tiếp theo sẽ gắn giá trị của trường slug vào một mục nào đó trên giao diện, để khi người dùng bấm vào, thì website sẽ thực hiện truy vấn dựa trên giá trị slug.

Ví dụ, thực hiện trên view Books\index (để ý dòng tô đậm), :

<div class="books index">
            <h2><?php echo __('Sách mới'); ?></h2>
            <h4><?php echo $this->Html->link('Xem thêm','/sach-moi') ?></h4>
            <?php foreach($books as $book): ?>
                        <?php echo $this->Html->link($book['Book']['title'], '/'.$book['Book']['slug']); ?> <br>
                        <?php echo $this->Html->image($book['Book']['image'], ['width' => '60px', 'height' => '80px']); ?> <br>
                        Giá bán:<?php echo $this->Number->currency($book['Book']['sale_price'],' VND',['places' => 0,'wholePosition' => 'after']); ?> <br>
                        <?php foreach($book['Writer'] as $writer): ?>
                                    <?php echo $writer['name'].' '; ?>
                        <?php endforeach; ?>
                        <br>
                        <br>
                        <hr>
                        <br>
            <?php endforeach; ?>
</div>

Do mã trong view Books\index và Books\latest_books tương tự nhau, nên sẽ gom lại thành một element, đặt tên cho element này là book.

[View\Elements\book.ctp]
<?php foreach($books as $book): ?>
            <?php echo $this->Html->link($book['Book']['title'], '/'.$book['Book']['slug']); ?> <br>
            <?php echo $this->Html->image($book['Book']['image'], ['width' => '60px', 'height' => '80px']); ?> <br>
            Giá bán:<?php echo $this->Number->currency($book['Book']['sale_price'],' VND',['places' => 0,'wholePosition' => 'after']); ?> <br>
            <?php foreach($book['Writer'] as $writer): ?>
                        <?php echo $writer['name'].' '; ?>
            <?php endforeach; ?>
            <br>
            <br>
            <hr>
            <br>
<?php endforeach; ?>

Gọi element trong các view khác:

[View\Books\index.ctp]
<div class="books index">
            <h2><?php echo __('Sách mới'); ?></h2>
            <h4><?php echo $this->Html->link('Xem thêm','/sach-moi') ?></h4>
            <?php echo $this->element('book', ['books' => $books]); ?>
</div>

[View\Books\latest_books.ctp]
<div class="books index">
            <h2><?php echo __('Sách mới'); ?></h2>
            <p>
                        <?php echo $this->paginator->sort('title','Sắp xếp theo tên sách'); ?>
            </p>
            <?php echo $this->element('book', ['books' => $books]); ?>
            <?php echo $this->element('pagination', ['object' => 'quyển sách']); ?>

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