Hướng dẫn viết module cho phiên bản NukeViet 3.0

HƯỚNG DẪN VIẾT MODULE CHO PHIÊN BẢN NUKEVIET CMS 3.0

CÁC BÀI VIẾT:

1. Giới thiệu về cấu trúc cơ bản của module
2. Cách viết một module đơn giản
3. Thêm link quản lý module vào menu quản trị
4. Thêm 1 submenu quản lý module trong admin
5. Kết nối với file ngôn ngữ
6. Kết nối với cơ sở dữ liệu
7. Kết nối với template engine (Xtemplate)
8. Các chú ý khi lập trình

1. Cấu trúc cơ bản khi bắt đầu viết module
Khác với những phiên bản trước đây của hệ thống nukeviet, trong phiên bản mới này việc đóng gói module được tối ưu, các file và folder của module đều được đưa vào trong 1 thư mục.
Một module example có cơ sở dữ liệu và có phần quản trị cho người dùng có cấu trúc căn bản như sau:

admin
—-.htaccess
—-main.php
modules
funcs
—-index.html
—-.htaccess
—-main.php
language
—-index.html
—-.htaccess
—-vi.php
—-vi_admin.php
js
—-.htaccess
—-javascript.js
action.php
admin.functions.php
functions.php
version.php
index.html
.htaccess

2. Cách viết một module đơn giản

Chú ý: Tên module mới chỉ gồm các chữ cái, số và dấu gạch ngang, bắt buộc phải bắt đầu bằng một chữ cái.
- Trong bài viết này chúng ta xây dựng một module đơn giản để xuất ra nội dung,:
Hello world!!!
- Các bước chuẩn bị:
Tạo các file và folder như sau:

$ modules/example/index.html
$ modules/example/funcs/main.php
$ modules/example/funcs/index.html
$ modules/example/admin.functions.php
$ modules/example/functions.php
$ modules/example/theme.php
$ modules/example/version.php

modules/example/functions.php

<?php

if (!defined('NV_SYSTEM'))
die('Stop!!!');

define('NV_IS_MOD_EXAMPLE', true);
?>

modules/example/version.php

<?php

if ( ! defined( 'NV_ADMIN' ) or ! defined( 'NV_MAINFILE' )) die( 'Stop!!!' );

$module_version = array(
"name" => "Example", //
"modfuncs" => "main", // "is_sysmod" => 0, // "virtual" => 0, // "version" => "3.0.01", //
"date" => "2 Oct 2010 09:47:15 GMT", // "author" => "http://www.thegioimanguon.com", // "note" => ""
);

?>

Các chú ý khi khai báo trong file version.php
- “modfuncs” => “main”, là danh sách các các function tương ứng với tên các file trong folder funcs của module.
- “virtual” => 0: Module không được ảo hóa
- “virtual”=>1: Module được ảo hóa. modules/example/funcs/main.php

<?php

if ( ! defined( 'NV_IS_MOD_EXAMPLE' ) ) die( 'Stop!!!' );
$contents = "Hello world";
include ( NV_ROOTDIR . "/includes/header.php" );
echo nv_site_theme( $contents );
include ( NV_ROOTDIR . "/includes/footer.php" );
?>

Sau khi thực hiện các bước như trên ta có được 1 module đơn giản, Để xem kết quả bạn đăng nhập vào khu vực quản trị với quyền admin, cài đặt và click hoạt module để có thể xem module qua link:

http://mydomain.com/index.php?lang=vi&nv=example

Nếu bạn muốn thêm 1 func mới cho module bạn tạo mới 1 file (new.php) trong thư mục:
modules/example/funcs/

Sau đó bạn cần đăng nhập và khu vực quản trị kích hoạt các function này.

3. Thêm link quản lý module vào menu quản trị
modules/example/admin/functions.php

<?php

if (! defined('NV_ADMIN') or ! defined('NV_MAINFILE') or ! defined('NV_IS_MODADMIN')
)
die('Stop!!!');
$allow_func = array('main');
define( 'NV_IS_EXAMPLE_ADMIN', true );

?>

modules/example/admin/main.php

<?php

if ( ! defined( 'NV_IS_EXAMPLE_ADMIN' ) )
{
die( 'Stop!!!' );
}
$page_title = "main";
$contents = "test content";

include ( NV_ROOTDIR . "/includes/header.php" );
echo nv_admin_theme( $contents );
include ( NV_ROOTDIR . "/includes/footer.php" );
?>

Để có thể quản trị module thì trong thư mục admin bắt buộc phải chứa file: main.php và trong thư mục
tương ứng với các file functions.php, version.php bắt buộc phải chứa file: admin.functions.php

Chú ý: Để các function có thể hoạt động được thì function phải được gán vào mảng $allow_func

Khi đó danh mục các file của module gồm:

$ modules/example/admin/index.html
$ modules/example/admin/functions.php
$ modules/example/admin/main.php
$ modules/example/index.html
$ modules/example/funcs/main.php
$ modules/example/funcs/index.html
$ modules/example/functions.php
$ modules/example/version.php

4. Thêm 1 submenu quản lý module trong admin
Thay đổi lại file modules/example/admin.functions.php

<?php

if ( ! defined( 'NV_ADMIN' ) or ! defined( 'NV_MAINFILE' ) or ! defined( 'NV_IS_MODA DMIN' ) ) die( 'Stop!!!' );
$allow_func = array('main');
$submenu['add'] = "add";
$submenu['edit'] = "edit";
$allow_func = array('main', 'add', 'edit');

define( 'NV_IS_EXAMPLE_ADMIN', true );

?>

5. Kết nối với file ngôn ngữ
Sửa lại nội dung file modules/example/admin.functions.php

<?php

if ( ! defined( 'NV_ADMIN' ) or ! defined( 'NV_MAINFILE' ) or ! defined( 'NV_IS_MODA DMIN' ) ) die( 'Stop!!!' );
$allow_func = array('main');
$submenu['add'] = $lang_module['example_add'];
$submenu['edit'] = $lang_module['example_edit'];
$allow_func = array('main', 'add', 'edit');

define( 'NV_IS_EXAMPLE_ADMIN', true );

?>

Quy tắc đặt tên file ngôn ngữ: Các file ngôn ngữ được đặt trong thư mục language của module, Nếu ngôn ngữ cho module sẽ đặt tên: vi.php, en.php, ngôn ngữ cho admin admin_vi.php, admin_en.php

Ta tạo file ngôn ngữ tiếng Việt cho module example:
modules/example/language/ admin_vi.php

<?php

if (! defined('NV_ADMIN') or ! defined('NV_MAINFILE')){
die('Stop!!!');
}

$lang_translator['author'] ="http://www.thegioimanguon.com";
$lang_translator['createdate'] ="04/03/2010, 15:22";
$lang_translator['copyright'] ="";
$lang_translator['info'] ="";
$lang_translator['langtype'] ="lang_module";

$lang_module['example_add']= "Thêm";
$lang_module['example_edit']= "Sửa";

?>

Khi đó danh mục các file của module gồm:

$ modules/example/admin/index.html
$ modules/example/admin/main.php
$ modules/example/index.html
$ modules/example/funcs/main.php
$ modules/example/funcs/index.html
$ modules/example/admin.functions.php
$ modules/example/functions.php
$ modules/example/theme.php
$ modules/example/version.php
$ modules/example/language/vi_admin.php
$ modules/example/language/en_admin.php

6. Kết nối với cơ sở dữ liệu

modules/example/action.php

<?php

if ( ! defined( 'NV_IS_FILE_MODULES' ) ) die( 'Stop!!!' );

$sql_drop_module = array();

$sql_drop_module[] = "DROP TABLE IF EXISTS " . $db_config['prefix'] . "_" .$lang . "_" . $module_data . "`;";

$sql_create_module = $sql_drop_module;

$sql_create_module[] = "CREATE TABLE " . $db_config['prefix'] . "_" . $lang . "_" . $module_data . "` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL, PRIMARY KEY (`id`)
) ENGINE=MyISAM	DEFAULT CHARSET=utf8";
?>

Sau khi tạo xong file action.php, bạn vào phần quản lý module để cài lại module example. Khi đó cơ
sở dữ liệu sẽ được tạo tự động.

Sửa lại file modules/example/admin/add.php

<?php

if ( ! defined( 'NV_IS_EXAMPLE_ADMIN' ) )
{
die( 'Stop!!!' );
}
$page_title = $lang_module['example_add'];
$add = 0;
$error = "";

if ( $nv_Request->get_int( 'add', 'post' ) == 1 )
{
$title = filter_text_input( 'title', 'post', '', 1 );
if ( empty( $title ) )
{
$error = $lang_module['err_title'];
}
else
{

$query = "INSERT INTO `" . NV_PREFIXLANG . "_" . $module_data . "` (`id`, `title`) VALUES (NULL, " . $db->dbescape( $title ) . ")";
if ( $db->sql_query_insert_id( $query ) )
{
$db->sql_freeresult();
Header( "Location: " . NV_BASE_ADMINURL . "index.php?" . NV_NAME_VARIABL E . "=" . $module_name . "" );
die();

}
else
{

}
}
}

$error = $lang_module['errorsave'];

if ( $error != "" )
{
$contents .= "<div class=\"quote\" style=\"width:780px;\">\n";
$contents .= "<blockquote class=\"error\"><span>" . $error . "</span></blockquote>\n";
$contents .= "</div>\n";
$contents .= "<div class=\"clear\"></div>\n";
}
$contents .= "<form action=\"" . NV_BASE_ADMINURL . "index.php\" method=\"POST\">\n";
$contents .= "<table class=\"tab1\">\n";
$contents .= " 	<tr>\n";
$contents .= " 	<td width=\"30%\"><strong>" . $lang_module['title'] . "<strong></td>\n";
$contents .= " 	<td>\n";
$contents .= " 	<input type=\"text\" name=\"title\" size=\"100\">\n";
$contents .= " 	</td>\n";
$contents .= " 	</tr>\n";
$contents .= "</table>\n";
$contents .= "<table class=\"tab2\" align=\"center\">\n";
$contents .= " 	<tr>\n";
$contents .= " 	<td style=\"text-align:center;\">\n";
$contents .= " 	<input type=\"submit\" value=\"" . $lang_module['save'] . "\"/>\n";
$contents .= " 	<input name=\"add\" type=\"hidden\" value=\"1\" />\n";
$contents .= " 	<input type=\"hidden\" name =\"" . NV_NAME_VARIABLE . "\"value=\"" . $module_name . "\" />";
$contents .= " 	<input type=\"hidden\" name =\"" . NV_OP_VARIABLE . "\ "value=\"" . $op . "\" />";
$contents .= " 	</td>\n";
$contents .= " 	</tr>\n";
$contents .= "</table>\n";
$contents .= "</form>\n";

include ( NV_ROOTDIR . "/includes/header.php" );
echo nv_admin_theme( $contents );
include ( NV_ROOTDIR . "/includes/footer.php" );

?>

Sửa lại file modules/example/language/vi_admin.php

<?php

if (! defined('NV_ADMIN') or ! defined('NV_MAINFILE')){
die('Stop!!!');
}

$lang_translator['author'] ="http://www.thegioimanguon.com";
$lang_translator['createdate'] ="04/03/2010, 15:22";
$lang_translator['copyright'] ="";
$lang_translator['info'] ="";
$lang_translator['langtype'] ="lang_module";

$lang_module['list']= "Danh sách bài viết";
$lang_module['example_add']= "Thêm mới bài viết";
$lang_module['example_edit']= "Sửa bài viết";
$lang_module['example_del']= "Xóa bài viết";
$lang_module['id']= "ID";
$lang_module['title']= "Tiêu đề";
$lang_module['func']= "Chức năng";
$lang_module['save'] = "Lưu";
$lang_module['err_title'] = "Bạn phải nhập tên";
$lang_module['errorsave'] = "Vì một số lý do nào đó mà tên không được lưu vào cơ sở dữ liệu";

?>

Sửa lại file modules/example/admin/main.php

<?php

if ( ! defined( 'NV_IS_EXAMPLE_ADMIN' ) ) {
die( 'Stop!!!' );
}
$page_title = $lang_module['list'];

$contents = "";
$contents .= "<table class=\"tab1\">\n";
$contents .= "<thead>";
$contents .= "<tr style=\"text-align:center;\">\n";
$contents .= "<td>" . $lang_module['id'] . "</td>\n";
$contents .= "<td>" . $lang_module['title'] . "</td>\n";
$contents .= "<td>" . $lang_module['func'] . "</td>\n";
$contents .= "</tr>\n";
$a = 0;
$sql = "SELECT id, title FROM `" . NV_PREFIXLANG . "_" . $module_data . "`";
$resuilt = $db->sql_query( $sql );
while ( $row = $db->sql_fetchrow( $resuilt ) )
{
$class = ( $a % 2 == 0 ) ? "" : " class=\"second\"";
$contents .= "<tbody" . $class . ">";
$contents .= "<tr>\n";
$contents .= "<td style=\"text-align:center;\">" . $row['id'] . "</td>\n";
$contents .= "<td>" . $row['title'] . "</td>\n";
$contents .= "<td style=\"text-align:center;\">
<a href=\"index.php?" . NV_NAME_VARIABLE . "=" . $module_name . "&" . NV_OP_ VARIABLE . "=edit&amp;id=" . $row['id'] . "\">" . $lang_module['example_edit'] . "</ a> -
<a href=\"index.php?" . NV_NAME_VARIABLE . "=" . $module_name . "&" . NV_OP_VARIABLE . "=del&amp;id=" . $row['id'] . "\">" . $lang_module['example_del'] . "</a>
</td>\n";
$contents .= "</tr>\n";
$contents .= "</tbody>\n";
$a++;
}
$contents .= "</table>\n";
include ( NV_ROOTDIR . "/includes/header.php" );
echo nv_admin_theme( $contents );
include ( NV_ROOTDIR . "/includes/footer.php" );
?>

Sửa lại file modules/example/funcs/main.php

<?php

if ( ! defined( 'NV_IS_MOD_EXAMPLE' ) ) die( 'Stop!!!' );
$sql = "SELECT `id`, `title` FROM `" . NV_PREFIXLANG . "_" . $module_data . "`";
$result = $db->sql_query( $sql );
$contents = "<table>\n";
$a = 1;
while ( $row = $db->sql_fetchrow( $result ) )
{
$contents .= "<tr>\n";
$contents .= "<td>" . $a . "</td><td>" . $row['title'] . "</td></tr>\n";
$contents .= "</tr>\n";
$a ++;
}
$contents .= "</table>\n";
include ( NV_ROOTDIR . "/includes/header.php" );
echo nv_site_theme( $contents );
include ( NV_ROOTDIR . "/includes/footer.php" );
?>

Danh mục các file:

$ modules/example/admin/index.html
$ modules/example/admin/main.php
$ modules/example/index.html
$ modules/example/funcs/main.php
$ modules/example/funcs/index.html
$ modules/example/admin.functions.php
$ modules/example/functions.php
$ modules/example/action.php
$ modules/example/language/vi_admin.php
$ modules/example/language/en_admin.php

7. Kết nối với template engine (Xtemplate)

Bắt đầu từ phiên bản nukeviet 3.0, hệ thống template được tách biệt hẳn ra với mã php. Hiện tại, hệ thống template của nukeviet đang sử dụng Xtemplate để xử lý cho việc tách biệt mã php và html. Để tìm hiểu thêm về cách viết Xtemplate, các bạn có thể đọc thêm tài liệu về tại địa chỉ: http://sourceforge.net/projects/xtpl/files/XTemplate%20PHP5/
Sơ đồ template admin control panel sử dụng Xtemplate

themes
—-admin_default
css
—-example.css
images
js
modules
—-example.php
tpl
—-example.tpl

Để sử dụng Xtemplate cho admin control panel của module Example ta tiến hành các bước như sau:
Sửa lại file modules/example/admin/main.php

<?php

if ( ! defined( 'NV_IS_EXAMPLE_ADMIN' ) ) {
die( 'Stop!!!' );
}
$page_title = $lang_module['list'];
$sql = "SELECT id, title FROM `" . NV_PREFIXLANG . "_" . $module_data . "`";
$resuilt = $db->sql_query( $sql );
while ( $row = $db->sql_fetchrow( $resuilt ) )
{
$content[] = $row;
}
$contents = call_user_func("main", $content); include ( NV_ROOTDIR . "/includes/header.php" ); echo nv_admin_theme( $contents );
include ( NV_ROOTDIR . "/includes/footer.php" );
?>

Sửa lại file modules/example/admin/add.php

<?php

if ( ! defined( 'NV_IS_EXAMPLE_ADMIN' ) )
{
die( 'Stop!!!' );
}
$page_title = $lang_module['example_add'];
$add = 0;
$error = "";

if ( $nv_Request->get_int( 'add', 'post' ) == 1 )
{
$title = filter_text_input( 'title', 'post', '', 1 );
if ( empty( $title ) )
{

}
else
{

$error = $lang_module['err_title'];

$query = "INSERT INTO `" . NV_PREFIXLANG . "_" . $module_data . "` (`id`,`title`) VALUES (NULL, " . $db->dbescape( $title ) . ")";
if ( $db->sql_query_insert_id( $query ) )
{
$db->sql_freeresult();
Header( "Location: " . NV_BASE_ADMINURL . "index.php?" .
NV_NAME_VARIABLE . "=" . $module_name . "" );
die();

}
else
{

}
}
}

$error = $lang_module['errorsave'];
$contents = call_user_func("add", $error); include ( NV_ROOTDIR . "/includes/header.php" ); echo nv_admin_theme( $contents );
include ( NV_ROOTDIR . "/includes/footer.php" );

?>

Sửa lại file modules/example/admin/edit.php

<?php

if ( ! defined( 'NV_IS_EXAMPLE_ADMIN' ) )
{
die( 'Stop!!!' );
}

$error = "";
$page_title = $lang_module['example_edit'];

$id = $nv_Request->get_int( 'id', 'get,post', 0 );
if ( $id > 0 )
{
if ( $nv_Request->get_int( 'save', 'post' ) == 1 )
{
$title = filter_text_input( 'title', 'post', '', 1 );
if ( empty( $title ) )
{

}
else
{

$error = $lang_module['err_title'];

$query = "UPDATE `" . NV_PREFIXLANG . "_" . $module_data . "` SET `title` = " . $db->dbescape( $title ) . " WHERE `id` =" . $id . "";
$db->sql_query( $query );
$db->sql_freeresult();
Header( "Location: " . NV_BASE_ADMINURL . "index.php?" . NV_NAME_VARIABLE . "=" . $module_name . "" );
}

}
else
{

$sql = "SELECT title FROM `" . NV_PREFIXLANG . "_" . $module_data . "` WHERE `id` = '" . $id . "'";
$resuilt = $db->sql_query( $sql );
list( $title ) = $db->sql_fetchrow( $resuilt );
}
$contents = call_user_func("edit",$id, $title, $error);
}
include ( NV_ROOTDIR . "/includes/header.php" );
echo nv_admin_theme( $contents );
include ( NV_ROOTDIR . "/includes/footer.php" );

?>

Thêm file themes/admin_default/modules/example.php. Lưu ý: Tên file trong thư mục module của
template admin phải trùng tên với tên module.

<?php
function add($error)
{
global $global_config, $lang_module,$module_data, $db_config, $nv_Request,
$module_name, $op;
$xtpl = new XTemplate ( "example.tpl", NV_ROOTDIR . "/themes/" .
$global_config ['module_theme'] . "/modules" );
$xtpl->assign('LANG',$lang_module);
$xtpl->assign('NV_BASE_ADMINURL',NV_BASE_ADMINURL);
$xtpl->assign('NV_NAME_VARIABLE',NV_NAME_VARIABLE);
$xtpl->assign('MODULE_NAME', $module_name);
$xtpl->assign('OP', $op);
if(!empty($error))
{
$xtpl->assign('ERROR',$error);
$xtpl->parse('add.error');
}
$xtpl->assign('NV_OP_VARIABLE',NV_OP_VARIABLE);
$xtpl->parse('add');
return $xtpl->text('add');
}
function edit( $id, $title, $error)
{
global $global_config, $lang_module,$module_data, $db_config, $nv_Request,
$module_name, $op;
$xtpl = new XTemplate ( "example.tpl", NV_ROOTDIR . "/themes/" .
$global_config ['module_theme'] . "/modules" );
$xtpl->assign('LANG',$lang_module);
$xtpl->assign('NV_BASE_ADMINURL',NV_BASE_ADMINURL);
$xtpl->assign('NV_NAME_VARIABLE',NV_NAME_VARIABLE);
$xtpl->assign('MODULE_NAME', $module_name);
$xtpl->assign('TITLE', $title);
$xtpl->assign('ID', $id);
$xtpl->assign('OP', $op);
if(!empty($error))
{
$xtpl->assign('ERROR',$error);
$xtpl->parse('edit.error');
}
$xtpl->assign('NV_OP_VARIABLE',NV_OP_VARIABLE);
$xtpl->parse('edit');
return $xtpl->text('edit');
}
function main($content)
{
global $global_config, $lang_module,$module_data, $db_config, $nv_Request,
$module_name, $op;
$xtpl = new XTemplate ( "example.tpl", NV_ROOTDIR . "/themes/" .
$global_config ['module_theme'] . "/modules" );
$xtpl->assign('LANG',$lang_module);
if(!empty($content))
{
foreach($content as $i => $row)
{
$xtpl->assign('CLASS',($i % 2)	? '' : ' class="second"');
$xtpl->assign('EDIT',"<a href=\"index.php?" . NV_NAME_VARIABLE . "=" .
$module_name . "&" . NV_OP_VARIABLE . "=edit&amp;id=" . $row['id'] . "\">" .
$lang_module['example_edit'] . "</a>");
$xtpl->assign('DEL',"<a href=\"index.php?" . NV_NAME_VARIABLE . "=" .
$module_name . "&" . NV_OP_VARIABLE . "=del&amp;id=" . $row['id'] . "\">" .
$lang_module['example_del'] . "</a>");
$xtpl->assign('CONTENT', $row);
$xtpl->parse('main.loop');
}
}
$xtpl->parse('main');
return $xtpl->text('main');
}
?>

Thêm file themes/admin_default/modules/example.tpl

<!-- BEGIN: add -->
<form action="{NV_BASE_ADMINURL}index.php" method="POST">
<table class="tab1">
<tr>
<td width="30%"><strong>{LANG.title}</strong></td>
<td><input name="title" type="text" size="100" /></td>
</tr>
</table>
<table class="tab2" align="center">
<tr>
<td style="text-align:center;">
<input type="submit" value="{LANG.save} "/>
<input name="add" type="hidden" value="1" />
<input type="hidden" name =" {NV_NAME_VARIABLE} "value="
{MODULE_NAME} " />
</tr>
</td>
<input type="hidden" name =" {NV_OP_VARIABLE} "value=" {OP} " />
</table>
</form>
<!-- BEGIN: error -->
<div class="quote" style="width:780px;">
<blockquote class="error"><span>{ERROR}</span></blockquote>
</div>
<div class="clear"></div>
<!-- END: error -->
<!-- END: add -->
<!-- BEGIN: edit -->
<form action="{NV_BASE_ADMINURL}index.php" method="POST">
<table class="tab1">
<tr>
<td width="30%"><strong>{LANG.title}</strong></td>
<td><input name="title" type="text" size="100" value="{TITLE}" /></td>
</tr>
</table>
<table class="tab2" align="center">
<tr>
<td style="text-align:center;">
<input type="submit" value="{LANG.save} "/>
<input name="add" type="hidden" value="1" />
<input type="hidden" name =" {NV_NAME_VARIABLE} "value="
{MODULE_NAME} " />
<input type="hidden" name ="id" value="{ID}" />
<input type="hidden" name =" {NV_OP_VARIABLE} "value=" {OP} " />
</tr>
</td>
</table>
</form>
<!-- BEGIN: error -->
<div class="quote" style="width:780px;">
<blockquote class="error"><span>{ERROR}</span></blockquote>
</div>
<div class="clear"></div>
<!-- END: error -->
<!-- END: edit -->
<!-- BEGIN: main -->
<table class="tab1">
<thead>
<tr style="text-align:center;">
<td>{LANG.id}</td>
<td>{LANG.title}</td>
<td>{LANG.func}</td>
</tr>
<!-- BEGIN: loop -->
<tbody{CLASS}>
<tr>
<td style="text-align:center;">{CONTENT.id}</td>
<td>{CONTENT.title}</td>
<td style="text-align:center;">
{EDIT} - {DEL}
</td>
</td>
</tbody>
<!-- END: loop -->
</table>
<!-- END: main -->

Danh sách các file:

$ modules/example/admin/index.html
$ modules/example/admin/main.php
$ modules/example/index.html
$ modules/example/funcs/main.php
$ modules/example/funcs/index.html
$ modules/example/admin.functions.php
$ modules/example/functions.php
$ modules/example/action.php
$ modules/example/language/vi_admin.php
$ modules/example/language/en_admin.php
$ themes/admin_default/modules/example.php
$ themes/admin_default/modules/example.tpl

Sơ đồ cấu trúc template sử dụng Xtemplate

themes
—-default
css
—-example.css
images
js
modules
—-example.php
tpl
—-example.tpl

Sửa lại file modules/example/funcs/main.php

<?php

if ( ! defined( 'NV_IS_MOD_EXAMPLE' ) ) die( 'Stop!!!' );
$sql = "SELECT `id`, `title` FROM `" . NV_PREFIXLANG . "_" . $module_data . "`";
$resuilt = $db->sql_query( $sql );
while ( $row = $db->sql_fetchrow( $resuilt ) )
{
$content[] = $row;
}
$contents = call_user_func( "main_theme", $content );
include ( NV_ROOTDIR . "/includes/header.php" );
echo nv_site_theme( $contents );
include ( NV_ROOTDIR . "/includes/footer.php" );
?>

Thêm mới file modules/example/theme.php với nội dung như sau:
Chú ý:Tên của file trong thư mục modules của template phải trùng với tên của module.

<?php

function main_theme($content)
{
global $module_file, $global_config;
$xtpl = new XTemplate("example.xtpl", NV_ROOTDIR . "/themes/" . $module_info['template'] . "/modules/" . $module_file );
$a = 1;
foreach($content as $content_i)
{
$xtpl->assign('CONTENT',$content_i);
$xtpl->assign('STT',$a);
$xtpl->parse('main.loop');
$a++;
}
$xtpl->parse('main');
return $xtpl->text('main');
}

?>

Thêm mới file themes/default/modules/example/example.xtpl

<!-- BEGIN: main -->
<table>
<!-- BEGIN: loop -->
<tr>
<td>{STT}</td>
<td>{CONTENT.title}</td>
</tr>
<!-- END: loop -->
</table>
<!-- END: main -->

Nếu bạn cần tạo ngôn ngữ cho ngoài site bạn có thể tạo thêm các file: vi.php, en.php trong thư
mục language của module

Khi đó danh mục các file của module gồm:

$ modules/example/admin/index.html
$ modules/example/admin/main.php
$ modules/example/index.html
$ modules/example/funcs/main.php
$ modules/example/funcs/index.html
$ modules/example/admin.functions.php
$ modules/example/functions.php
$ modules/example/theme.php
$ modules/example/action.php
$ modules/example/version.php
$ modules/example/language/vi.php
$ modules/example/language/vi_admin.php
$ modules/example/language/en.php
$ modules/example/language/en_admin.php
$ themes/default/modules/example.php
$ themes/default/modules/example/example.xtpl
$ themes/admin_default/modules/example.php
$ themes/admin_default/modules/example.tpl

Các chú ý khi lập trình

1) Encoding

Encoding mặc định tất cả các file là: ansi, các file lang như tiếng việt, pháp, nga .. Encoding cần chuyển sang utf-8

2) Trigger_error

thay vì dùng die(“…”) báo lỗi và dừng chương trình; cần dùng dùng trigger_error(“…”, 256);
để ghi lại lỗi đó và thông báo lỗi.

3) Chế độ thông báo lỗi

Để thay đổi chế độ thông báo lỗi của php cần sửa file includes /constants.php

//define( "NV_DISPLAY_ERRORS_LIST", E_ALL | E_STRICT ); //Danh sach cac loi se hien thi
define( "NV_DISPLAY_ERRORS_LIST", E_ALL );
//define( "NV_DISPLAY_ERRORS_LIST", 0); //tat thong bao loi
define( "NV_LOG_ERRORS_LIST", E_ALL | E_STRICT ); //Danh sach cac loi se ghi l og
define( "NV_SEND_ERRORS_LIST", E_USER_ERROR ); //Danh sach cac loi se gui den email

VD: để tắt thông báo lỗi ta cần sửa đoạn trên thành

//define( "NV_DISPLAY_ERRORS_LIST", E_ALL | E_STRICT ); //Danh sach cac loi se hien thi
//define( "NV_DISPLAY_ERRORS_LIST", E_ALL );
define( "NV_DISPLAY_ERRORS_LIST", 0); //tat thong bao loi
define( "NV_LOG_ERRORS_LIST", E_ALL | E_STRICT ); //Danh sach cac loi se ghi log
define( "NV_SEND_ERRORS_LIST", E_USER_ERROR ); //Danh sach cac loi se gui den email

Nhung cai trang nao ko cho phep truy cap truc tiep neu khong co referer can phai co dong nay

if ( ! defined( 'NV_IS_AJAX' ) ) die( 'Wrong URL' );

4) Lấy giá trị của biến khi submit form
class request còn có thể lấy theo các phương thức: get_bool, get_string, get_int, get_float, get_array, Trong phương thức get_string nếu lấy qua phương thức get, giá trị của biến đã được lọc mã html
Lấy biến dụng số nguyên

<?php

$id = $nv_Request->get_int( 'id', 'post' );
// Lấy giá trị của 'id' qua phương thức post, nếu không có giá trị bằng 0

$default = 10;
$id = $nv_Request->get_int( 'id', 'get', $default);
// Lấy giá trị của 'id' qua phương thức get, nếu không có giá trị bằng 10

$default = 10;
$id = $nv_Request->get_int( 'id', 'post,get', $default);
// Lấy giá trị của 'id' qua phương thức post, hoặc get ưu tiên lấy post trước,nếu không có giá trị bằng 10

?>

Lấy biến dụng số thực

<?php

$id = $nv_Request->get_float( 'id', 'post' );
// Lấy giá trị của input_name qua phương thức post, nếu không có giá trị bằng 0

$default = 10.5;
$id = $nv_Request->get_float( 'id', 'get', $default);
// Lấy giá trị của input_name qua phương thức get, nếu không có giá trị bằng 10.5

$default = 10.5;
$id = $nv_Request->get_float( 'id', 'post,get', $default);
// Lấy giá trị của input_name qua phương thức post, hoặc get ưu tiên lấy posttrước, nếu không có giá trị bằng 10.5

?>

Sử dụng hàm: filter_text_input

<?php

$value = filter_text_input( 'input_name', 'post', '' );
// Lấy giá trị của input_name qua phương thức post, nếu không có giá trị bằng rỗng

$value = filter_text_input( 'input_name', 'post,get', "", 1);
// Lấy giá trị của input_name qua phương thức post hoặc get, nếu không có giá trị bằng rỗng
// Giá trị của biến sẽ được gọi qua hàm nv_htmlspecialchars để thay thế các mã html đặc biệt

$value = filter_text_input( 'input_name', 'post,get', "", 1, 255);
// Lấy giá trị của input_name qua phương thức post hoặc get, nếu không có giá trị bằng rỗng
// Giá trị của biến sẽ được gọi qua hàm nv_htmlspecialchars để thay thế các mã html đặc biệt
// Giá trị của biến lấy 255 ký tự đầu tiên, nếu giá trị nhiều hơn 255 ký tự th ì các ký tự sau 255 sẽ bị cắt đi

$default = "default";
$preg_replace = array( 'pattern' => "/[^a-zA-Z0-9]/", 'replacement' => "_");
$value = filter_text_input( 'input_name', 'request', $default, 0, 100, $preg_replace );

// Lấy giá trị của input_name qua phương thức request, nếu không có giá trị bằng default
// Giá trị của biến lấy 100 ký tự đầu tiên, nếu giá trị nhiều hơn 100 ký tự th ì các ký tự sau 100 sẽ bị cắt đi
// Giá trị của biến sẽ thay thế các kỹ tự khác a-zA-Z0-9 bằng ký tự gạch dưới

?>

Sử dụng hàm: filter_text_textarea
khi 1 form có textarea, chỉ dùng phương thức post, chứ không dùng phương thức get, nếu không sẽ bị mất dữ liệu
sử dụng filter_text_textarea cho các editor

<?php

$content = filter_text_textarea( 'content', '', NV_ALLOWED_HTML_TAGS );
// dung de lay data tu textarea.
//Chì chỉ các tags được liệt kê trong NV_ALLOWED_HTML_TAGS mới được sử dụng, các mã khác sẽ bị lọc bỏ
$content = nv_editor_nl2br( $content );// dung de save vào CSDL

$content = nv_editor_br2nl( $row['content'] ); // dung de lay data tu CSDL
$content = nv_htmlspecialchars( $content ); // dung de dua vao editor

$content = filter_text_textarea( 'content', ''); //sẽ không lọc các tags html

?>

sử dụng filter_text_textarea cho các textarea không sử dụng editor

<?php

$content = filter_text_textarea( 'content', '', NV_ALLOWED_HTML_TAGS );
// dung de lay data tu textarea.
//Chì chỉ các tags được liệt kê trong NV_ALLOWED_HTML_TAGS mới được sử dụng, các mã khác sẽ bị lọc bỏ

$content = nv_nl2br( $content, '<br />' );// dung de save vao csdl

$content = nv_br2nl( $row['content'] ); // dung de lay data tu CSDL
$content = nv_htmlspecialchars( $content ); // dung de dua vao textarea

$content = filter_text_textarea( 'content', ''); //sẽ không lọc các tags html

?>
Did you like this? Share it:

Tham khảo:

  • Zai

    Có thể giúp em tạo một module tên là Test mà khi nhấn vào module đấy nó sẽ liên kết tới một link bất kỳ mà mình đặt không

  • http://user.vn xman

    chỉ cần đọc và làm theo hướng dẫn trên là có thể viết được rồi, còn câu hỏi của bạn nó quá đơn giản mình chỉ hướng dẫn cách hiểu cấu trúc làm việc chứ kô dạy bạn html cơ bản. html cơ bản bạn phải học trước khi nghĩ đến lập trình

    • PHAN THANH THUC

      Bạn có thể cho mình xin code hướng dẩn ở trên hok
      Mình mới vào nuke nên hơi gà.
      mình đã thực hiện như bạn nhưng khong thành công.
      Thank bạn nhiều

      • http://thegioimanguon.com xman

        nuke hiện tại mình kô dùng nữa nên có lẽ là kô support nữa bạn ạh :)

  • http://sokhanh03.co.cc sokhanh03

    bài viết rất hay cảm ơn bạn nhiều

  • http://nhom9ck2.freevnn.com/ gait

    Bài viết bạn rất hay ,mình muốn xin bạn 1 csdl viết 1 trang web cá nhân được không ah? tại vì làm 1 csdl lớn quá mình làm không nỗi với cái csdl mình còn hơn kém nều được bạn có thể mail cho mình  :hoangsanhck2@gmail.com .mình cảm ơn bạn rất nhiều.

    • http://thegioimanguon.com xman

      xin lỗi bạn, mình không thể share csdl cho bạn được. thân

  • lê ngọc phát

    bạn ơi các file này tạo như thế nào bạn? file themes.php ý
    $ modules/example/index.html
    $ modules/example/funcs/main.php
    $ modules/example/funcs/index.html
    $ modules/example/admin.functions.php
    $ modules/example/functions.php
    $ modules/example/theme.php
    $ modules/example/version.php

    • http://thegioimanguon.com xman

      thật sự không biết bạn muốn hỏi về cái gì

  • TrienChieu_007

    Bạn XMAN ơi,,cho mình hỏi tí..
    Mình làm hết bước 2 rồi “Cách viết một module đơn giản” là dc 1 module rồi đúng không bạn…Xong rồi mình nén thành file zip và cài đặt ở NukeViet3.4 nhung nó báo “Cấu trúc thư mục không hợp lệ”…
    Mình làm hết luôn phần 3,4,5,6,7 thì nó cũng báo vậy hà..Có cách nào khắc phục không bạn XMAN….thanks bạn nhiều lắm…

    • http://thegioimanguon.com xman

      mình viết bài này cũng khá lâu rồi nên có lẽ cấu trúc đã thay đổi nên không còn phù hợp với phiên bản hiện tại

  • coco

    Cho mình hỏi trong nukeviet có sử dụng được cơ sở dữ liệu có sẵn không hay phải tạo csdl mới của mỗi module

    • http://thegioimanguon.com xman

      nếu là csdl là 1 database khác không nằm cùng database của nuke thì hiện tại core nuke kô hỗ trợ bạn àh. Còn nếu bạn muốn thì bạn phải tự kết nối với csdl đó còn thông thường thì bạn tạo bảng cho module trong csdl của nuke để dùng

  • http://trangcongnghe.com công nghệ

    Có thể giúp em tạo một module tên là Test mà khi nhấn vào module đấy nó sẽ liên kết tới một link bất kỳ mà mình đặt không

    • http://thegioimanguon.com xman

      srr bạn lâu rồi mình kô dùng nukeviet nữa bạn ạh