BÀI 4: DRUPAL NODE

We encourage users to post events happening in the community to the community events group on https://www.drupal.org.
king1031988's picture

1. NODE LÀ GÌ?
+ Một trong những câu hỏi đầu tiên mà những người mới phát triển với framework Drupal là : Node là gì?
+ Node là những phần (piece) nội dung riêng biệt, Drupal sẽ gán cho mỗi node một số ID được gọi là node ID ($nid). Thông thường, mỗi node sẽ có một title để admin có thể xem danh sách các nội dung của nó.
+ Có nhiều kiểu node khác nhau, những kiểu node phổ biến như là : “blog entry”, “poll”, “book page”…
+ Tất cả các kiểu nội dung được xây dựng trên node đều có cùng một cấu trúc dữ liệu bên dưới giống nhau. Điều này nghĩa là đối với các thao tác trên node, bạn có thể xem như tất cả các nội dung là giống nhau.
+ Việc thực hiện các thao tác trên node rất dễ dàng : tìm kiếm, tạo, chỉnh sửa, quản lý… tất cả đều được cung cấp sẵn trong Drupal vì tất cả các kiểu nội dung đều là node.
Hình ảnh

+ Các kiểu node đều kế thừa từ node cơ bản và thường thêm vào các thuộc tính dữ liệu riếng của chúng.
+ Tất cả các node có các thuộc tính sau (chúng được lưu trữ bên trong node và bảng dữ liệu node_revisions) :
- nid : ID để nhận biết node
- vid : revison ID của node, cần thiết bởi vì Drupal có thể lưu trữ số lần xem node
- type : mỗi node sẽ có một kiểu node. Vd: blog, story…
- title : một chuỗi dài 128 kí tự.
- uid : ID user, người tạo ra node. Mặc định, tất cả các node đều chỉ có 1 tác giả.
- status : giá trị 0 nghĩa là chưa công bố (publish), nội dung sẽ được ẩn đi đối với những người không có quyền “administer nodes”. Giá trị 1 có nghĩa là node đã publish, nội dung có thể thấy bởi những người có quyền “access content”. Việc thể một node đã publish có thể được cấm lại bởi hệ thống điều khiến quyền truy cập của Drupal.
- created : thời gian mà node được tạo ra.
- changed : thời gian mà node được thay đổi.
- comment : một số nguyên cho biết trang thái các comment của node. Có thể có 3 giá trị :
- 0: comment bị disable. Đây là giá trị mặc định khi module comment được bật lên.
- 1: không được phép thêm comment.
- 2: comment có thể được nhìn thấy và user có thể thêm comment mới.
- promote : một số nguyên xác định khi nào thì thể hiện node ở front-page, có 2 giá trị :
- 1: node sẽ được thể hiện ở front-page.
- 0: node không được thể hiện ở front-page.
- moderate: một số nguyên, giá trị 0 cho biết việc điều chỉnh (moderation) bị tắt, và 1 là bật.
- sticky : khi Drupal thể hiện một danh sách các node trên một trang, mặc nhiên nó sẽ liệt kê danh sách các node có đánh dấu sticky trước, sau đó sẽ đến các node chưa đánh dấu và xếp theo ngày được tạo. Giá trị 1 nghĩa là sticky và 0 nghĩa là unsticky.
+ Nếu bạn sử dụng hệ thống node revision, Drupal sẽ tạo một revision chứa thông tin về người cuối cùng thay đổi nó.

2. KHÔNG PHẢI TẤT CẢ ĐỀU LÀ NODE.
+ User, block và comment không phải là node.
+ Node thường có “title” và “body” còn cấu trúc user thì không cần cái này. Hơn nữa user cần email-address, user name và cách bảo vệ an toàn để lưu trữ password.
+ Block là một giải pháp lưu trữ cho từng mảnh nội dung nhỏ hơn như : menu navigation, searcho box, danh sách các comment gần đây…
+ Comment cũng không phải là node. Nó có thể có 100 comment hoặc hơn trên một trang và nếu những comment này đều phải đi qua hệ thống hook menu thì số lần thực thi sẽ rất kinh khủng.

3. TẠO MỘT NODE MODULE.
+ Về mặt truyền thống, khi bạn muốn tạo một kiểu nội dung mới trong Drupal, bạn sẽ viết một node module, cái sẽ chịu trách nhiệm và cung cấp mọi thứ cho kiểu nội dung mà bạn cần. Chúng ta gọi đó là truyền thống vì các phát triển gần đây trong framework Drupal cho phép bạn tạo ra kiểu nội dung bằng giao diện administrative. Chúng ta sẽ xem xét cả 2 giải pháp trên.
+ Chúng ta sẽ viết một module để user có thể thêm vào một joke (câu nói đùa) lên site. Mỗi joke sẽ có một title, nội dung của nó và điểm nút (punch-line). Bạn có thể dễ dàng sử dụng thuộc tính “title” sẵn có của node cho title của joke và phần nội dung có thể dùng thuộc tính “body” của node. Nhưng bạn cần phải tạo một bảng dữ liệu mới để lưu trữ punch-line :

Code: Chọn hết
CREATE TABLE joke (
nid int unsigned NOT NULL default '0',
vid int unsigned NOT NULL default '0',
punchline text NOT NULL,
PRIMARY KEY (nid,vid),
UNIQUE KEY vid (vid),
KEY nid (nid)
);

+ Bạn lưu trữ node ID để biết được node này tham chiếu đến đâu trong bảng node_revisions, cái sẽ lưu trữ title và body. Cột vid để bạn có thể dùng bộ điều khiển revision sẵn có của Drupal.
+ Tạo một thư mục có tên là joke tại đường dẫn :
sites/all/modules/custom

+ Tạo file joke.install và đặt nó vào thư mục joke mới tạo. Cài đặt nó như sau :

Code: Chọn hết
<?php
// $Id$
/**
* Implementation of hook_install().
*/
function joke_install() {
switch ($GLOBALS['db_type']) {
case 'mysql':
case 'mysqli':
db_query("CREATE TABLE {joke} (
nid int unsigned NOT NULL default '0',
vid int unsigned NOT NULL default '0',
punchline text NOT NULL,
PRIMARY KEY (nid,vid),
UNIQUE KEY vid (vid),
KEY nid (nid)
) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
break;
case 'pgsql':
db_query("CREATE TABLE {joke} (
nid int unsigned NOT NULL default '0',
vid int unsigned NOT NULL default '0',
punchline text NOT NULL,
PRIMARY KEY (nid,vid),
UNIQUE KEY vid (vid),
KEY nid (nid)
)");
break;
}
}

/**
* Implementation of hook_uninstall().
*/
function joke_uninstall() {
db_query('DROP TABLE {joke}');
}

+ Tạo file joke.info :

Code: Chọn hết
; $Id$
name = Joke
description = Provides a joke node type with a punchline.
version = "1.0"

+ Tạo filel joke.module :

Code: Chọn hết
<?php
// $Id$
/**
* @file
* Provides a "joke" node type.
*/

4. CUNG CẤP THÔNG VỀ KIỂU NODE.
+ Bây giờ bạn đã sẵn sàng để thêm vào các hook cho joke.module. Đầu tiên chúng ta sẽ cài đặt hook_node_info(). Drupal sẽ gọi hook này khi mà nó phát hiện các node hiện có trong hệ thống. Bạn sẽ cung cấp các thông tin dữ liệu về node của mình :

Code: Chọn hết
/**
* Implementation of hook_node_info().
*/
function joke_node_info() {
// We return an array since a module can define multiple node types.
// We're only defining one node type, type 'joke'.
return array(
'joke' => array(
'name' => t('Joke'), // Required.
'module' => 'joke', // Required.
'description' => t('Tell us your favorite joke!'), // Required.
'has_title' => TRUE,
'title_label' => t('Title'),
'has_body' => TRUE,
'body_label' => t('Joke'),
'min_word_count' => 2,
'locked' => TRUE
)
);
}

+ Một module có thể định nghĩa nhiều kiểu node, vì vậy giá trị trả về nên là một mảng. Các giá trị dữ liệu có thể được cung cấp trong hàm hook node_info() :
- name (require): tên của node thể hiện trên site. Ví dụ : nếu giá trị là “joke”, Drupal sẽ dùng nó để làm tiêu đề cho form thể hiện nó.
- module (require): tên tiền tố của hàm callback mà Drupal sẽ tìm kiếm. Chúng ta dùng “joke” và Drupal sẽ tìm những hàm callback có tên là joke_validate(), joke_insert(), joke_delete()…
- description: mô tả về nội dung của kiểu node được sử dụng. Đoạn text này sẽ được thể hiện trong danh sách của trang “Create content”.
- has_title: giá trị boolean cho biết kiểu nội dung sử dụng có title hay không. Giá trị mặc định là TRUE.
- title_label: text label cho title. Nó chỉ xuất hiện khi has_title mang trị là TRUE.
- has_body : cho biết có body hay không.
- body_label: text label cho body. Nó chỉ xuất hiện khi has_body mang trị là TRUE.
- min_word_count: số từ nhỏ nhất mà body cần có.
- lock: giá tị boolean cho biết nội dung có được khóa hay không từ site administator.

+ Định nghĩa hàm menu callback :

Code: Chọn hết
/**
* Implementation of hook_menu().
*/
function joke_menu($may_cache) {
$items = array();
// Do not cache this menu item during the development of this module.
if (!$may_cache) {
$items[] = array(
'path' => 'node/add/joke',
'title' => t('Joke'),
'access' => user_access('create joke'),
);
}
return $items;
}

+ Bằng việc sử dụng hàm callback đã được định nghĩa sẵn, bạn sẽ giảm được rất nhiều công việc bởi vì nó đã “map” sẵn đến nhân node validation (kiểm tra) và submission routine (thủ tục xem xét), bạn chỉ cần quan tâm đến dữ liệu mà bạn thêm vào đó (đó là puch-line mà module cần xử lý) vì module node sẽ xử lý việc tạo, kiểm tra và xử lý title, body cùng những thuộc tính khác.

5. ĐỊNH NGHĨA NODE TYPE VỚI QUYỀN TRUY CẬP.
+ Trong menu item, bạn cũng có thể thêm vào việc kiểm tra lại quyền “create joke”. Chúng ta sẽ tạo nó bằng hook _perm() :

Code: Chọn hết
/**
* Implementation of hook_perm().
*/
function joke_perm() {
return array('create joke', 'edit own joke');
}

+ Bây giờ nếu bạn vào Adminster  User manager  Access control, quyền mới mà bạn định nghĩa sẽ xuất hiện bên dưới :

6. XÂY DỰNG NODE BẰNG MODULE CCK.
+ Việc tạo node bằng cách viết module joke.module quá nhiều công đoạn phức tạp. Bạn muốn tạo một node của mình mà không cần lập trình? Hãy dùng module CCK của Drupal.
+ CCK đã được cung cấp trong bản 5.x. Bạn có thể tạo mới các kiểu nội dung (chẳng hạn như joke) thông qua giao diện administative tại Administer  Content Manager  Content Type. Bạn phải đảm bảo rằng các kiểu nội dung không trùng tên để tránh xung đột namespace.
+ Một phần của CCK vẫn sẽ được lưu trong nhân để có thể tạo ra các fields ngoài title và body cho các kiểu nội dung mới.
+ Ví du : trong joke.module bạn cần 3 fields: title, body và punchline. Hàm dùng hook_node_info() để đặt lại nhãn cho body là Joke, tạo ra fields funchline bằng cách cài đặt một vài hook khác và tạo ra bảng để lưu trữ punchline. Trong CCK, bạn chỉ đơn giản tạo mới 1field mang tên punchline và thêm nó vào kiểu nội dung của bạn. CCK sẽ tự làm các công việc lưu trữ, nhận và xóa dữ liệu cho bạn.

7. NGĂN CHẶN QUYỀN TRUY CẬP ĐẾN CÁC NODE.
+ Có nhiều cách để chặn quyền truy cập đến các node. Bạn có thể dùng hook_access()và hook_perm() nhưng Drupal cung cấp bộ điều khiển try cập sử dụng bảng node_access và 2 hook_node_grants(), hook_node_access_records().
+ Định nghĩa Node-Grants : có ba quyền truy cập cơ bản cho node là: xem, chỉnh sửa và xóa. Các module sẽ cung cấp quyền truy cập cho các kiểu node qua hook node_access(). Nếu module không cung cấp vị trí quyền truy cập cho phép, Drupal sẽ hỏi tất cả các module đã định nghĩa node access chịu trách nhiệm xem các thao tác có được cho phép hay không. Nó làm điều này phản hồi lại hook_node_grants() với một danh sách các ID cho mỗi realm (lĩnh vực) dành cho người dùng hiện tại.
+ Realm là gì? Realm là một chuỗi arbitrary (chuyên quyền) cho phép nhiều module node chia sẻ quyền bảng node_access.

Comments

Bạn ơi, mình đang giả dụ thế

luatviettin's picture

Bạn ơi, mình đang giả dụ thế này: cái gì cũng lưu vào node mà không lưu sang bản khác, nếu bạn có 5 triệu bản ghi và 1 triệu view/ ngày thì bảng node này có quá bận rộn không nhỉ ? đang lo lắng vì thấy drupal load đơ đơ !

Cam on ban

Nhucoder's picture

Minh dang thac mac ve node thi doc duoc bai nay. Cam on ban da viet va chia se nhe.

đơn giản hơn chút ít

Shyvana's picture

Đệm dữ liệu trong Drupal 6.x có đơn giản hơn chút ít: tham số $data được truyền vào có thể là một mảng hay một đối tượng (Drupal 5.x chỉ chấp nhận kiểu chuỗi).

Cảm ơn bạn!

thietbidiencamtay's picture

Cảm ơn bạn nhiều, rất rõ ràng và dễ hiểu.

Cảm ơn bạn

dannytrinh's picture

Cảm ơn bạn, hơi dài nhưng rất chi tiết và dễ hiểu

Cám ơn Bác đã chia sẻ

techvccloud's picture

Bài viết của bác rất hay và chi tiết. em cám ơn bác nhiều ạ

Tech.vccloud.vn là blog công nghệ hàng đầu tại Việt Nam