Đối với những site có rất nhiều nội dung, có lẽ chúng ta cần tạo những URL đơn giản, gọn gàng để người dùng dễ nhớ để truy cập lại sau này. Thí dụ, toila.net/thehong thì đẹp hơn toila.net/index.php?q=user/1, web.com/thongbao sẽ dễ nhớ hơn web.com/index.php?q=taxonomy/term/1+2+3 rất nhiều hay là thehong.yeublog.com sẽ chuyên nghiệp hơn là yeublog.com/index.php?module=blog&action=frontpage, ... Đối với sub-domain dạng sub folder thì vấn đề được giải quyết rất đơn giản, nhưng đối với sub-domain dạng subdomain.domain.com thì có một số trở ngại. Bài viết này nêu lên một số trở ngại và cách giải quyết.
Yêu cầu hệ thống
Host phải hỗ trợ chức năng subdomain wildcard -- subdomain ảo. Khi chức năng subdomain wildcard này được kích hoạt, các request đến server dưới dạng http://foo.domainname.com/bar sẽ được server hiểu là http://domainname.com/bar. Khi đó, các request đến Drupal site đều quy về một mối -- các request dạng http://foo.domainname.com/node/1, server sẽ gọi Drupal site của bạn với URL có dạng http://domainname.com/index.php?q=node/1
Cookie
Việc tạo tên SESSION trong Drupal phụ thuộc vào domain (và sub domain) được request, cho nên, cũng là một người truy cập, nhưng khi bạn truy cập http://domainname.com và khi bạn truy cập http://foo.domainame.com, thì đối với Drupal, bạn là hai người khác nhau. Tham khảo hàm config_init. Để giải quyết trở ngại này, chúng ta phải đồng bộ tên SESSION khi sử dụng các domain/sub-domain. Mở tập tin sites/settings/settings.php, thêm (bỏ comment) dòng:
<?php
$cookie_domain = domainname.com';
?>Vấn đề còn lại giờ, chúng ta hải chỉnh lại tập tin .htaccess để Drupal hiểu được chính xác các yêu cầu của người dùng ứng với các domain/sub-domain:
- http://foo.domainname.com/ => http://domainname.com/index.php?q=foo
- http://bar.domainname.com/baz/blah => http://domainname.com/index.php?q=baz/blah
Rewrite
Apply patch này (áp dụng cho Drupal 5.7) để điều chỉnh lại tập tin .htaccess. Khi đó, .htaccess của Drupal sẽ có dạng sau:
#
# Apache/PHP/Drupal settings:
#
# Protect files and directories from prying eyes.
<FilesMatch "\.(engine|inc|info|install|module|profile|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)$|^(code-style\.pl|Entries.*|Repository|Root|Tag|Template)$">
Order allow,deny
</FilesMatch>
# Don't show directory listings for URLs which map to a directory.
Options -Indexes
# Follow symbolic links in this directory.
Options +FollowSymLinks
# Customized error messages.
ErrorDocument 404 /index.php
# Set the default handler.
DirectoryIndex index.php
# Override PHP settings. More in sites/default/settings.php
# but the following cannot be changed at runtime.
# PHP 5, Apache 1 and 2.
<IfModule mod_php5.c>
php_value magic_quotes_gpc 0
php_value register_globals 0
php_value session.auto_start 0
php_value mbstring.http_input pass
php_value mbstring.http_output pass
php_value mbstring.encoding_translation 0
</IfModule>
# Requires mod_expires to be enabled.
<IfModule mod_expires.c>
# Enable expirations.
ExpiresActive On
# Cache all files for 2 weeks after access (A).
ExpiresDefault A1209600
# Do not cache dynamically generated pages.
ExpiresByType text/html A1
</IfModule>
# Various rewrite rules.
<IfModule mod_rewrite.c>
RewriteEngine on
# If your site can be accessed both with and without the 'www.' prefix, you
# can use one of the following settings to redirect users to your preferred
# URL, either WITH or WITHOUT the 'www.' prefix. Choose ONLY one option:
#
# To redirect all users to access the site WITH the 'www.' prefix,
# (http://example.com/... will be redirected to http://www.example.com/...)
# adapt and uncomment the following:
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301]
#
# To redirect all users to access the site WITHOUT the 'www.' prefix,
# (http://www.example.com/... will be redirected to http://example.com/...)
# uncomment and adapt the following:
# RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
# RewriteRule ^(.*)$ http://example.com/$1 [L,R=301]
# Modify the RewriteBase if you are using Drupal in a subdirectory or in a
# VirtualDocumentRoot and the rewrite rules are not working properly.
# For example if your site is at http://example.com/drupal uncomment and
# modify the following line:
# RewriteBase /drupal
#
# If your site is running in a VirtualDocumentRoot at http://example.com/,
# uncomment the following line:
# RewriteBase /
# Rewrite old-style URLs of the form 'node.php?id=x'.
#RewriteCond %{REQUEST_FILENAME} !-f
#RewriteCond %{REQUEST_FILENAME} !-d
#RewriteCond %{QUERY_STRING} ^id=([^&]+)$
#RewriteRule node.php index.php?q=node/view/%1 [L]
# Rewrite old-style URLs of the form 'module.php?mod=x'.
#RewriteCond %{REQUEST_FILENAME} !-f
#RewriteCond %{REQUEST_FILENAME} !-d
#RewriteCond %{QUERY_STRING} ^mod=([^&]+)$
#RewriteRule module.php index.php?q=%1 [L]
# Rewrite current-style URLs of the form 'index.php?q=x'.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^/.+$
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
# Rewrite subdomain.example.com to example.com/index.php?q=subdomain
RewriteCond %{REQUEST_URI} ^/$
RewriteCond %{HTTP_HOST} ^(.+)\.example\.com$ [NC]
RewriteRule ^.*$ index.php?q=%1 [L,QSA]
</IfModule>
# $Id: .htaccess,v 1.81.2.4 2008/01/22 09:01:39 drumm Exp $
Ứng dụng
Chúng ta có thể áp dụng chức năng sub-domain cho các trường hợp sau:
- Multi blogger sites - Mỗi user blog có một sub-domain.
- Site bán hàng - Mỗi site, mỗi shop có một domain name riêng biệt.
- Các tờ báo lớn, ...

Comments
Phần này chỉ là
Phần này chỉ là rewrite từ sub.xxx.com về => xxx.com/sub thôi, còn việc website quản lý việc out ra các url dạng sub.xxx.com thì sao hả Thế Hồng?
Bring Vietnam to the World
My Blog
Bring Vietnam to the World
My Blog
Hàm url (), l () tự lo
Hàm url (), l () tự lo việc này. Anh có thể xem thử:
http://bloghold.com/
http://contact.bloghold.com/
http://node.bloghold.com/
Thế Hồng
ah, ý mình là mỗi cái
ah, ý mình là mỗi cái sub sẽ hiển thị một loại contents (node) khác nhau do admin setup giống như cái module localizer họ làm
en.domain.com <= English site
vi.domain.com <= Vietnamese site
Không biết sao google tự nhiên lại coi email from this domain là spam (Mình dùng google app cho email và chát chít).
Bring Vietnam to the World
My Blog
Bring Vietnam to the World
My Blog
Try this
Anh thử thêm các rewrite cond/rule sau vào .htaccess xem có chạy không?
RewriteCond %{HTTP_HOST} ^en\.example\.com$ [NC] RewriteRule ^(.*)$ index.php?q=en/$1 [L,QSA] RewriteCond %{HTTP_HOST} ^vi\.example\.com$ [NC] RewriteRule ^(.*)$ index.php?q=vi/$1 [L,QSA]Chú ý:
- Thay example.com thành domain name thật tế.
- [NC]: không phân biệt hoa/thường
- [QSA] = query string append = chèn thêm truy vấn vào sau domain
- i18n hiểu ngôn ngữ sử dụng dựa trên mã ngôn ngữ được xác định ở phần tử đầu của biến "q", do đó, nó sẽ tự động thêm en/vi/de/... vào các intertal path của Drupal => cần một patch để break cái path alter này.
Thế Hồng
Hi TH, Vấn đề là như
Hi TH,
Vấn đề là như thế này, nội dung và url cho các subdomain thì ok nhưng trên front page sẽ là thông tin tập hợp tin của toàn bộ website. Ví dụ website có 4 mục thông tin chính, mỗi mục đưa vào 1 subdomain. Khi đó trên homepage của website sẽ chứa nội dung nổi bật của 4 mục thông tin trên, mỗi news item đó sẽ link về dạng subdomain khác nhau.
Cụ thể site về giải trí: có 4 vùng trên 4 subdomain là
1. Ảnh người mẫu
2. Nhạc
3. Forum
4. Tin tức
Như vậy, trên trang chính sẽ có vài block lấy từ
- subdomain ảnh => link point về url dạng http://pic.giaitri.vn/????.html
- subdomain nhạc => link point về url dạng http://music.giaitri.vn/???html
Thế Hồng có giải pháp nào cho việc generate ra nhiều dạng url của cùng một bản cài đặt không?
FYI: Mod pathauto chỉ giải quyết sinh ra path đứng sau domain chứ không thể change trực tiếp domain được.
Bring Vietnam to the World
My Blog
Bring Vietnam to the World
My Blog
TH đang gặp một vấn
TH đang gặp một vấn đề tương tự: một site hội chợ, cho doanh nghiệp thuê shop con, mỗi shop con là một Oganic Group, trong shop con có sản phẩm, tin tức, poll, ... nội dung của shop con cần được thống kê tổng quát ở trang chủ.
Tuy nhiên, do site của TH sử dụng modules views, nên chỉ cần một hook của views là giải quyết được hết vấn đề, còn cách giải quyết cơ bản nhất thì chưa có.
Thế Hồng
Một cách giải quyết hơi dã man một tí
Ghi chú: Mã nguồn phía dưới này là bản thô, cần chỉnh sửa!Viết thêm hàm
custom_url_rewritevào tập tin settings.php hoặc vào một module nào đó:<?php
function custom_url_rewrite ($op, $result, $path) {
if ($op == 'alias') {
// save node id to a global array
if (preg_match ('|node/[0-9]+|', $path)) {
global $subdomain_nids;
if (!isset ($subdomain_nids)) {
$subdomain_nids = array ();
}
$nid = preg_replace ('|.<em>node/([0-9]+).</em>|', '$1', $path);
if (!isset ($subdomain_nids[$nid])) {
$subdomain_nids[$nid] = $result;
}
}
return $result;
}
}
?>
Mục đích của hàm này là lưu lại các node được hệ thống tạo link đến ở trang được xem. Viết một hook_footer để
- Dò xem node nào thuộc group nào
- Thay đổi URL đã xuất ra = javascript
<?php
function vne_footer($main = 0) {
global $subdomain_nids;
// query to find sub-domain base on shop
$q = db_query (
"SELECT oa.nid, oa.group_nid, ua.dst FROM {og_ancestry} oa INNER JOIN {url_alias} ua ON ua.src = CONCAT('node/', oa.group_nid) WHERE oa.nid IN (%s)",
implode (',', array_keys ($subdomain_nids))
);
$subdomain_map = array ();
while ($v = db_fetch_object ($q)) {
$subdomain_map[$subdomain_nids[$v->nid]] = $v->dst;
}
$subdomain_map = drupal_to_js ($subdomain_map);
// $root_url = url('<front>', null, null, true);
// print_r ($_SERVER);
$output = <<<SUBDOMAIN
<script>
var domain = '{$_SERVER['HTTP_HOST']}';
var subdomain_map = {$subdomain_map};
$(function(){
$('a').each(function(){
var url = $(this).attr('href').replace(Drupal.settings.jstools.basePath, '');
if (subdomain_map[url]) {
$(this).attr('href', 'http://' + subdomain_map[url] + '.' + domain + Drupal.settings.jstools.basePath + url);
url = $(this).attr('href');
}
$('body').prepend('<div>'+url+'</div>');
});
});
</script>
SUBDOMAIN;
return $output;
?>
Thế Hồng
Cách này hơi nguy hiển
Cách này hơi nguy hiển TH à, nếu đổi link bằng JS tức là site tồn tại 2 hệ thống link đến cùng một nội dung, nếu có dùng .htaccess để redirect về cùng một nội dung thì vấn không friendly với các Search Engine lắm.
Mấy hôm nữa có thời gian mình sẽ vọc thử vào core của drupal xem có thể làm gì được không.
Bring Vietnam to the World
My Blog
Bring Vietnam to the World
My Blog
Chào anh nguyendhex, Đúng
Chào anh nguyendhex,
Đúng là cách này có hơi dị hợm một chút. Nhưng khá tiện lợi, vì truy vấn CSDL chỉ có một lần, TH chọn cách này. Cách hợp lý hơn là hack thẳng vào hàm URL, không cần viết thêm hàm custom_url_rewrite, còn cách hack ntn thì chắc anh làm được :-)
Thế Hồng
Hacked version of url (core
Hacked version of url (core function): http://toila.net/content/drupal-va-sub-domain.html#comment-2745
--
Thế Hồng
More on $subdomains
More on $subdomains building: http://toila.net/content/drupal-va-sub-domain.html#comment-2750
--
Thế Hồng
Mình thì thích cái kiểu giải
Mình thì thích cái kiểu giải quyết subdomain của một số CMS là : Cho tất tật quay về với mẹ Index.php và giải quyết dựa trên cấu hình trong admin, nếu không thấy điều kiện thỏa mãn thì 404, vậy là một admin dùng cho mọi subdomain, không biết drupal có cái module nào tương tự không nhỉ ?
My blog: Jamviet.com, Hỏi đáp trực tuyến, váy dài