Tut Magento 004: Layouts, Blocks và Templates trong Magento
Những developer mới làm việc với magento thường bị nhầm lẫn layout với hệ thống hiển thị. Bài viết này sẽ cho chúng ta biết chúng kết nối với nhau như thế nào và chúng có vai trò gì trong cái mô hình MVC.
Trong Magento thì tầng View bao gồm có Block và Template. Block là những đối tượng PHP còn Template là những file kết hợp cả mã html và php (có đuôi là phtml). Bên trong file template có sử dụng $this để reference đến đối tượng block của nó.
1. Block
Magento chia block thành hai loại: structure block và content block.
– Structural Block: đây là những block được tạo ra để định dạng vị trí cho những block khác trong một page. Hãy lấy ví dụ với trang chủ của magento default sử dụng three column layout:
- Head
- Left
- Content
- Right
- Footer
– Content Block: Đây là những block nội dung, chúng được hiển thị bên trong những structure block. Mỗi content block thường hiển thị một khối nội dung nào đó thông qua những file template và chèn vào những block cha là structure block.. Hãy em right column trog hình trên có những content blocks nào:
- Minicart
- Recently viewed product
- Newsletter subsription block
- Poll
Khi nhận được 1 request từ người dùng để hiển thị 1 page:
– Magento sẽ load những vùng cấu trúc
– Mỗi vùng cấu trúc có những content block. Magento sẽ tập hợp những block này lại và gán cho các structure block tương ứng theo layout để xử lý đầu ra.
– Cuối cùng hệ thống sẽ trả lại kết quả sau cùng cho trình duyệt phần nội dung đã được định dạng vị trí.
2. Template
Template là những file phtml được đặt trong thư mục design. Chúng bao gồm cả code php và mã html nên có phần mở rộng là phtml. Những file template có tác dụng lấy dữ liệu từ file block và hiển thị.
Ví dụ về file template:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="?php echo $this->getLang() ?>" lang="<?php echo $this->getLang() ?>"> <head> <?php echo $this->getChildHtml('head') ?> </head> <body class="page-popup <?php echo $this->getBodyClass()?$this->getBodyClass():'' ?>"> <?php echo $this->getChildHtml('content') ?> <?php echo $this->getChildHtml('before_body_end') ?> <?php echo $this->getAbsoluteFooter() ?> </body> </html>
3. Layout
Qua hai phần đầu chúng ta đã hình dung được block là gì và template là gì, chúng có tác dụng gì nhưng vẫn còn có một số vấn đề mà chúng ta chưa hề biết về chúng:
– Làm thế nào để cho magento biết rằng tôi sẽ sử dụng block này trên cái page này?
– Làm thế nào để cho magento biết block nào sẽ được rendering đầu tiên?
– Làm thế nào để có thể gọi hàm getChildHtml trong khi tham số truyền vào không phải là tên của block.
Để các bạn có thể hình dung được dễ dàng hơn mình sẽ đi vào một ví dụ cụ thể, đó là action in “Hello World” ra trình duyệt.
* Bước 1: tạo 1 file layout với tên local.xml
app/design/frontend/base/default/layout/local.xml
<layout version="0.1.0"> <default> <block type="page/html" name="root" output="toHtml" template="magentotutorial/helloworld/simple_page.phtml" /> </default> </layout>
* Bước 2: tạo file template simple_page.phtml app/design/frontend/base/default/template/magentotutorial/helloworld/simple_page.phtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Hello World</title> <style type="text/css"> body { background-color:#f00; } </style> </head> <body> </body> </html>
* Bước 3: trong bước cuối cùng này ta sẽ xem được thành quả bằng cách tạo một action trong một controller bất kỳ và trong đó có gọi hai phương thức loadLayout() và renderLayout():
public function indexAction() { $this->loadLayout(); $this->renderLayout(); }
Sau khi kết thúc hãy clear cache và refresh lại action vừa viết để thấy kết quả hiển thị.
Trong ví dụ trên thì file layout đã map block page/html với template simple_page.phtml để hiển thị trên tất cả các trang của magento (thẻ default của file layout). Như vậy ta đã trả lời được câu hỏi thứ nhất ở trên “Làm thế nào để cho magento biết rằng tôi sẽ sử dụng block này trên cái page này?”.Hai câu hỏi thứ hai và thứ ba mình sẽ trả lời các bạn trong những bài học tiếp theo.
Trong bài viết vẫn còn rất nhiều chỗ thiếu xót và mong được sự góp ý của tất cả các bạn. Cảm ơn và hẹn gặp lại ở bài học tiếp theo. 🙂
Tham khảo: magestore.com, magentoecommerce.com
type phải là đường dẫn đến block mà em thấy page/html chưa phải là đường dẫn đến block nào sao magento có thể hiển thị được ạ
Nó cũng là block An ạ! Em vào thư mục app/code/core/Mage/Page/Block thì sẽ thấy 1 file là Html.php – đây chính là block em cần tìm! 🙂
type=”page/html”
page ở đây là tên khái báo block của module Mage_Page bạn ạ. Nó tương đương với folder Mage/Page/Block 🙂
like 🙂
Hi bạn, bài này bài viết quả thực mình không hiểu mình cũng tạo như bạn và ở phần controller mình cũng cop phần code của bạn vào nhưng mình không biết chạy ở đâu?
Nó sẽ chạy vào controller đầu tiên bạn à! Bạn viết code trong action gì? Có thể view đoạn code đó lên không? Thông thường thì link chạy sẽ là:
http://yoursite.com/routerName/controllerName/actionName
Cảm ơn Blanka Phạm mình đã làm được rồi
Mong rằng có nhiều bài viết mới của bạn
Trân trọng.
Very good!
hóng bác ra full TUT về mảng này,em hóng lâu lắm rồi ah
Mình cũng đang hóng như bạn đây 🙂
“trong bước cuối cùng này ta sẽ xem được thành quả bằng cách tạo một action trong một controller bất kỳ”
controller nó nằm chỗ nào vậy? đến đây thì mình chịu 😐 bạn nói cụ thể đường dẫn giúp mình với
Mình cũng giống bạn, nhưng đọc lại bài tut 3, mình nghĩ nó nằm trong app\code\core\Mage , trong đây là các Module, trong các thư mục Module này sẽ có thư mục Controller, vậy nên có thể vào bất kỳ Controllrt nào để mở file và thêm vào đoạn code đó.
Mình hiểu như vậy có đúng ko anh?
Cũng mới nghiên cứu Magento trên tut của anh từ sáng tới giờ… có vẻ phức tạp hơn Joomla và WordPress.
Theo đường dẫn app/design/frontend/base/default/template/magentotutorial/helloworld/simple_page.phtml. Thì filemagentorutorial/helloworld/simple/simple_page.phtml là mình tự tạo ra hay mặc định là có sẵn ạ….e mới bắt tìm hiểu magento à có gì giúp e với!
Còn ở bước 3 thì file controller là mặc định hay mĩnh cũng tự tạo ra tùy ý ạ !
Thân!
cho hỏi tí. mình viết 1 block code html rồi gọi ra trang page có được không vậy: ví dụ như sau:app/code/core/mage/page/Block/html/tên.php (nhưng trong file tên này mình viết code bằng html có được không) nếu được thì chỉ mình với hay là có cách nào không?
Ở trong Magento bạn không thể viết một file php rồi gọi trực tiếp nó ra thông qua url bạn nhé! Muốn tạo ra một trang hiển thị code html bạn viết thì có thể làm như sau:
1. Tạo ra 1 file template ví dụ sample.phtml sau đó viết mã html, php vào đó
2. Tạo ra 1 controller và viết 1 action gọi đến file template bạn vừa tạo: echo $this->getLayout()->createBlock(‘core/template’)->setTemplate(‘sample/sample.phtml’)->toHtml();
Bây giờ bạn chỉ cần gọi đến action vừa tạo là file template sẽ được hiển thị. Tuy nhiên đây chỉ là một cách hết sức đơn giản và còn rất nhiều cách nữa để hiển thị template.
cho hỏi tí. mình viết 1 block code html rồi gọi ra trang page có được không vậy: ví dụ như sau:app/code/core/mage/page/Block/html/tên.php (nhưng trong file tên này mình viết code bằng html có được không) . còn không chắc mình dô cms viết ah?
Hóng các tut tiếp theo của bác
Ok bạn! 🙂
“Bước 2: tạo file template simple_page.phtml app/design/frontend/base/default/template/magentotutorial/helloworld/simple_page.phtml”
Mình cài đặt magento 1.9.0.1, đường dẫn trên không tồn tại.
“app/design/frontend/base/default/template/” trong thư mục “template” không tồn tại thư mục “magentotutorial”.
Anh BLANKA PHẠM có thể giúp đỡ được không!
Em làm theo 2 bước đầu rùi nhưng đến bước 3 thì không biết làm thế nào ạ.
” tạo một action trong một controller bất kỳ và trong đó có gọi hai phương thức loadLayout() và renderLayout():
Sau khi kết thúc hãy clear cache và refresh lại action vừa viết để thấy kết quả hiển thị.”
thầy có thể lấy ví dụ cụ thể là tạo action trong controller nào, đường dẫn cụ thể chạy như thế nào được không ạ?
Thầy thông cảm, em bây giờ mới tìm hiểu cái này, em gà mờ lắm ạ
Bạn có thể dùng module creator để tạo ra một cái module, trong module này nó sẽ có sẵn những cái action, controller và trong action thì nó gọi sẵn hàm loadLayout và renderLayout rồi bạn à. Giờ mà mình hướng dẫn bạn tạo từ đầu đến cuối thì tương đối mất thời gian. Nếu có thể bạn hãy post chi tiết vấn đề lên forum: http://forum.basetut.com/index.php team của mình sẽ giúp đỡ bạn cụ thể hơn.
Sao e thấy sử dụng nhiều XML vậy a. Học magento này có cần nắm vững XML không ạ?
app/design/frontend/base/default/template/magentotutorial/helloworld/simple_page.phtml mình muốn đặt ở đâu cũng được miễn nằm trong folder template và block có khai báo đường dẫn là tự mapping vào pk, vậy nếu nhiều block sử dụng lại 1 template vẫn được đúng không?
vả lại forum http://forum.basetut.com/index.php die mất rồi
Mình đến bước cuối cùng là gọi đến action tương ứng thì không được, mình thử viết vào action index của IndexController trong module Catalog, đường dẫn mình ghi là http://127.0.0.1/magento/catalog/index/index thì hệ thống vẫn redirect về trang chủ mà không thấy layout mình tạo hiển thị.
Đoạn code ban đầu trong action index của IndexController là $this->_redirect(‘/’); thì mình đã comment nó, thay bằng 2 đoạn code load layout của bạn nhưng nó không có tác dụng, cứ vào action index thì nó vẫn redirect tức là thay đổi trong code của mình không có tác dụng, như vậy lý do là sao ạ?
Em mới học Magento lần đầu. Trong bài này làm được 2 bước đầu rồi nhưng bước 3 em không biết thực hiện như thế nào, ở file nào, mong anh có thể chỉ rõ cho em với.
Cảm ơn anh