Search found 16 matches for tutorial

[TUTs] Tạo Push Notification với OneSignal

Diễn đàn: TUTsTrả lời: 8Lượt xem: 7968

 25.07.16 23:14

Push Notification (thông báo đẩy) đang được ưa chuộng ở nhiều trang web hiện đại, nhằm gửi thông báo quan trọng đến người dùng, ngay trên trình duyệt của họ.

Hình thức gửi thông báo này có phần tương tự API HTML5 Notification trước đây, nhưng tối ưu hơn ở điểm có thể gửi thông báo ngay cả khi người dùng không mở trang web. Và nó cũng thân thiện với người dùng hơn so với hình thức gửi Email vì nội dung sẽ hiển thị ngay khi mở trình duyệt và họ có thể dừng nhận tin bất kỳ lúc nào.

Để ứng dụng công nghệ Push Notification thì trang web của bạn phải được bật SSL (HTTPS), và cấu hình server khá rắc rối. Nếu làm thế thì Forumotion xem như vô vọng rồi. Vì vậy, chúng ta sẽ dùng một dịch vụ trong gian là OneSignal để gửi thông báo. Có nhiều dịch vụ tương tự bao gồm miễn phí và trả phí, có cả từ Việt Nam nữa, nhưng mình chọn OneSignal vì nó cho phép tùy biến tốt hơn và hoàn toàn miễn phí.


Demo


Topics tagged under tutorial on DEVs forumvi 2110
Giao diện quản lý và cách thông báo hiển thị


Hướng dẫn cài đặt


Vì bài viết chứa rất nhiều hình ảnh nên mình sẽ chỉ để hình thu nhỏ, các bạn đọc hướng dẫn khó hiểu thì nhấn vào đó để xem hình gốc.

Bước 1


Mở trang OneSignal.com, nhấn vào nút Sign up free để đăng ký tài khoản.

Topics tagged under tutorial on DEVs forumvi 110

Bạn có thể dùng tài khoản Github, Facebook có sẵn, hoặc dùng Email của bạn.
Trong mục Company or Organization Name, hãy nhập tên diễn đàn của bạn.

Bước 2


Sau khi đăng ký thành công, đăng nhập vào trang quản lý, lúc này bạn chưa có ứng dụng nào được tạo.

Topics tagged under tutorial on DEVs forumvi 210

Nhấn Add a new app để tạo ứng dụng mới.
Trong mục App name, điền tên diễn đàn của bạn.
Nhất Create để tạo ứng dụng.

Bước 3


Chọn nền tảng cho ứng dụng vừa tạo.

Topics tagged under tutorial on DEVs forumvi 310

Chọn Website Push, vì diễn đàn cũng Forumotion thuộc kiểu trang web.
Nhấn Next để tiếp tục.

Bước 4


Chọn nền tảng để cấu hình.

Topics tagged under tutorial on DEVs forumvi 410

Chọn Google Chrome & Mozilla Firefox để cấu hình trước. Nếu bạn nào sử dụng Mac thì cấu hình Safari trước cũng được.
Nhấn Next để tiếp tục.

Bước 5


Cấu hình cho Google Chrome và Mozilla Firefox.

Để thực hiện được bước này, bạn phải có Server API KeySender ID.

Hướng dẫn tạo Server API Key và Sender ID:


Điền đầy đủ thông tin. Lưu ý, trong khung này có nhiều mục nên phải cuộn xuống (trong khung) để xem hết.

Topics tagged under tutorial on DEVs forumvi 510

Site URL: Điền URL diễn đàn của bạn. Ví dụ:
Code:
http://devs.forumvi.com

Google Server API Key: Điền Server API Key của ứng dụng bạn tạo trên Google Services Wizard.
Default Notification Icon URL: Điền URL icon, kích thước tối thiểu 192 x 192 px. Bạn nên dùng logo của diễn đàn, nếu không, có thể dùng URL sau:
Code:
http://i.imgur.com/srF9Tzi.png

Tích vào My site is not fully HTTPS.
Choose Subdomain: Nên điền tên miền diễn đàn, nó sẽ được dùng làm tên miền phụ của OneSignal. Ví dụ mình điền devs, nó sẽ thành:
Code:
https://devs.onesignal.com

Google Project Number: Điền Sender ID của ứng dụng bạn tạo trên Google Services Wizard.
Nhấn Save và qua bước tiếp theo.

Bước 6


Chọn bộ SDK để tích hợp vào diễn đàn.

Topics tagged under tutorial on DEVs forumvi 610

Chọn Website Push.
Nhấn Next để tiếp tục.

Bước 7


Cài đặt SDK của OneSignal vào diễn đàn.

Topics tagged under tutorial on DEVs forumvi 710

Ghi lại mã Your App ID.
Không đóng OneSignal. Đi đến diễn đàn của bạn để cài đặt SDK.
Lưu ý không dùng trình duyệt ở chế độ ẩn danh, tắt các tiện ích chặn Popup và nên dùng Google Chrome.

Sao chép và chỉnh sửa code sau:
Code:
<script src="https://cdn.onesignal.com/sdks/OneSignalSDK.js" async='async'></script>
<script>
    var OneSignal = OneSignal || [];
    OneSignal.push(['init', {
        appId: 'APP_ID',
        safari_web_id: 'SAFARI_WEB_ID',
        autoRegister: true,
        subdomainName: 'SUBDOMAIN',
        notifyButton: {
            enable: true,
            size: 'small',
            position: 'bottom-left',
            prenotify: true,
            showCredit: false,
            text: {
                'tip.state.unsubscribed': 'Đăng ký nhận thông báo',
                'tip.state.subscribed': 'Bạn đã đăng ký nhận thông báo',
                'tip.state.blocked': 'Bạn đã chặn hiển thị thông báo',
                'message.prenotify': 'Click để đăng ký nhận thông báo',
                'message.action.subscribed': 'Cảm ơn bạn đã đăng ký!',
                'message.action.resubscribed': 'Bạn đã đăng ký nhận thông báo',
                'message.action.unsubscribed': 'Bạn đã hủy đăng ký nhận thông báo',
                'dialog.main.title': 'Quản lý thông báo',
                'dialog.main.button.subscribe': 'ĐĂNG KÝ',
                'dialog.main.button.unsubscribe': 'HỦY ĐĂNG KÝ',
                'dialog.blocked.title': 'Bỏ chặn thông báo',
                'dialog.blocked.message': 'Thực hiện các hướng dẫn sau để cho phép thông báo:'
            }
        },
        welcomeNotification: {
            title: 'SITE_NAME',
            message: 'Cảm ơn bạn đã đăng ký!'
        },
        promptOptions: {
            siteName: 'SITE_NAME',
            actionMessage: 'Chúng tôi muốn hiển thị thông báo cho bạn khi có bài viết hoặc cập nhật mới.',
            exampleNotificationTitle: 'Thông báo mẫu',
            exampleNotificationMessage: 'Ví dụ cách thông báo sẽ hiển thị',
            exampleNotificationCaption: 'Bạn có thể dừng nhận thông báo bất kỳ lúc nào',
            acceptButtonText: 'CHO PHÉP',
            cancelButtonText: 'BỎ QUA'
        }
    }]);
</script>

Trong code trên:
Thay APP_ID bằng mã Your App ID vừa lấy.
Thay SUBDOMAIN bằng tên miền phụ từ OneSignal tạo ở Bước 5 (mục Choose Subdomain).
Thay 2 vị trí SITE_NAME bằng tên diễn đàn của bạn.

Sau khi chỉnh sửa xong, mở template overall_header:
ACP >> Display >> Templates >> General >> overall_header

Tìm </head> và thêm code vừa chỉnh sửa vào phía trước nó.
Save template và Publish.

Bước 8


Kiểm tra hoạt động. Truy cập diễn đàn của bạn và kiểm tra thông báo.

Topics tagged under tutorial on DEVs forumvi 810

Nhấn CHO PHÉP trong bảng yêu cầu xác nhận hiện ra. Nếu không hiện thì có thể code bạn sửa bị sai, kiểm tra lại Bước 7.

Sau đó một Popup sẽ hiện ra. Nhấn Cho phép (Allow) khi được yêu cầu xác nhận hiển thị thông báo.

Topics tagged under tutorial on DEVs forumvi 910

Nếu nó không hiện, kiểm tra xem bạn có dùng tiện ích chặn Popup không, nếu có thì tắt nó đi, rồi nhấn vào icon thông báo ở góc dưới, bên trái diễn đàn.
Nếu bạn dùng trình duyệt ẩn danh sẽ không thể cho phép hiển thị thông báo được.

Bước 9


Kiểm tra người dùng nhận thông báo. Lúc này thì đó chính là bạn.

Topics tagged under tutorial on DEVs forumvi 1010

Nhấn vào nút Check Subscribed Users.
Nếu bạn làm Bước 8 đúng thì sẽ qua được bước này. Nhấn Next để tiếp tục.

Bước 10


Kiểm tra hoạt động của ứng dụng.

Topics tagged under tutorial on DEVs forumvi 1110

Nhấp vào nút Send Test Notification, một thông báo sẽ được hiện ra.

Topics tagged under tutorial on DEVs forumvi 1210

Nhấn vào thông báo vừa hiện ra, trình duyệt sẽ mở một tab mới, dẫn đến trang kiểm tra ứng dụng hoạt động.

Topics tagged under tutorial on DEVs forumvi 12_510

Tắt trang kiểm tra đó và quay lại trang cấu hình. Nhấn vào nút Check Notification Status.
Nhấn Done.

Topics tagged under tutorial on DEVs forumvi 1310

Vậy là bạn đã cấu hình xong cho Google Chrome và Mozilla Firefox. Nhấn Done để kết thúc.

Bước 11


Cấu hình cho Safari.

Topics tagged under tutorial on DEVs forumvi 1410

Nhấn vào App Settings.
Nhấn nút Configure ở dòng Apple Safari.

Bước 12


Điền đầy đủ thông tin. Lưu ý, trong khung này có nhiều mục nên phải cuộn xuống (trong khung) để xem hết.

Topics tagged under tutorial on DEVs forumvi 1510

Site Name: Điền tên diễn đàn của bạn
Site URL: Điền URL diễn đàn của bạn.
Không tích vào I'd like to upload my own .p12 certificate
Tích vào I'd like to upload my own notification icons, và tải lên logo diễn đàn của bạn theo các kích thước được yêu cầu. Nếu không, bạn có thể tải về Bộ icon BELL để sử dụng.
Nhấn Save và qua bước tiếp theo.

Bước 13


Lấy mã Web ID cho Safari

Topics tagged under tutorial on DEVs forumvi 1611

Đóng Dialog lại, bằng cách nhấn vào Kí hiệu X.
Do mình không có máy Mac nên không hướng dẫn tiếp được. Hơn nữa, bước tiếp theo chỉ là kiểm thử ứng dụng tương tự như Google Chrome và Mozilla Firefox, chỉ còn thêm Web ID cho Safari vào code mà còn sai nữa thì mình cũng chịu.
Dù sao bạn cũng yên tâm, mình đã nhờ người kiểm tra bằng Safari trên Mac rồi, đảm bảo hoạt động.

Topics tagged under tutorial on DEVs forumvi 1711

Sau khi đóng Dialog thì tại dòng cấu hình Apple Safari bạn sẽ thấy mã Web ID của nó, sao chép lại.
Đi đến diễn đàn của bạn, mở template overall_header.
Tìm trong code mà bạn đã thêm vào ở Bước 7.
Thay SAFARI_WEB_ID bằng mã Web ID mà bạn vừa lấy được.
Save template và Publish.

Vậy là xong rồi đó, giờ bạn đã có thể tạo thông báo cho người dùng (nếu họ cho phép).


Cách tạo thông báo


Topics tagged under tutorial on DEVs forumvi 1910

Nhấn New Message
Điền tiêu đề thông báo trong mục Title và nội dung trong mục Content.

Topics tagged under tutorial on DEVs forumvi 19_510

Nhấn vào Options để mở tùy chọn thêm.

Topics tagged under tutorial on DEVs forumvi 2010

Mở mục Launch URL và điền URL, để khi người dùng nhấn vào thông báo, trình duyệt sẽ chuyển đến URL đó.

Các tùy chọn khác, ít dùng hơn:
Include Additional Data: Bạn sẽ cần biết cách dùng API, có kiến thức javascript kha khá mới dùng được.
Include Android / iOS Action Buttons: Dùng cho ứng dụng Web, không sài được.
Include Chrome Web Push Action Buttons: Tùy chọn này chỉ hoạt động trên Google Chrome 48+, nó cho phép tạo thêm tối đa 2 nút phụ bên dưới thông báo.

Topics tagged under tutorial on DEVs forumvi 2110

Sau khi thông báo được gửi, bạn cũng có thể xem thống kê số người dùng tương tác với nó.


Nguồn


Zzbaivong (devs.forumvi.com)
Tags: #firefox #mod #tutorial #phpbb2 #phpbb3 #punbb #invision #notification #chrome #safari

 21.12.15 16:01

Trong forum về code như Devs forumvi thì vấn đề màu mè cho khung code luôn được đặt lên hàng đầu. :D

Trước đây, mình đã có hướng dẫn vài cách ứng dụng các plugin syntax highlighter cho forum, mỗi cái có ưu và nhược điểm riêng, tạm kể ra vài tội như:
- Google Code Prettify: Tự nhận diện ngôn ngữ nhưng không chính xác lắm, xử lý rất chậm khi gặp code dài, kích thước file js lớn.
- Prismjs: Lỗi ở một số mã Regexp phức tạp, không tự nhận diện ngôn ngữ.
- CodeMirror: Không tự nhận diện ngôn ngữ, kích thước file js khá lớn.

Hôm nay mình sẽ hướng dẫn cách dùng highlightjs, một plugin syntax highlighter khắc phục được các nhược điểm trên.


Demo


Topics tagged under tutorial on DEVs forumvi 2xpXfbr
Ảnh minh họa highlight code với ngôn ngữ PHP


Tính năng


  1. Hỗ trợ 146 ngôn ngữ và 66 giao diện (Xem ví dụ).
  2. Tự động nhận diện ngôn ngữ.
  3. Kích thước file js nhỏ ~17Kb.
  4. Sao chép nhanh dùng Clipboard.


Hạn chế


  1. Không hỗ trợ phpBB2. Do cấu trúc phpBB2 khác biệt với 3 mã nguồn còn lại, và ít người dùng nên mình không làm.
  2. Làm nổi bật cú pháp không chi tiết bằng 3 plugin mình giới thiệu trước đây.
  3. Không có các tính năng phụ như: số dòng, tìm dòng, chọn giao diện, chọn toàn bộ (đã thay bằng nút copy). Mình thấy các tính năng này ít dùng, lại làm chậm xử lý nên bỏ bớt cho nó nuột.



Hướng dẫn


ACP >> Display >> QLTT >> overall_header

Tìm:
Code:
<script src="{JQUERY_PATH}" type="text/javascript"></script>
<script src="{JS_DIR}{L_LANG}.js" type="text/javascript"></script>


Và thêm vào bên dưới nó, code sau:
Code:
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.1.0/styles/github-gist.min.css">
<style>
/* Zzhljs - http://devs.forumvi.com */
dl.codebox:not(.spoiler) dt {
    display: none;
}
dl.codebox:not(.spoiler) dd {
    border: 0 none;
    background: #f8f8f8;
    position: relative;
    max-height: 100%;
}
.clipboard {
    display: block;
    color: #333;
    position: absolute;
    right: 4px;
    top: 4px;
    background: url(http://i.imgur.com/o9NOYtH.png) no-repeat center center #eee;
    border: 1px solid #D5D5D5;
    width: 30px;
    height: 30px;
    text-align: center;
    border-radius: 3px;
    transition: opacity 0.3s ease-in-out 0s;
    opacity: 0;
    -webkit-user-select:none;
    -moz-user-select:none;
    -ms-user-select:none;
    user-select:none;
    -webkit-appearance:none;
    cursor: pointer;
}
.clipboard.check-circle {
    background-image: url(http://i.imgur.com/CBEkyLH.png);
}
.clipboard.exclamation-triangle {
    background-image: url(http://i.imgur.com/QQkE9Wj.png);
}
dl.codebox:not(.spoiler) dd:hover .clipboard {
    opacity: 1;
}
.clipboard:hover {
    background-color:#ddd;
    border-color:#ccc;
}
.hljs {
    background: #f8f8f8;
}
dl.codebox:not(.spoiler) code,
.codebox:not(.spoiler) dd.cont_code {
    max-height: 100%;
    margin: 0;
}
.codebox:not(.spoiler) {
    background-color: transparent;
    border: 0 none;
    margin: 0;
}
</style>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.1.0/highlight.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.5.5/clipboard.min.js"></script>
<script>
/* Zzhljs - http://devs.forumvi.com */
jQuery(function($){
    var $code = $("code");
    if ($code.length) {
        hljs.configure({
            useBR: true
        });
        $code.each(function (i, block) {
            hljs.highlightBlock(block);
        });

        function fallbackMessage(action) {
            var actionMsg = '';
            var actionKey = (action === 'cut' ? 'X' : 'C');

            if (/iPhone|iPad/i.test(navigator.userAgent)) {
                actionMsg = 'No support!';
            } else if (/Mac/i.test(navigator.userAgent)) {
                actionMsg = 'Press ⌘-' + actionKey + ' to ' + action;
            } else {
                actionMsg = 'Press Ctrl-' + actionKey + ' to ' + action;
            }

            return actionMsg;
        }

        function afterClipboard(ele) {
            setTimeout(function(){
                ele.className = 'clipboard clipboard';
            }, 400);
        }

        var snippets = document.querySelectorAll('.codebox:not(.spoiler) > dd');

        [].forEach.call(snippets, function (snippet) {
            snippet.firstChild.insertAdjacentHTML('beforebegin', '<i class="clipboard clipboard" data-clipboard></i>');
        });

        var clipboardSnippets = new Clipboard('[data-clipboard]', {
            target: function (trigger) {
                return trigger.nextElementSibling;
            }
        });

        clipboardSnippets.on('success', function (e) {
            e.clearSelection();
            e.trigger.className = 'clipboard check-circle';
            afterClipboard(e.trigger);
        });

        clipboardSnippets.on('error', function (e) {
            e.trigger.className = 'clipboard exclamation-triangle';
            afterClipboard(e.trigger);
            alert(fallbackMessage(e.action));
        });
    }
});
</script>



Tài nguyên

Icon từ FlatIcon.
Javascript plugin HighlightJs và ClipboardJs.
Ứng dụng cho Forumotion viết bởi Zzbaivong.
Tags: #mod #template #tutorial #highlight #clipboard #hljs

[TUTs] Việt hóa thanh Toolbar của Forumotion

Diễn đàn: TUTsTrả lời: 5Lượt xem: 2414

 24.06.15 8:04

Việt hóa thanh Toolbar



Giới thiệu


Code này sẻ Việt hóa toàn bộ thanh Toolbar của Forumotion.


Demo


Topics tagged under tutorial on DEVs forumvi 3S5ldCo
Giao diện thanh toolbar đã được Việt hóa


Cài đặt


ACP >> Display >> Templates >> General >> overall_header

Tìm:
Code:
{HOSTING_JS}


Thêm vào bên dưới nó, code sau:
Code:
<script type="text/javascript">
//<![CDATA[
if(typeof(_userdata) == "undefined") var _userdata = new Object();
_lang["Share"] = "Chia sẻ";
_lang["Login"] = "Đăng nhập";
_lang["Register"] = "Đăng ký";
_lang["Welcome"] = "Xin chào";
_lang["Notifications"] = "Thông báo";
_lang["See_my_profile"] = "Xem lý Lịch";
_lang["Edit_profile"] = "Thay đổi lý lịch của bạn";
_lang["All_Topics"] = "Tất cả chủ đề";
_lang["All_Messages"] = "Tất cả tin nhắn";
_lang["js_topics_followed"] = "Bài viết đang theo dõi";
_lang["Admin_panel"] = "Bảng điều khiển quản trị";
_lang["Logout"] = "Thoát";

_lang["Notif_see_all"] = "Xem tất cả các thông báo.";
_lang["Notif_priv_msg"] = "Bạn nhận được một <a href=\"/privmsg?folder=inbox&amp;nid=%(nid)s\">tin nhắn riêng</a> từ <a href=\"/u%(id)d\">%(name)s</a>.";
_lang["Notif_report"] = "<a href=\"/u%(id)d\">%(name)s</a> đã gửi một <a href=\"/report?nid=%(nid)s\">tin báo cáo</a>.";
_lang["Notif_friend_req"] = "Bạn nhận được một <a href=\"/profile?mode=editprofile&amp;nid=%(nid)s&amp;page_profil=friendsfoes\">yêu cầu kết bạn</a> từ <a href=\"/u%(id)d\">%(name)s</a>.";
_lang["Notif_group_req"] = "<a href=\"/u%(id)d\">%(name)s</a> đã gửi một yêu cầu tham gia nhóm <a href=\"/g%(group_id)d-%(group_url_name)s?nid=%(nid)s\">%(group_name)s</a>.";
_lang["Notif_friend_con"] = "<a href=\"/u%(id)d\">%(name)s</a> đã đăng nhập";
_lang["Notif_wall_msg"] = "<a href=\"/u%(id)d\">%(name)s</a> vừa viết một tin nhắn lên <a href=\"/u%(self)dwall?nid=%(nid)s\">tường nhà bạn</a>.";
_lang["Notif_abuse"] = "<a href=\"/admin/index.forum?mode=active&amp;nid=%(nid)s&amp;part=misc&amp;sub=support\">Một tố cáo</a> đã được gửi.";
_lang["Notif_topic_watch"] = "<a href=\"/u%(id)d\">%(name)s</a> đã gửi bài <a href=\"/t%(topic_id)d-%(topic_name)s?nid=%(nid)s#%(post_id)d\">vào bài viết bạn đang theo dõi</a>.";
_lang["Notif_topic_watch_p"] = "<a href=\"/u%(id)d\">%(name)s</a> đã gửi bài <a href=\"/t%(topic_id)dp%(start)d-%(topic_name)s?nid=%(nid)s#%(post_id)d\">vào bài viết bạn đang theo dõi</a>.";
_lang["Notif_topic_watch_guest"] = "Có một khách đã gửi bài <a href=\"/t%(topic_id)d-%(topic_name)s?nid=%(nid)s#%(post_id)d\">vào bài viết bạn đang theo dõi</a>.";
_lang["Notif_topic_watch_p_guest"] = "Có một khách đã gửi bài <a href=\"/t%(topic_id)dp%(start)d-%(topic_name)s?nid=%(nid)s#%(post_id)d\">vào bài viết bạn đang theo dõi</a>.";
_lang["Notif_mention"] = "Tên bạn là <a href=\"/u%(id)d\">%(name)s</a> được nhắc trong <a href=\"/t%(topic_id)dp%(start)d-%(topic_name)s?nid=%(nid)s#%(post_id)d\">bài viết này</a>.";
_lang["Notif_hashtag"] = "Từ khóa <a href=\"/tags/%(tag)s\">#%(tag)s</a> được ghi vào <a href=\"/t%(topic_id)dp%(start)d-%(topic_name)s?nid=%(nid)s#%(post_id)d\">bài viết này</a>.";
_lang["All_PMs"] = "Tin nhắn riêng";
_lang["No_assigned_rank"] ="Không có chỉ định cấp bậc đặc biệt.";
_lang["Posts"] = "Số bài";
_lang["PMs"] = "Tin nhắn riêng";
_lang["Reputation"] ="Được cảm ơn";
 
if(typeof(_board) == "undefined") var _board = new Object();
_board["Forumotion"] = "";
_board["toolbar_title_url"] = "http://" + location.host;
//]]>
</script>



NGUỒN


@markai30 (viethoagame.forumvi.com)
Tags: #mod #tutorial #việt-hóa #toolbar

[TUTs] Sitemap Forum giao diện Xenforo

Diễn đàn: TUTsTrả lời: 1Lượt xem: 2205

 16.06.15 14:07

Sitemap Forum giao diện Xenforo


Giới thiệu


Sitemap hay còn gọi là sơ đồ diễn đàn - là danh sách giản lược các chỉ mục, giúp người dùng có thể truy cập nhanh chuyên mục mình cần. Trong forumotion, ta có jumpbox với chức năng tương tự, tuy nhiên nó nằm ở dạng select, option tag nên khó chỉnh giao diện, vì lý do này mà một số diễn đàn muốn sử dụng nó như: tạo sơ đồ, khung điều hướng nhanh,... cũng phải nhập thủ công. Trong tutorial này, mình sẽ chuyển jumpbox sang dạng sitemap, sử dụng ul, li tag.
( Copy gần như nguyên văn của @Zzbaivong )

Trong tutorial có sử dụng Gist của @Zzbaivong, các bạn có thể xem qua tại: [Gist] Tạo sitemap cho diễn đàn từ jumpbox

Vì vậy nên đây không hẳn là code do mình làm, chỉ là 1/5 của nó thôi, lão @Zzbaivong nói là "không thích làm nữa vì một số lý do" =))) nên mình hoàn thiện nó trong tutorial này

Topics tagged under tutorial on DEVs forumvi WrIKgin
Đây là thành quả sau khi thực hiện Tut


Hướng dẫn


ACP >> Display >> Pictures and Colors >> Colors >> CSS Stylesheet
Chèn đoạn sau vào:
Code:
/* SitemapForum by Mạc Lục Phàm */
body.hiddenOverflow{overflow:hidden;}
.sitemapOpen{background:url('http://i57.servimg.com/u/f57/18/74/01/46/quickn10.png') no-repeat left center;display:inline-block;cursor:pointer;padding:4px;padding-left:24px;font-weight:700;}
#sitemapOverlay{background:rgba(0,0,0,0.8);position:fixed;top:0;left:0;width:100%;height:100%;display:none;z-index:9999;}
#sitemapSection{width:80%;margin:10%;background:#fafafa;border:10px solid #ddd;box-sizing:border-box;}
#sitemapHeading{font-size:16px;line-height:normal;padding:5px 15px;background:#333;color:#fff;font-weight:700;}
#sitemapMain{display:table;width:100%;}
#sitemapMain .sitemapColumn{display:table-cell;}
#sitemapMain .sitemapInhead{padding:5px 20px;background:#eee;}
#sitemapMain .sitemapQuickLinks{display:block;list-style:none;border-bottom:1px solid #eee;}
#sitemapMain .sitemapQuickLinks a{display:block;padding:5px 20px;}
#sitemapMain .sitemapQuickLinks a:hover{background:#eee;}
#zzSitemap{overflow:auto;height:237px;}
#zzSitemap ul{list-style:none;}
#zzSitemap ul li a{display:block;padding:5px 15px;}
#zzSitemap ul li a:hover{background:#eee;}
#zzSitemap ul > li > ul > li{padding-left:15px;}
#sitemapOption{text-align:right;}
#sitemapOption a{display:inline-block;margin:10px 25px;padding:5px 15px;background:#333;color:#fff;border:1px solid #aaa;box-shadow:0 1px 2px #eee;cursor:pointer;}


ACP >> Modules >> HTML & JAVASCRIPT >> Javascript codes management >> Topics tagged under tutorial on DEVs forumvi AjouterCreate a new javascript
Title * : Sitemap Forum
Placement : In all the pages
Javascript Code * :
Code:
$(function() {
  var $smOpen = $('.sitemapOpen'),
      $smClose = $('#sitemapClose'),
      $smMain = $('#sitemapOverlay'),
      $bodyOv = $('body');

  $smOpen.click(function() {
    $smMain.fadeIn();
    $bodyOv.addClas('hiddenOverflow');
  });
  $smClose.click(function() {
    $smMain.fadeOut();
    $bodyOv.removeClas('hiddenOverflow');
  });

  /* Chuyển jumpbox thành sitemap by Zzbaivong */
  var $cat = $("<ul>", {
    "data-level": 2,
    "class": "group-map"
  });

  $("#zzSitemap").html($cat);

  var $link = "";
  var $li = "";
  var catLevel = 2;
  var currLevel = 0;

  $('option', '[name="selected_id"]').each(function() {

    var $this = $(this);
    var $val = $this.val();

    if ($val != "-1") {

      var $html = $this.html();
      var $name = $html.match(/^.*\|--(.*)/)[1];
      currLevel = $html.split(/&nbsp;|\|/).length;

      if (catLevel < currLevel) {
        $li.addClass("cat-map");
        $("<ul>", {
          "data-level": currLevel,
          "class": "group-map"
        }).appendTo($li);
      }

      $link = $("<a>", {
        href: "/" + $val + "-jump",
        text: $name
      });

      $li = $("<li>", {
        html: $link
      });

      $li.appendTo('.group-map[data-level="' + currLevel + '"]:last');

      catLevel = currLevel;

    }

  });

});


ACP >> Display >> Templates >> Quản Lý Tổng Thể >> overall_footer_end
Tìm
Code:
<!-- BEGIN switch_facebook_login -->


Chèn vào trước nó:
Code:
<div id="sitemapOverlay">
  <div id="sitemapSection">
    <h3 id="sitemapHeading"> Điều hướng nhanh </h3>
 
    <div id="sitemapMain">
      <div class="sitemapColumn" style="width:30%;border-right:1px solid #ddd;">
        <div class="sitemapInhead"> Liên kết thông dụng </div>
        <ul class="sitemapQuickLinks">
          <li><a href="/">Trang chủ</a></li>
          <li><a href="/forum">Diễn đàn</a></li>
          <!-- BEGIN switch_user_logged_out -->
          <li><a href="/register">Đăng ký</a></li>
          <li><a href="/login">Đăng nhập</a></li>
          <!-- END switch_user_logged_out -->
          <!-- BEGIN switch_user_logged_in -->
          <li><a href="/login?logout=1">Thoát</a></li>
          <!-- END switch_user_logged_in -->
        </ul>
        <!-- BEGIN switch_user_logged_in -->
        <ul class="sitemapQuickLinks">
          <li><a href="/profile?mode=editprofile">Sửa thông tin</a></li>
          <li><a href="/profile?mode=editprofile&page_profil=avatars">Đổi ảnh đại diện</a></li>
          <li><a href="/search?search_id=newposts">Xem bài viết mới</a></li>
          <li><a href="/privmsg?folder=inbox">Tin nhắn riêng</a></li>
        </ul>
        <!-- END switch_user_logged_in -->
      </div>
      <div class="sitemapColumn" style="width:70%">
        <div class="sitemapInhead"> Danh sách diễn đàn </div>
        <div id="zzSitemap"></div>
      </div>
    </div>
 
    <div id="sitemapOption">
      <a id="sitemapClose"> Đóng </a>
    </div>
  </div>
</div>


Tiếp theo là nút nhấn vào sẽ hiện sitemap:

Code:
<a class="sitemapOpen" href="#sitemap"> Điều hướng nhanh </a>

Các bạn có thể để nó ở bất cứ chỗ nào các bạn cho là phù hợp.


Lưu ý

Như đã nói ở phần hướng dẫn, tutorial này dựa vào jumpbox mặc định của forumotion chuyển về dạng sitemap, nếu bạn chưa biết nó là cái gì thì hình dáng của nó như thế này ở cuối forum:
Topics tagged under tutorial on DEVs forumvi 4pWLjlq

Nếu bạn chỉ ẩn nó thì không sao, tut vẫn hoạt động bình thường, nhưng nếu bạn đã xóa nó khỏi forum thì bắt buộc phải thêm lại.
Đây là code của nó trong overall_footer_begin
Code:
<form action="{S_JUMPBOX_ACTION}" method="get" name="jumpbox" onsubmit="if(document.jumpbox.f.value == -1){return false;}" id="qjump">
 <fieldset>{S_JUMPBOX_SELECT}</fieldset>
 </form>



Nguồn

Zzbaivong - devs.forumvi.com
KirigayaKazuto (Mạc Lục Phàm) - devs.forumvi.com
Tags: #tutorial #tut #sitemap #jumbox #xenforo #gist

[TUTs] Việt hóa Post option

Diễn đàn: TUTsTrả lời: 9Lượt xem: 3504

 15.06.15 10:09

Đây là cách để đưa các nút Quote, Edit, Delete,... từ dạng hình ảnh về dạng văn bản thuần.

Lưu ý: Tut này được viết dựa trên mã nguồn mặc định của viewtopic_body trên tất cả các version. Nếu bạn đã đổi template này thì phải kiểm tra lại phần tử bọc ngoài của các nút này.

Đây là kết quả bạn có được:
https://jsfiddle.net/maclucpham/Lgk8rh1u/embedded/result/


Hướng dẫn


ACP >> Display >> Pictures and Colors >> Colors >> CSS Stylesheet
Chèn đoạn này vào CSS:
Code:
/* Việt hóa postOption */
a[href^="/"][href*="mode="][href*="p="] {display:inline-block;padding:2px 8px;}
a[href^="/"][href*="mode="][href*="p="] .optionpLink {padding-left:5px;}


ACP >> Modules >> HTML & JAVASCRIPT >> Javascript codes management >> Topics tagged under tutorial on DEVs forumvi AjouterCreate a new javascript

Title * : Việt hóa postOption
Placement : In the topic
Javascript Code * :

Code:
$(function() {
  var version = 0;
  var selection = [".posting-icons", ".post-options", ".profile-icons"][version];
  var topicOption = {
    'edit': {
      text: "Sửa bài viết",
      icon: "pencil"
    },
    'delete': {
      text: "Xóa bài viết",
      icon: "times"
    },
    'quote': {
      text: "Trích dẫn",
      icon: "comment"
    },
    'ip': {
      text: "Xem IP",
      icon: "flag"
    }
  };
  $.each(topicOption, function(mode, val) {
    $(selection).find('a[href*=' + mode + ']').html('<i class="fa fa-' + val.icon + '"></i><span class="optionpLink">' + val.text + '</span>');
  });
});


Ghi chú:

Trong hướng dẫn trên ở dòng thứ 2, các bạn sẽ thấy số 0:
Code:
 var version = 0;


Đây là phiên bản Forumotion của bạn. Mặc định mình để là invision
Thay vào đó là một trong các giá trị sau tùy theo phiên bản của forum bạn:
0 : Invision
1 : punBB & phpBB2
2 : phpBB3

Nếu template viewtopic_body của bạn đã thay đổi thì dòng thứ 2 và 3:
Code:
 var version = 0;
  var selection = [".posting-icons", ".post-options", ".profile-icons"][version];


Các bạn sử thành
Code:
 var selection = "selector";

Thay selector thành Phần tử bọc ngoài của postOption


Nếu forum bạn chưa có bộ Font Awesome thì vào over_header đặt sau
Code:
{CSS}

đoạn code này:
Code:
<link href="http://netdna.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet" />


Để tìm hiểu về bộ font này, mời các bạn xem qua bài viết: [Tips] Huớng dẫn sử dụng Font Awesome


Nguồn


KirigayaKazuto (Mạc Lục Phàm) - devs.forumvi.com
Tags: #mod #tutorial #tut #việt-hóa #post-option

[Add-ons] Forumotion backup templates

Diễn đàn: Add-onsTrả lời: 26Lượt xem: 9002

 23.05.15 11:18

Forumotion Backup Templates



Giới thiệu


Tiện ích này sẽ giúp bạn lưu trữ và cài đặt tất cả Template trong Forumotion một cách nhanh chóng và chính xác.


  • Tất cả Template sẽ được nén vào một tệp zip nên rất thuận tiện lưu trữ và chia sẻ.
  • Cài đặt tệp zip lưu trữ từ máy sẽ có đủ thông tin và được cảnh báo về phiên bản giúp tránh nhầm lẫn.
  • Chế độ One-Click: Đơn giản hóa thao tác với 1 click, sử dụng khi cần cài đặt và lưu trữ toàn bộ Template.
  • Thông báo trên màn hình khi tiến trình hoàn tất, bạn chỉ cần giữ tab mở trong lúc tiện ích đang xử lý và làm việc khác.
  • Để đảm bảo bạn không vô tình tắt trình duyệt khi tiến trình đang chạy, một cảnh báo đã được thêm vào.


Cài đặt


Google Chrome: [You must be registered and logged in to see this link.]
Sau khi tải xong, bạn mở tab chrome://extensions/ và kéo thả file cxr vừa tải vào để cài đặt.
Firefox: [You must be registered and logged in to see this link.]
Opera: [You must be registered and logged in to see this link.]

Phiên bản Userscript cho các trình duyệt khác: [You must be registered and logged in to see this link.].


Ảnh chụp màn hình


[You must be [You must be registered and logged in to see this link.] and [You must be registered and logged in to see this link.] to see this image.]
Tiện ích vừa hoàn tất lưu trữ toàn bộ Template

Xem thêm ảnh chụp màn hình khác tại đây.


Video hướng dẫn


Google Chrome: [You must be registered and logged in to see this link.]
Firefox: [You must be registered and logged in to see this link.]
Opera: [You must be registered and logged in to see this link.]


Mã nguồn


[You must be registered and logged in to see this link.]

Tài nguyên

jsZip (v2.5.0) By StuartKnightley
jszip-utils (v0.0.2) By Stuart Knightley, David Duponchel
FileSaver (2015-05-07.2) By Eli Grey
ForumotionBackupTemplates (v2.0.1) By [You must be registered and logged in to see this link.]


Tác giả


[You must be registered and logged in to see this link.] (https://devs.forumvi.com)
Tags: [You must be registered and logged in to see this link.]

[Hỏi đáp] Thanh đường dẫn đẹp

Diễn đàn: Đã giải đápTrả lời: 4Lượt xem: 1817

 24.12.14 12:20

Thanh breadcrumb giúp người dùng dễ dàng điều hướng, biết được vị trí trong diễn đàn. Trong phiên bản PunBB thì nó gặp lỗi nhỏ ở các trang phụ, và cũng khó tùy chỉnh giao diện. Hướng dẫn này sẽ dùng Javascript điều chỉnh lại cấu trúc của breadcrumb trong PunBB, và thêm CSS để có được giao diện thân thiện hơn.

Topics tagged under tutorial on DEVs forumvi Nav_610


Hướng dẫn


Trước tiên hãy xóa hết CSS và JS liên quan đến breadcrumb (thanh đường dẫn) mà bạn đã thêm vào, rồi làm theo hướng dẫn sau:

Bước 1

Trong template overall_footer_begin, tìm:
Code:
<div id="pun-foot">

Thêm vào trước đó, code sau:
Code:
<script type="text/javascript">
//<![CDATA[
/* breadcrumb for punbb - devs.forumvi.com */
$(".pun-crumbs").each(function() {
    var $crumbs = $(this);
    $crumbs.find("strong").has("a").replaceWith(function() {
        return this.innerHTML;
    });
    var $items = $crumbs.find(".crumbs").children(),
        $navstrip = $('<ul class="navstrip clearfix"></ul>');
    $crumbs.empty().html($navstrip);
    $items.not(":empty").appendTo($navstrip).wrap("<li></li>");
    $items.first().parent().addClass("begin");
}).html(function() {
    return this.innerHTML.replace(/(»\s|&nbsp\;»&nbsp\;)/g, "");
});
//]]>
</script>


Bước 2

Thêm vào CSS:
Code:
/* breadcrumb for punbb - devs.forumvi.com */
.pun-crumbs{padding:1em 0}
.navstrip{color:#e8e8e8;font-weight:700;list-style:none;background:#fff;margin:20px 0;border:1px solid #ddd}
.navstrip > li{float:left;color:#666;margin:0;padding:0;line-height:36px;height:36px;display:block;position:relative;background:#FFF;padding:0 5px 0 20px}
.navstrip > li.begin{background-color:#1f537b;background-image:none;background-position:center;background-repeat:no-repeat;width:47px;padding-left:4px}
.navstrip li a{font-weight:700;text-decoration:none}
.navstrip > li.begin > a{text-indent:-9999px;display:block;background:url(http://i39.servimg.com/u/f39/19/09/43/62/house411.png) no-repeat center center transparent}
.navstrip > li:before,.navstrip > li:after{content:" ";border:18px solid transparent;border-left-width:12px;border-right:0;border-left-color:#FFF;display:block;position:absolute;right:-12px;top:0;z-index:10;width:0;height:0}
.navstrip > li:after{border-left-color:#DBDBDB;right:-13px;z-index:5}
.navstrip > li.begin:before{border-left-color:#1f537b}
.navstrip > li:hover,.navstrip > li:hover a{background-color:#333;color:#FFF}
.navstrip > li:hover:before{border-left-color:#333}



Tác giả

@Zzbaivong
Tags: #punbb #breadcrumb #mod #tutorial

[TUTs] zzRank - Thêm huân chương theo số bài viết

Diễn đàn: TUTsTrả lời: 30Lượt xem: 10638

 09.09.14 16:13

zzRank sẽ tạo ra nhiều kiểu huân chương cho từng mốc bài viết. Bằng cách kết hợp với điều kiện điểm thưởng và lượt cảm ơn, huân chương của bạn sẽ phong phú và hợp lý hơn.

Khi bạn sử dụng rank mặc định của forumotion sẽ chỉ có một huân chương cho mỗi cấp bậc, thay đổi mỗi khi lên cấp. Với zzRank, bạn có thể giữ lại huân chương của cấp bên dưới và bổ sung thêm các điều kiện về điểm thưởng, lượt cảm ơn để tạo thêm nhiều kiểu huận chương mới trong cùng cấp bậc đó.

Các thông số cho từng kiểu huân chương được viết ở dạng plainObject nên rất dễ tùy chỉnh và áp dụng.


Demo


http://jsfiddle.net/baivong/a5k3yjgo/2/show/


Hướng dẫn


Bước 1


Tìm trong temp viewtopic_body:
Code:
<!-- BEGIN profile_field -->
{postrow.displayed.profile_field.LABEL}{postrow.displayed.profile_field.CONTENT}{postrow.displayed.profile_field.SEPARATOR}
<!-- END profile_field -->

Sửa thành:
Code:
<!-- BEGIN profile_field -->
<p class="profile_field_mess">
    {postrow.displayed.profile_field.LABEL}{postrow.displayed.profile_field.CONTENT}{postrow.displayed.profile_field.SEPARATOR}
</p>
<!-- END profile_field -->


Bước 2


Đặt code sau ở nơi muốn hiển thị rank:
Code:
<div class="rank_mess"></div>

Lưu ý: Vị trí của code phải nằm trong .post

Bước 3


Tạo một file js, check vào In the topics:
Code:
/*!
 * zzRank v0.2.1 by Zzbaivong <devs.forumvi.com>
 * Thêm huân chương dựa theo số lượng bài viết
 */
$(function() {
    var data_rank = {
        10: {
            title: "10 bài viết",
            desc: "Huân chương tưởng thưởng cho thành viên tích cực, đăng 10 bài viết trở lên. Điểm thưởng tối thiểu là 20.",
            icon: "http://blog.uhm.vn/emo/laluot/2.gif",
            point: 20
        },
        50: {
            title: "50 bài viết",
            desc: "Huân chương tưởng thưởng cho thành viên tích cực, đăng 50 bài viết trở lên. Điểm tưởng lớn hơn hoặc bằng số bài viết.",
            icon: "http://blog.uhm.vn/emo/laluot/5.gif",
            point: ">"
        },
        100: {
            title: "100 bài viết",
            desc: "Huân chương tưởng thưởng cho thành viên tích cực, đăng 100 bài viết trở lên. Được cảm ơn từ 10 lần trở lên.",
            icon: "http://blog.uhm.vn/emo/laluot/20.gif",
            thank: 10
        },
        500: {
            title: "500 bài viết",
            desc: "Huân chương tưởng thưởng cho thành viên tích cực, đăng 500 bài viết trở lên. Điểm tưởng lớn hơn hoặc bằng số bài viết. Được cảm ơn từ 99 lần trở lên.",
            icon: "http://blog.uhm.vn/emo/laluot/10.gif",
            point: ">",
            thank: 99
        },
        x500: {
            title: "Spamer",
            desc: "Thành viên đăng 500 bài viết trở lên, nhưng điểm thưởng thấp hơn số bài viết.",
            icon: "http://blog.uhm.vn/emo/laluot/24.gif",
            point: "<"
        }
    };
    
    function checkif(key, check, val, post) {
        var cPost = data_rank[key][check];
        if (($.type(cPost) === "number" && cPost <= val) || ($.type(cPost) === "string" && cPost === ">" && val >= post) || ($.type(cPost) === "string" && cPost === "<" && val < post)) {
            return true;
        } else {
            return false;
        }
    }

    function getNumber(t, txt) {
        return parseInt($(t).closest(".post").find(".profile_field_mess:contains('" + txt + " : ')").text().match(/\d+/)[0], 10);
    }

    $(".rank_mess").html(function() {
        var all = "";

        var post_mess = getNumber(this, "Posts"),
            point_mess = getNumber(this, "Points"),
            thank_mess = getNumber(this, "Thanked");

        $.each(data_rank, function(key, val) {

            var point = data_rank[key].point,
                thank = data_rank[key].thank;

            if (post_mess >= parseInt(key.match(/\d+/)[0], 10)) {
                if ((point === undefined && thank === undefined) || (point !== undefined && thank === undefined && checkif(key, "point", point_mess, post_mess)) || (point === undefined && thank !== undefined && checkif(key, "thank", thank_mess, post_mess)) || (point !== undefined && checkif(key, "point", point_mess, post_mess) && thank !== undefined && checkif(key, "thank", thank_mess, post_mess))) {

                    all += '<fieldset><legend>' + data_rank[key].title + '</legend><img src="' + data_rank[key].icon + '" alt="' + data_rank[key].title + '" title="' + data_rank[key].desc + '" /></fieldset>';

                }
            }

        });

        return all;
    });
});


Lưu ý: Trong code trên, ở dòng 56, thay từ Posts bằng từ chú thích số lượng bài viết của thành viên, trong diễn đàn của bạn. Tương tự với từ Points, Thanked.


Ghi chú


Chỉnh sửa lại thông số data_rank(dòng 6 - 38) theo ý muốn, trong đó:
Code:
// Đây là thiết lập cho một rank, ở một mức bài viết
10: { // 10 là số bài tối thiểu để đạt được huân chương
    title: "10 bài viết", // Ghi chú ngắn gọn cho huân chương
    desc: "Huân chương tưởng thưởng cho thành viên tích cực, đăng 10 bài viết trở lên.", // Ghi chú chi tiết cho huân chương
    icon: "http://blog.uhm.vn/emo/laluot/2.gif" // Ảnh huân chương sẽ hiển thị
}


Bạn cũng có thể thêm điều kiện point và thank nếu muốn, ví dụ:
Code:
point: ">" // point >= post
point: "<" // point < post
point: 3 // point >= 3


Nếu như mức bài viết trùng nhau, như trong ví dụ trên, trùng mức 500 bài viết, thì bạn thêm ký tự bất kỳ ở trước.

Để thêm từng mức bài khác nhau thì bạn dùng lặp lại cấu trúc trên, lưu ý là ở nhóm cuối cùng không có dấu phẩy (,).

Nếu biết cách sử dụng plainObject, bạn cũng có thể tự thêm các thông tin khác cho phù hợp.


Xem v0.1 tại: https://devs.forumvi.com/t861-hoi-ap-js-xet-rank-nhe-nhat-co-the?showpost=p5584


Nguồn


Zzbaivong (devs.forumvi.com)
Tags: #mod #tutorial #phpbb2 #phpbb3 #punbb #invision #rank

 23.07.14 22:36

jQuery plugin Announcement sẽ gói gọn tất cả thông báo vào một bảng nhỏ nằm bên dưới diễn đàn, cách sử dụng không có nhiều khác biệt với chức năng mặc định nên bạn sẽ không gặp chút khó khăn nào để làm quen với nó.
Nếu bạn đã thấy nhàm chán với thông báo chạy phía trên diễn đàn thì đây chắc chắn sẽ là lựa chọn tuyệt vời dành cho bạn.

Topics tagged under tutorial on DEVs forumvi Screenshot
Giao diện chức năng thông báo


Demo


https://baivong.github.io/announcement/


Chức năng


  1. Giữ lại các tuỳ chọn của chức năng thông báo mặc định.
  2. Dễ dàng xem từng tin riêng.
  3. Cho phép người dùng ẩn hoặc tắt bảng.
  4. 15 hiệu ứng chuyển tin.


Hướng dẫn


Cài đặt


ACP >> Display >> Templates >> QLTT >> overall_header

Tìm:
Code:
{JS_DIR}jquery/ticker/ticker.css

và thay bằng:
Code:
//baivong.github.io/announcement/dist/jquery.announcement.css


Tìm:
Code:
{JS_DIR}jquery/ticker/ticker.js

và thay bằng:
Code:
//baivong.github.io/announcement/dist/jquery.announcement.min.js


Tìm:
Code:
Ticker.start({
    height : {switch_ticker.HEIGHT},
    spacing : {switch_ticker.SPACING},
    speed : {switch_ticker.SPEED},
    direction : '{switch_ticker.DIRECTION}',
    pause : {switch_ticker.STOP_TIME}
});

và thay bằng:
Code:
var tickerDirection = '{switch_ticker.DIRECTION}',
    tickerEffect = '',

    tickerWidth = {switch_ticker.SPACING},
    tickerHeight = {switch_ticker.HEIGHT};

if (tickerWidth === 0) tickerWidth = 'auto';
if (tickerHeight === 0) tickerHeight = 'auto';

switch (tickerDirection) {
    case 'top':
        tickerEffect = 'zoom-in';
        break;

    case 'left':
        tickerEffect = 'rotate-left';
        break;

    case 'bottom':
        tickerEffect = 'zoom-out';
        break;

    case 'right':
        tickerEffect = 'shuffle';
        break;

    default:
        tickerEffect = 'fading';
}

$('#announcements').announcement({

    title: 'Thông báo',

    showToggle: true,
    showClose: !!{switch_ticker.STOP_TIME},

    position: 'bottom-right',

    width: tickerWidth,
    height: tickerHeight,

    speed: {switch_ticker.SPEED},

    effect: tickerEffect

});

Nếu bạn muốn bảng thông báo nằm bên trái thì trong code trên, dòng 38, sửa bottom-right thành bottom-left. Ở dòng 33, bạn cũng có thể thay Thông báo, bằng tiêu đề khác phù hợp hơn.

Tìm:
Code:
<!-- BEGIN switch_ticker -->
<div id="fa_ticker_block" style="padding-top:4px;">
    <div class="module main">
        <div class="main-content clearfix">
            <div id="fa_ticker_container">
                <div id="fa_ticker" style="height:{switch_ticker.HEIGHT}px;">
                    <div class="fa_ticker_content">
                        <!-- BEGIN ticker_row -->
                        <div>{switch_ticker.ticker_row.ELEMENT}</div>
                        <!-- END ticker_row -->
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<!-- END switch_ticker -->

và thay bằng:
Code:
<!-- BEGIN switch_ticker -->
<div id="fa_ticker_block" style="display: none;">
    <ul id="announcements">
        <!-- BEGIN ticker_row -->
        <li>{switch_ticker.ticker_row.ELEMENT}</li>
        <!-- END ticker_row -->
    </ul>
</div>
<!-- END switch_ticker -->


Tìm và xoá:
Code:
<!-- BEGIN switch_ticker_new -->
Bao gồm cả code nằm bên trong nó
Có 3 đoạn switch_ticker_new như thế này
<!-- END switch_ticker_new -->


Sử dụng


ACP >> QLTT >> Messages and e-mails >> Announcements

>> General announcements options: Tùy chọn chức năng

  • Activate announcements : Bật/tắt chức năng thông báo
  • Announcements display : Trang sẽ hiển thị thông báo
  • Scrolling : Hiệu ứng chuyển tin thông báo.
  • Scrolling speed : Thời gian chuyển giữa 2 tin kế tiếp. Đơn vị: giây(seconds).
  • Stop time : jQuery Announcement sử dụng thông số này với vai trò showClose, nhận 2 giá trị 0 hoặc 1 để tắt hoặc bật nút đóng.
  • Space between announcements (in pixels) : jQuery Announcement sử dụng thông số này với vai trò width để xác định chiều rộng. Đơn vị: px(pixels).
  • Announcements block height (in pixels) : jQuery Announcement sử dụng thông số này với vai trò height để xác định chiều cao. Đơn vị: px(pixels).

Topics tagged under tutorial on DEVs forumvi Announ10
Ví dụ cách tùy chỉnh

>> Announcements: Danh sách các tin thông báo

Bạn có thể thêm nhiều thông báo mới bằng cách click vào nút +.
Nếu bạn chọn ScrollingDeactivate, thì thông báo sẽ chỉ hiển thị duy nhất tin đầu tiên.


Nguồn


Zzbaivong (devs.forumvi.com)
Tags: #mod #jquery-plugin #tutorial #phpbb2 #phpbb3 #punbb #invision #announcement

 06.05.14 18:24

CodeMirror là một Text editor, viết bằng Javascript hoạt động trên trình duyệt, được dùng trong dev tool của Chrome, Firefox và nhiều Text editor khác như Brackets,  Light Table, ... Trong forumotion, nó được dùng làm công cụ chỉnh sửa CSS, Templates, trang html.
Ở bài này mình sẽ ứng dụng nó để làm nổi bật cú pháp trong code. Xét về dung lượng, nó có vẻ hơi khủng nếu đem so với 2 cách dùng plugin Google Code Prettify và Prismjs mà mình giới thiệu trước đây. Tuy nhiên, trái với vẻ bề ngoài nặng nề, nó có tốc độ xử lý rất nhanh và ổn định.


Chức năng


Ưu điểm


  • Chức năng di chuyển nhanh bằng cách nhập số dòng. Nhập 0 để chuyển đến dòng cuối.
  • Hỗ trợ chọn nhanh toàn bộ code.
  • Xử lý nhanh chóng, phân biệt rõ cú pháp trong code.
  • 30 giao diện thoải mái lựa chọn.
  • Hỗ trợ rất nhiều Add-on và API nếu bạn muốn tùy chỉnh thêm.

Nhược điểm


  • Chỉ áp dụng cho 3 loại ngôn ngữ HTML-CSS-JS.
  • Một số mã regexp không được xác định đúng.

Cập nhật: Sử dụng phiên bản mới nhất cho các addon (21/6/2015), và thay thế core của codemirror bằng addon stand-alone, giúp giảm dung lượng từ 192kb xuống còn 48kb.

Demo

[You must be [You must be registered and logged in to see this link.] and [You must be registered and logged in to see this link.] to see this image.]
Giao diện zzCodeMirror


Hướng dẫn


Tạo file javascript zzCodeMirror
Title * : zzCodeMirror
Placement : In all the pages
Javascript Code * :
Code:
$(function() {
    window.codeTranslate = {
        gotoLineOffsetTop: 5
    };
    $("code").length && $.getScript("http://baivong.github.io/cdn/devsforumvi/js/35300.js");
});

Trong code trên, gotoLineOffsetTop là tham số khoảng cách của dòng code với mép trên trình duyệt. Nếu bạn sử dụng Toolbar của forumotion thì thay số 5 bằng 35.

Chú ý:
zzCodeMirror không sử dụng được cho phpBB2.
Gỡ bỏ các mod, plugin liên quan đến khung code trước khi sử dụng.
Nên upload lại file CSS và Javascript lên host của riêng bạn khi sử dụng, ví dụ như Google. Xem hướng dẫn [You must be registered and logged in to see this link.].
zzCodeMirror được tùy biến để nhận dạng 3 ngôn ngữ HTML - CSS - Javascript, đây là phần mình viết thêm nên nếu gặp lỗi thì gửi báo cáo ngay tại chủ đề này. Thử nghiệm tại [You must be registered and logged in to see this link.]


Phiên bản áp dụng

phpBB3, punBB, Invision


Source code


CSS

[You must be registered and logged in to see this link.]

Javascript

[You must be registered and logged in to see this link.]


Nguồn


Zzbaivong (devs.forumvi.com)
Tags: [You must be registered and logged in to see this link.]

[Hỏi đáp] Chèn ảnh cho từng topic_list_box

Diễn đàn: Đã giải đápTrả lời: 4Lượt xem: 1423

 15.04.14 10:31

Cách 1

Dùng thuộc tính background.

Trong temp viewforum_body, tìm:
Code:
{BOARD_INDEX}


... thêm vào bên dưới:
Code:
<div id="banner{FORUM_ID}" class="main paged banner-category"></div>


Thêm vào CSS (mẫu):
Code:
.banner-category {
    height: 150px;
    background: url(IMG_1) no-repeat center center/auto 100% transparent;
    background-size: cover;
}
#banner2 {
    background-image: url(IMG_2);
}
#banner7 {
    background-image: url(IMG_7);
}


Lưu ý

Trong code trên:

IMG_1 là link ảnh dùng làm banner mặc định cho tất cả chuyên mục.

Để đặt banner riêng cho mỗi chuyên mục thì thêm thuộc tính background-image cho [b]#banner<forum id>[/b] (trong ví dụ trên là chuyên mục 27).

Nếu không muốn dùng banner mặc định thì,
sửa: url(IMG_1) thành none,
và xóa height: 150px;
Nếu dùng cách này thì khi thêm banner riêng, nhớ bổ sung thuộc tính height.


Cách 2

Dùng link ảnh cố định.

Để dùng cách này thì bạn phải tải ảnh lên host cho phép giữ nguyên tên ảnh và đường dẫn chung, ví dụ photobucket, dropbox... Trong đó tên ảnh là forum id.

Trong temp viewforum_body, tìm:
Code:
{BOARD_INDEX}


... thêm vào bên dưới:
Code:
<div class="main paged">
    <img src="../images/{FORUM_ID}.png" />
</div>


Lưu ý

Code trên chỉ là ví dụ, link ảnh thay đổi theo host bạn dùng.
Tags: #mod #tutorial #punbb #category

[TUTs] Quick register - Đăng ký nhanh

Diễn đàn: Lưu trữTrả lời: 21Lượt xem: 4998

 23.03.14 12:26

Hướng dẫn này sẽ giúp bạn tạo chức năng Đăng ký nhanh cho diễn đàn, người dùng sau khi điền đủ thông tin đăng ký, tài khoản sẽ được kích hoạt và tự đăng nhập ngay sau đó.


Chức năng


  • Đăng ký thành viên nhanh.
  • Tự đăng nhập sau khi đăng ký.
  • Quay trở lại trang đang xem.
  • Không cần kích hoạt tài khoản.
  • Giới hạn số lần đăng ký theo IP.
  • Áp dụng cho tất cả liên kết đăng ký.
  • Giao diện gọn, đẹp.
  • Hỗ trợ ngôn ngữ Anh - Việt.



Demo

[You must be [You must be registered and logged in to see this link.] and [You must be registered and logged in to see this link.] to see this image.]



Hướng dẫn


Bước 1

Tùy chỉnh
ACP >> General >> Forum >> Security >> Security Administration
Giới hạn số tài khoản có thể tạo trong 24h cho một IP:
IP address accounts creation limit, for each 24 hours : 10

ACP >> Users & Groups >> Users >> Users options
Cho phép tự kích hoạt tài khoản:
New accounts activation : No activation
Bỏ yêu cầu nhập mã captcha:
Confirmation code : No
Cho phép đăng ký thành viên:
Allow new members : Yes

ACP >> Users & Groups >> Users >> Profiles >> Profile fields >> [You must be [You must be registered and logged in to see this link.] and [You must be registered and logged in to see this link.] to see this image.]Modify
Bỏ hết các field bắt buộc khi đăng ký:
Necessarily filled ? No

Bước 3

Sửa Template
ACP >> Display >> Templates >> General >> overall_footer_begin

Tìm:
Code:
<div id="pun-foot">


Đặt trước nó:
Code:
<!-- Quick register by Zzbaivong - devs.forumvi.com -->
<!-- BEGIN switch_user_logged_out -->
<div id="qick_reg_overlay" style="z-index:99999;"></div>
<div id="qick_reg" style="z-index:999999;">
   <div id="reg_loder">Đang kiểm tra dữ liệu...</div>
   <p id="reg_tip">Bạn phải điền đầy đủ thông tin đăng ký.</p>
   <a href="javascript:void(0)" class="modal_close"></a>
   <form onsubmit="submit_reg(); return false" action="/register?agreed=true&step=2" method="post" name="post" id="ucp">
      <div class="main-content frm" style="border: 0px none;">
         <fieldset class="frm-set multi" style="border: 0px none; margin:0;background-color: #FFF;">
            <dl>
               <dt>
                  <label>Tên tài khoản :</label>
               </dt>
               <dd>
                  <input autocomplete="off" type="text" id="username_reg" name="username" value="" size="25" maxlength="25" required />
                  <div id="name_reg" class="check_reg">
                     <div class="pwd_img reg_er kytu">Số ký tự phải từ 3 trở lên</div>
                     <div class="pwd_img reg_er loi">Hãy chọn tài khoản khác</div>
                     <div class="pwd_img reg_ok">Có thể dùng tài khoản này</div>
                  </div>
               </dd>
            </dl>
            <dl>
               <dt>
                  <label>Địa chỉ E-mail :</label>
               </dt>
               <dd>
                  <input autocomplete="off" class="ltr" type="email" id="email" name="email" value="" size="25" maxlength="64" required />
                  <div id="email_reg" class="check_reg">
                     <div class="pwd_img reg_er">Không sử dụng địa chỉ này</div>
                     <div class="pwd_img reg_wa">E-mail sẽ được kiểm sau</div>
                  </div>
               </dd>
            </dl>
            <dl>
               <dt>
                  <label>Mật khẩu :</label>
               </dt>
               <dd>
                  <input autocomplete="off" class="ltr" type="password" id="password_reg" name="password" value="" size="25" maxlength="25" required />
                  <div class="check_reg" id="cont_pwd">
                     <div class="pwd_img reg_er kytu">Số ký tự phải từ 3 trở lên</div>
                     <div class="pwd_img reg_er trung">Trùng tên đăng nhập</div>
                     <div class="pwd_img" id="pwd_bad" style="display: none;">Quá đơn giản</div>
                     <div class="pwd_img" id="pwd_middle" style="display: none;">Tạm ổn</div>
                     <div class="pwd_img" id="pwd_good" style="display: none;">Vãi</div>
                  </div>
               </dd>
            </dl>
            <dl>
               <dt>
                  <label>Gõ lại mật khẩu :</label>
               </dt>
               <dd>
                  <input autocomplete="off" type="password" id="password_confirm" size="25" maxlength="25" name="password_confirm" class="inputbox narrow" required />
                  <div id="pass_co" class="check_reg">
                     <div class="pwd_img reg_er">Chưa đúng</div>
                     <div class="pwd_img reg_ok">Chính xác</div>
                  </div>
               </dd>
            </dl>
            <dl class="frm-buttons">
               <p style="padding: 10px 0px 0px; text-align: center;">
                  <input class="button2" type="submit" name="submit" value="Đăng ký" />
                  <input class="button2" type="reset" name="reset" value="Làm mới" />
               </p>
            </dl>
         </fieldset>
      </div>
   </form>
</div>
<script type="text/javascript" src="{Js}"></script>
<!-- END switch_user_logged_out -->


Bước 4

ACP >> Modules >> HTML & JAVASCRIPT >> Javascript codes management
Tạo file javascript, lấy liên kết (Không check Placement) thay vào vị trí {Js} ở cuối code trong bước 3

Code:
/* Quick register by Zzbaivong - devs.forumvi.com */
var shortPass = "bad",
    badPass = "bad",
    goodPass = "good",
    strongPass = "strong";

function passwordStrength(a, b) {
    score = 0;
    if ("" == a) return null;
    if (4 > a.length) return shortPass;
    if (void 0 != b && a.toLowerCase() == b.toLowerCase()) return badPass;
    score += 4 * a.length;
    score += 1 * (checkRepetition(1, a).length - a.length);
    score += 1 * (checkRepetition(2, a).length - a.length);
    score += 1 * (checkRepetition(3, a).length - a.length);
    score += 1 * (checkRepetition(4, a).length - a.length);
    a.match(/(.*[0-9].*[0-9].*[0-9])/) && (score += 5);
    a.match(/(.*[!,@,#,$,%,^,&,*,?,_,~].*[!,@,#,$,%,^,&,*,?,_,~])/) && (score += 5);
    a.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/) &&
        (score += 10);
    a.match(/([a-zA-Z])/) && a.match(/([0-9])/) && (score += 15);
    a.match(/([!,@,#,$,%,^,&,*,?,_,~])/) && a.match(/([0-9])/) && (score += 15);
    a.match(/([!,@,#,$,%,^,&,*,?,_,~])/) && a.match(/([a-zA-Z])/) && (score += 15);
    if (a.match(/^\w+$/) || a.match(/^\d+$/)) score -= 10;
    0 > score && (score = 0);
    100 < score && (score = 100);
    return 34 > score ? badPass : 68 > score ? goodPass : strongPass
}

function checkRepetition(a, b) {
    res = "";
    for (i = 0; i < b.length; i++) {
        repeated = !0;
        for (j = 0; j < a && j + i + a < b.length; j++) repeated = repeated && b.charAt(j + i) == b.charAt(j + i + a);
        j < a && (repeated = !1);
        repeated ? (i += a - 1, repeated = !1) : res += b.charAt(i)
    }
    return res
}

function submit_reg() {
    $("#reg_tip").text("Đang kiểm tra dữ liệu...");
    $("#qick_reg .reg_er").each(function() {
        "block" == $(this).css("display") && $(this).parent().parent().addClass("error")
    });
    $("#qick_reg input").each(function() {
        "" == $(this).val() && $(this).parent().addClass("error")
    });
    $("#qick_reg .error").length ? $("#reg_tip").text("Lỗi thông tin đăng ký.") : ($("#reg_loder").show(), $.ajax({
        type: "POST",
        url: "/register?agreed=true&step=2",
        data: {
            username: $("#username_reg").val(),
            email: $("#email").val(),
            "profile_field_3_-10": $("#profile_field_3_-10").val(),
            password: $("#password_reg").val(),
            submit: "Save"
        },
        success: function(a) {
            if ($(a).find("p.message").length) $("#reg_tip").text("Quản trị viên đã giới hạn số lần tạo tài khoản hôm nay."), $("#reg_loder").fadeOut(500), $("#ucp").hide();
            else if ($("#reg_tip").text("Đang kiểm tra tài khoản, mật khẩu..."),
                $(a).find("#form_confirm").length) $("#qick_reg .frm-buttons input[name='confirm_pass'], #qick_reg .frm-buttons input[name='auth[]']").remove(), $(a).find("input[name='confirm_pass'], input[name='auth[]']").prependTo("#qick_reg .frm-buttons"), $("#reg_tip").text("Đang kiểm tra E-mail..."), $.ajax({
                type: "POST",
                url: "/register?agreed=true&step=2",
                data: {
                    password_confirm: $("#password_confirm").val(),
                    "auth[]": $("#qick_reg input[name='auth[]']:first").val(),
                    username: $("#username_reg").val(),
                    email: $("#email").val(),
                    "profile_field_3_-10": $("#profile_field_3_-10").val(),
                    password: $("#password_reg").val(),
                    confirm_pass: $("#qick_reg input[name='confirm_pass']").val(),
                    submit: "Save"
                },
                success: function(a) {
                    if ($(a).find("p.message a").length) $("#reg_tip").text("Đăng ký thành công."), $.ajax({
                        type: "POST",
                        url: "/login",
                        data: {
                            username: $("#username_reg").val(),
                            password: $("#password_reg").val(),
                            login: "true"
                        },
                        success: function() {
                            window.location.reload()
                        }
                    });
                    else if (-1 != $(a).find("p.center:first span").text().indexOf("e-mail address") || -1 != $(a).find("p.center:first span").text().indexOf("địa chỉ email")) $("#reg_tip").text("Địa chỉ E-mail không hợp lệ hoặc đã được sử dụng."), $("#reg_loder").fadeOut(500), $("#email").parent().addClass("error"), $("#email_reg .reg_er").show().next().hide()
                }
            });
            else if (-1 != $(a).find("#main-content p.center:first span").text().indexOf("username has") ||
                -1 != $(a).find("p.center:first span").text().indexOf("ên truy cập")) $("#reg_tip").text("Tài khoản đã được sử dụng hoặc bị cấm."), $("#reg_loder").fadeOut(500), $("#username_reg").parent().addClass("error"), $("#name_reg div").hide(), $("#name_reg .reg_er.loi").show();
            else if (0 == $(a).find("p.center:first span").text().indexOf("Your password") || 0 == $(a).find("p.center:first span").text().indexOf("Mật khẩu")) $("#reg_tip").text("Mật khẩu phải từ 6 - 32 ký tự và không được trùng tài khoản."),
                $("#reg_loder").fadeOut(500), $("#password_reg, #password_confirm").val("").parent().addClass("error"), $("#cont_pwd div, #pass_co div").hide()
        }
    }))
}

function conpass() {
    "" != $("#password_confirm").val() ? ($("#password_confirm").parent().removeClass("error"), $("#password_reg").val() != $("#password_confirm").val() ? $("#pass_co .reg_er").show().next().hide() : $("#pass_co .reg_er").hide().next().show()) : $("#pass_co div").hide()
}

function isEmail(a) {
    return /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/.test(a)
}
$(function() {
    "/register" != location.pathname ? ($("a[href='/register']").click(function(a) {
        a.preventDefault();
        $("#qick_reg, #qick_reg_overlay").fadeIn()
    }), $("#qick_reg_overlay, .modal_close").click(function() {
        $("#qick_reg, #qick_reg_overlay").fadeOut()
    }), $("#qick_reg input[name='reset']").click(function() {
        $("#reg_tip").text("Bạn phải điền đầy đủ thông tin đăng ký.");
        $("#qick_reg dd").removeClass("error");
        $("#qick_reg .pwd_img").hide()
    }), $("#username_reg").on("blur",
        function() {
            "" != $("#username_reg").val() ? ($("#username_reg").parent().removeClass("error"), 3 > $("#username_reg").val().length ? ($("#name_reg .reg_er.kytu").show(), $("#name_reg .reg_er.loi, #name_reg .reg_ok").hide()) : $.ajax({
                type: "GET",
                url: "/search?mode=searchuser&fieldname=username",
                data: {
                    search_username: $("#username_reg").val(),
                    time: timestamp()
                },
                success: function(a) {
                    $("#name_reg div").hide();
                    $(a).find("#username_list").val() == $("#username_reg").val() ?
                        $("#name_reg .reg_er.loi").show() : $("#name_reg .reg_ok").show()
                }
            })) : $("#name_reg div").hide()
        }), $("#email").on("blur", function() {
        "" != $("#email").val() ? ($("#email").parent().removeClass("error"), isEmail($("#email").val()) ? $("#email_reg .reg_er").hide().next().show() : $("#email_reg .reg_er").show().next().hide()) : $("#email_reg div").hide()
    }), $("#password_confirm").on("input", function() {
        conpass()
    }), $("#password_reg, #username_reg").on("input",
        function() {
            if ("" != $("#password_reg").val())
                if ($("#password_reg").parent().removeClass("error"), 3 > $("#password_reg").val().length) $("#cont_pwd div").hide(), $("#cont_pwd .reg_er.kytu").show();
                else if ($("#cont_pwd .reg_er.kytu").hide(), $("#password_reg").val() == $("#username_reg").val()) $("#cont_pwd div").hide(), $("#cont_pwd .reg_er.trung").show();
            else switch ($("#cont_pwd .reg_er.trung").hide(), passwordStrength($("#password_reg").val(), $("#username_reg").val())) {
                case "bad":
                    $("#pwd_middle,#pwd_good").hide();
                    $("#pwd_bad").show();
                    break;
                case "good":
                    $("#pwd_good,#pwd_bad").hide();
                    $("#pwd_middle").show();
                    break;
                case "strong":
                    $("#pwd_middle,#pwd_bad").hide(), $("#pwd_good").show()
            } else $("#cont_pwd div, #pass_co div").hide(), $("#password_confirm").val("");
            "" != $("#password_confirm").val() && conpass()
        })) : $("#qick_reg, #qick_reg_overlay").remove()
});


Bước 5

Thêm vào CSS
ACP >> Display >> Pictures and Colors >> Colors >> CSS Stylesheet

Code:
/* Quick register by Zzbaivong - devs.forumvi.com */
#qick_reg_overlay{background:#000;position:fixed;left:0;top:0;width:100%;height:100%;display:none;opacity:0.8}
#qick_reg, #qick_reg *{box-sizing:border-box;-o-box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box}
#qick_reg{background-color:#FFF;border:1px solid rgba(0,0,0,0.333);box-shadow:0 4px 16px rgba(0,0,0,0.2);color:#000;outline:0 none;position:fixed;width:500px;display:none;left:50%;top:50%;margin-left:-250px;margin-top:-200px;padding:40px}
#qick_reg input{width:100%}
#qick_reg fieldset.frm-set dl dd,#qick_reg fieldset.frm-set dl dt{padding:0}
#qick_reg fieldset.frm-set dl dt{width:13em}
#qick_reg fieldset.frm-set dl dd{margin-left:14em}
#qick_reg #cont_pwd, #qick_reg .check_reg{float:none;height:24px;width: 100%;padding:2px 0!important}
#pwd_bad, .reg_er{background: url(http://i15.servimg.com/u/f15/16/58/89/73/001_3010.png) no-repeat scroll left center/16px 16px transparent;color:red}
#pwd_middle, .reg_wa{background:url(http://i15.servimg.com/u/f15/16/58/89/73/alert_10.png) no-repeat scroll left center/16px 16px transparent;color:blue}
#pwd_good, .reg_ok{background:url(http://i15.servimg.com/u/f15/16/58/89/73/001_0610.png) no-repeat scroll left center/16px 16px transparent;color:green}
#qick_reg .pwd_img{float:left;height:24px;line-height:24px;text-align:left;width: 100%;padding: 0 0 0 20px;}
#reg_tip{background-color:#FCF8E3;color:#C09853;border-color:#FBEED5;border:1px solid;padding:5px 7px}
#qick_reg form{margin-top:20px}
#reg_loder{background:url(http://i15.servimg.com/u/f15/16/58/89/73/ajax-l11.gif) no-repeat scroll center 130px rgba(255, 255, 255, 0.65);color:#086CC5;display:none;font-family:Comic Sans MS;font-weight:700;height:100%;left:0;line-height:350px;position:absolute;text-align:center;top:0;width:100%}
.modal_close{background:url(http://i40.servimg.com/u/f40/17/70/81/78/close-10.png) repeat scroll 0 0 transparent;content:"";height:11px;position:absolute;right:17px;top:17px;width:11px}
.error input{border:1px solid #F5A7A7;background-color:#F2DEDE}
#qick_reg .button2{background:#055fff;border:1px solid #DDD;color:#FFF;padding:7px 15px}
#qick_reg .button2:hover{background:#666;cursor:pointer}
#qick_reg .button2[name="reset"]{background:url(http://i15.servimg.com/u/f15/16/58/89/73/reload10.png) no-repeat center scroll green;text-indent:-9999px}



Ghi chú

Áp dụng cho phiên bản PunBB.
Cập nhật ngày 19/04/2015


Nguồn

Zzbaivong (devs.forumvi.com)
Tags: [You must be registered and logged in to see this link.]

 27.02.14 21:58

Hướng dẫn này sẽ giúp bạn tạo icon riêng cho từng chuyên mục trong PunBB.

Bạn vào cài đặt từng chuyên mục, thêm URL Icon cho phù hợp.

Topics tagged under tutorial on DEVs forumvi PSEqyl4


Trong cài đặt icon trạng thái chuyên mục, ẩn phần icon thường, thêm ảnh icon chuyên mục có bài mới và chuyên mục bị khóa. Lưu ý, icon này phải nhỏ hơn icon chuyên mục (khoảng 32 x 32px). Ví dụ:

Có bài mới:
Code:
http://i56.servimg.com/u/f56/18/59/49/93/new-ic10.png

Đã khóa:
Code:
http://i83.servimg.com/u/f83/16/58/89/73/lock10.png


Topics tagged under tutorial on DEVs forumvi UHoD5Ry


Thêm vào CSS:
Code:
.indexbox .forum_desc img[style="float:left"][alt^="http://"]{-webkit-transition:all .2s;height:45px;margin-left:-60px;margin-top:-20px;position:absolute;transition:all .2s;width:45px}
.indexbox .statused tr:hover .forum_desc img[style="float:left"][alt^="http://"]{-ms-transform:rotate(360deg);-webkit-transform:rotate(360deg);transform:rotate(360deg)}


Template Index_box:
Tìm:
Code:
<br />
{catrow.forumrow.FORUM_DESC}

Thay bằng:
Code:
<div class="forum_desc">{catrow.forumrow.FORUM_DESC}</div>


Tìm:
Code:
class="main-content"

sửa thành:
Code:
class="main-content indexbox"


Topics tagged under tutorial on DEVs forumvi MvxjLD1

Tags: #mod #tutorial #punbb #forum-icon

[TUTs] zzRedirects - Chuyển hướng liên kết ngoài

Diễn đàn: TUTsTrả lời: 52Lượt xem: 12646

 24.01.14 6:17

Chức năng này sẽ tạo ra thông báo nhắc nhở người dùng, khi họ click vào liên kết lạ.
Đối với một Admin, đa phần đều muốn 4rum có lượng truy cập đông, thời gian ở lại lâu, tất nhiên sẽ chẳng ai muốn người xem rời đi chỉ vì click nhầm vào liên kết nào đấy. Một thông báo, nhắc nhở khi người xem click vào liên kết lạ, sẽ có ích trong trường hợp này. Trong lúc người xem đang suy tư với thì một số Admin còn gắn thêm quảng cáo, hoặc kèm vài lời đe dọa như: Chúng tôi không chịu trách nhiệm khi bạn chuyển đến liên kết này, bala bala...


Demo


https://www.google.com.vn/

Topics tagged under tutorial on DEVs forumvi 4p9Tok2
Ảnh minh họa


Chức năng


  • Khi người xem click vào liên kết ngoài (trừ liên kết ảnh), sẽ xuất hiện một thông báo chuyển hướng với 2 lựa chọn: Trở về hoặc tiếp tục.
  • Tự chuyển trang sau 5 giây nếu người dùng không lựa chọn.
  • Thông báo lỗi nếu sai thông số chuyển hướng



Hướng dẫn


Bước 1


Tạo trang HTML:
ACP >> Modules >> HTML & JAVASCRIPT >> HTML pages management >> Create in advanced mode (HTML)

Do you wish to use your forum header and footer ?: Có
Page content *
Code:
<script type="text/javascript">
//<![CDATA[
/* zzRedirects v3.1.1 - devs.forumvi.com */
(function($) {

    'use strict';

    $('head').append($('<style>', {
        text: '#redirects{background:#FFF;width:75%;margin:30px auto;padding:20px 30px;border:1px solid #DDD}#redirects h3{border-bottom:1px solid #ddd;font-size:17px;font-weight:400;padding-bottom:10px;color:#830000;margin:0 0 20px}#redirects p{color:#222;font-size:13px;line-height:20px;margin:5px auto 15px}.redirectFooter{background-color:#fff;padding:20px 0 30px}#redirectButtons{float:right;list-style-type:none;margin:0;padding:0}#redirectButtons li{float:left}#redirectButtons a{transition:all .2s linear 0;-moz-transition:all .2s linear 0;-o-transition:all .2s linear 0;-webkit-transition:all .2s linear 0;background-color:#0063dc;border:0 none;color:#fff!important;font-size:12px;line-height:30px;min-width:45px;text-align:center;display:block;text-decoration:none!important;padding:0 10px}#redirectButtons a.cancel{background-color:#eee;color:#888!important;margin-right:10px}#redirectButtons a:hover{background-color:#333}'
    }));

    $('#content-container').html('<div id="redirects"><h3><span id="reTitle">Lỗi</span> chuyển hướng...</h3><p id="redirectMess"><span style="color:red">Không tìm thấy tham số cần thiết.</span><br />Đây là trang xác nhận chuyển hướng đến các liên kết ngoài diễn đàn. Nếu bạn vô tình vào trang này, hãy nhấn <a href="/" rel="nofollow" style="font-weight: bold;">vào đây</a> để quay lại. Nếu không, hãy <a href="/contact" rel="nofollow" style="font-weight: bold;">liên hệ</a> với BQT để báo lỗi này.</p><div class="redirectFooter"><ul id="redirectButtons"><li><a id="fromLink" class="cancel" href="/">Quay lại</a></li></ul></div></div>');

    var external = GetParam('url');
    if (null === external || !window.atob) return;

    var goback = document.referrer,
        page = window.name,
        timer, second = 5;

    $('#reTitle').text('Đang');
    $('#redirectMess').html('Bạn đang chuẩn bị rời khỏi <span id="fromTitle">diễn đàn</span> và di chuyển đến đường dẫn: <b><a id="toLink" href="#error" title="No link" rel="nofollow">...</a></b> trong vòng <b><span class="delayTime">5</span></b> giây nữa...<br />Bạn có chắc chắn là muốn đến đường dẫn này không?');

    if (page !== '') $('#fromTitle').html('<strong>' + page + '</strong>');
    if (goback !== '') $('#fromLink').attr('href', goback);

    window.name = '';
    external = window.atob(external);
    page = external;

    if (35 <= page.length) page = page.slice(0, 32) + '...';
    $('#toLink').attr({
        href: external,
        title: external
    }).text(page);

    $('#redirectButtons').append('<li><a href="' + external + '" id="gotoBtn" class="redirectSkip forward" rel="nofollow">Tiếp tục (<span class="delayTime">5</span>)</a></li>');
    timer = setInterval(function() {
        var count = second--;
        0 > count ? (clearInterval(timer), window.location = external) : $('.delayTime').text(count);
    }, 1E3);
    $('a', '#redirectButtons').click(function() {
        clearInterval(timer);
    });

})(jQuery);
//]]>
</script>

Chú ý: Ghi nhớ PAGE ID của trang HTML vừa tạo.
Nếu diễn đàn của bạn không sử dụng sidebar (forum widget) thì ở trong code trên, dòng 12, tìm: #content-container sửa thành:

  • punBB: #main-content
  • Invision: #content
  • PhpBB2, PhpBB3: #emptyidcc


Bước 2


Tạo file Javascript:
ACP >> Modules >> HTML & JAVASCRIPT >> Javascript codes management >> Create a new javascript

Title * : zzRedirect
Placement : In all the pages
Javascript Code * :
Code:
/* zzRedirects v3.1.1 - devs.forumvi.com */
jQuery(function($) {
    'use strict';
    if (window.btoa && window.atob) $('.post-entry a').not('a[href$=".jpg"],a[href$=".jpeg"],a[href$=".png"],a[href$=".gif"],a[href$=".bmp"],a[href^="/"],a[href^="#"],a[href^="?"],a[href^="http://' + location.host + '"]').addClass('external').click(function(e) {
        e.preventDefault();
        window.open('/h{PAGE_ID}-redirect?url=' + window.btoa(this.href), document.title);
    });
});

Chú ý: Thay {PAGE_ID} trong code trên bằng số thứ tự trang HTML tạo ở bước 2.
Nếu diễn đàn của bạn sử dụng phiên bản PhpBB2 hoặc PhpBB3, thì ở trong code trên, dòng 4, tìm: .post-entry a sửa thành: .postbody a


Credit


Zzbaivong (devs.forumvi.com)
Tags: #mod #tutorial #phpbb2 #phpbb3 #punbb #invision #redirect

[Userscript] Giới thiệu User script và cách sử dụng

Diễn đàn: UserscriptTrả lời: 8Lượt xem: 8940

 27.11.13 2:15

Userscript là gì?


Userscript (hoặc User script) là các script dùng trong trình duyệt, hướng tới việc đọc thông tin của trang web hoặc thay đổi chúng.

Topics tagged under tutorial on DEVs forumvi Unlock10
Anti Social Locker

Về cơ bản, Userscript là JavaScript, được bổ sung một số API mạnh mẽ mà thông thường không được phép.
Userscript thường không được phép cài trực tiếp vào trình duyệt, mà phải chạy thông qua một tiện ích (extension) quản lý, nếu không trình duyệt sẽ xem nó như một tệp JavaScript thông thường. Các trình duyệt nhân Chromium cho phép nó chạy như một tiện ích, tuy nhiên có nhiều hạn chế.
Tùy thuộc vào tiện ích quản lý mà Userscript có đuôi mở rộng khác nhau như .tamper.js, .grease.js, .ieuser.js, ... Tuy nhiên, phổ biến nhất vẫn là .user.js, hầu hết các tiện ích quản lý đều hỗ trợ đuôi này.
Từ Userscript, bạn có thể nâng cấp nó thành tiện ích trình duyệt với các API dành cho Content script.

Topics tagged under tutorial on DEVs forumvi Youtub10
Download YouTube Videos as MP4

Mặc dù những gì Userscript làm được thì các Extension cũng làm được và còn hơn nữa, nhưng Userscript vẫn tồn tại. Đó là vì, muốn tạo ra Extension cho trình duyệt thì còn phải theo sự kiểm soát của chủ quản trình duyệt đó, còn Userscript là anh chàng Libero linh hoạt hơn nhiều. Như trong ảnh minh họa trên, Extension download video từ Youtube bị cấm trên Google Chrome, nhưng với Userscript bạn vẫn sẽ có được chức năng đó.

Cách sử dụng


Cài tiện ích quản lý


Tùy vào trình duyệt bạn sử dụng mà tải tiện ích quản lý Userscript phù hợp.

  • Firefox: Greasemonkey hoặc Tampermonkey
  • Chrome: Tampermonkey hoặc Violentmonkey
  • Opera: Tampermonkey hoặc Violentmonkey
  • Safari: Tampermonkey
  • Microsoft Edge: Tampermonkey
  • Maxthon: Violentmonkey
  • Dolphin: Tampermonkey
  • UC: Tampermonkey
  • Qupzilla: Greasemonkey (Có sẵn, bật trong Edit > Preferences > Extensions)

Với các trình duyệt mà mình gợi ý hai tiện ích nổi bật, bạn nên dùng tiện ích đầu. Có thể còn tiện ích khác nhưng chậm cập nhật hoặc không hoạt động nên mình không đưa vào.
Bạn có thể thấy được sự phổ biến của tiện ích Tampermonkey, tuy nhiên nếu bạn có ý định viết Userscript một lần rồi chạy ở tất cả trình duyệt sẽ rất nhanh thất vọng. Vì tùy vào trình duyệt và phiên bản, mức độ hỗ trợ API của tiện ích này cũng không giống nhau.

Cài Userscript


Sau khi cài tiện ích quản lý, bạn có thể vào trang chia sẻ như OpenUserjs, GreasyFork để tìm một Userscript phù hợp và nhấn Cài đặt (Install).
Đây là hai cộng đồng sử dụng và phát triển Userscript lớn nhất hiện nay. OpenUserJs có giao diện đẹp và quản lý dễ dãi hơn, còn GreasyFork có cộng đồng đông đảo và chức năng quản lý tốt hơn.

Ngoài ra, bạn cũng có thể cài đặt Userscript từ nguồn không chính thống khác như Github Gist.
Hoặc dùng chức năng tạo Userscript mới (New Userscript...) trên tiện ích quản lý, và sử dụng mã nguồn được chia sẻ.

Cảnh báo


Trang Userscripts mirror là một bản sao của Userscripts.org, đã bị đóng cửa bởi chủ quản, với lý do chứa nhiều mã độc, không thể kiểm soát.
Các Userscript trong này đã không còn được cập nhật. Nếu bạn là nhà phát triển, có thể ghé qua lấy ý tưởng, tham khảo. Còn nếu bạn là người dùng thông thường, thì không nên sử dụng trang này.

Userscript có thể chèn mã độc, đánh cắp thông tin, gây tổn hại đến người dùng. Vì thế, không nên sử dụng từ nguồn không đáng tin cậy, tránh dùng các Userscript bị nén, bị mã hóa.

Cách viết Userscript


Userscript luôn chứa một Metadata Block, được đặt ở phần đầu mã nguồn. Đây là nơi khai báo các thông tin như tên, phiên bản, giới hạn sử dụng...

Định dạng chuẩn của một Metadata Block.
Code:
// ==UserScript==
// @key1  value1
// @key2  value2
// @keyN  valueN
// ==/UserScript==


Việc hỗ trợ khóa (key) Metadata cũng khác nhau tùy tiện ích quản lý, nên mình chỉ giới thiệu các khóa phổ biến, dựa trên Greasemonkey, và một số khóa quan trọng trong các tiện ích quản lý thông dụng.

Các khóa Metadata


@name


Tên của Userscript, bạn nên sử dụng tiếng Anh hoặc viết không dấu, và không ký tự đặc biệt, vì nó cũng được dùng làm tên tệp. Ví dụ:
Code:
// @name  anti social locker


@namespace


Tên bổ sung, nó được kết hợp với @name để tạo thành cặp khóa định danh cho Userscript đó, nếu bạn tạo ra một Userscript mới mà cặp khóa này trùng nhau, tiện ích quản lý sẽ xem nó như một bản cập nhật và thay thế nó. Vì @namespace không có nghĩa nên tác giả thường dùng để đăng URL website, một số tiện ích quản lý cũng dùng khóa này để xác định Trang chủ của Userscript. Ví dụ:
Code:
// @namespace  http://baivong.github.io/


@description


Giới thiệu thông tin sơ lược. Ví dụ:
Code:
// @description  Anti social locker plugin required user like or share before viewing content. If script doesn't work, please refresh the page to rebuild the cache and try again.


@version


Phiên bản hiện tại. Giá trị này được tiện ích quản lý sử dụng để cập nhật Userscript. Xem thêm quy chuẩn Semantic Versioning để hiểu cách viết phiên bản. Ví dụ:
Code:
// @version  1.0.0


@icon


URL icon, ảnh đại diện cho Userscript. Ví dụ:
Code:
// @icon  http://i.imgur.com/nOuUrIW.png


@author


Tên tác giả. Ví dụ:
Code:
// @author  Zzbaivong


@license


Tên hoặc URL đến giấy phép sử dụng Userscript. Truy cập Choose a License để biết thêm thông tin và cách lựa chọn. Ví dụ:
Code:
// @license  MIT


@include


Giới hạn địa chỉ trang web mà Userscript sẽ chạy, có thể dùng biểu thức chính quy (Regular Expressions). Khóa này có thể dùng nhiều lần. Ví dụ:
Code:
// @include  /^https?://*/*.js$/
// @include  /^https?://*/*.css$/


@match


Chức năng tương tự @include nhưng được đặt quy tắc nghiêm ngặt hơn trong cách sử dụng dấu *, không được dùng biểu thức chính quy. Xem chi tiết về Match Patterns. Ví dụ:
Code:
// @match  http://*/*.js
// @match  https://*/*.js
// @match  http://*/*.css
// @match  https://*/*.css


@exclude


Cách dùng tương tự @include nhưng có vai trò ngược lại, nó loại trừ địa chỉ trang web mà Userscript sẽ chạy. Ví dụ:
Code:
// @exclude  /^https?://*/*.json$/
// @exclude  /^https?://*/*.less$/


@downloadURL


URL để cập nhật Userscript. Nếu không dùng khóa này, tiện ích quản lý sẽ dùng URL lúc bạn tải về để làm URL cập nhật. Ví dụ:
Code:
// @downloadURL  https://openuserjs.org/install/baivong/anti_social_locker.user.js


@updateURL


URL để kiểm tra thông tin phiên bản, có đuôi .meta.js, thông thường chỉ chứa Metadata Block (tối thiểu phải có 3 khóa @version, @name,
Code:
@namespace

). Nếu thông tin @version trong này mới hơn thì tiện ích quản lý sẽ tiến hành cập nhật Userscript. Nếu không dùng khóa này, tiện ích quản lý sẽ dùng URL lúc bạn tải về, hoặc khóa @downloadURL để làm kiểm tra thông tin phiên bản. Ví dụ:
Code:
// @updateURL  https://openuserjs.org/install/baivong/anti_social_locker.meta.js


@supportURL


URL dẫn đến trang hỗ trợ, báo lỗi. Ví dụ:
Code:
// @supportURL  https://github.com/baivong/Userscript/issues


@require


URL của thư viện JavaScript cần sử dụng. Khóa này có thể dùng nhiều lần. Ví dụ:
Code:
// @require  https://code.jquery.com/jquery-2.2.4.min.js
// @require  https://greasyfork.org/scripts/19855-jszip/code/jszip.js
// @require  https://greasyfork.org/scripts/18532-filesaver/code/FileSaver.js


@resource


Bổ sung thêm tài nguyên để sử dụng, chúng sẽ được tải về máy người dùng nên sẽ nhanh và ổn định hơn dùng URL trực tuyến. Bạn có thể truy cập thông qua API GM_getResourceText hoặc GM_getResourceURL. Khóa này có thể dùng nhiều lần. Ví dụ:
Code:
// @resource  devsLogo https://baivong.github.io/css/images/logo-header.png
// @resource  lightTheme https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.11.0/styles/github-gist.min.css
// @resource  darkTheme https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.11.0/styles/monokai-sublime.min.css


@run-at


Thời điểm chạy Userscript so với trang web. Bao gồm 3 giá trị document-start, document-end document-idle. Ví dụ:
Code:
// @run-at document-idle


@noframes


Ngăn không cho Userscript chạy trong thẻ nhúng như iframe. Nó không có đối số, chỉ là dùng hoặc không dùng. Nên sử dụng khóa này để tránh lỗi hiệu suất, nhất là với các trang có quảng cáo nhúng. Ví dụ:
Code:
// @noframes


@grant


Yêu cầu cấp quyền sử dụng API đặc biệt với tiện ích quản lý, không có nó, tiện ích quản lý có thể đưa ra thông tin sai, gây lỗi. Các quyền này có thể khiến Userscript của bạn bị cách ly (sandbox) với các script trong trang. Nếu bạn không yêu cầu quyền API đặc biệt hãy đặt giá trị none. Khóa này có thể dùng nhiều lần. Ví dụ:
Code:
// @grant GM_addStyle
// @grant GM_getResourceText


@connect


Đây là khóa bổ sung khi yêu cầu API GM_xmlhttpRequest, nó xác định tên miền chứa dữ liệu cần lấy. Bao gồm các giá trị: domain (cũng sẽ bao gồm toàn bộ sub-domain), sub-domain, IP address, localhost, self (trang mà Userscript đang chạy), * (tất cả). Khóa này có thể dùng nhiều lần. Ví dụ:
Code:
// @connect baivong.github.io
// @connect self


Chú ý


Một Metadata Block tối thiểu phải có 3 khóa @name, @namespace, @grant (có tiện ích quản lý yêu cầu thêm @match, @id).
Tài nguyên từ @require@resource chỉ được tải về một lần vào máy người dùng, đến khi có bản cập nhật thì nó mới tải lại.

Sau khi tạo Metadata Block, bạn đã có thể bắt đầu viết code cho nó bằng JavaScript ở bên dưới, sử dụng thêm API nếu cần thiết. Tuy nhiên, mức độ hỗ trợ API của mỗi tiện ích quản lý đều có vài điểm khác biệt, trong bài này mình chỉ hướng dẫn cách tạo Userscript cơ bản với Javascript. Nếu bạn muốn viết nâng cao hơn thì nên tìm xem các tài liệu API của tiện ích quản lý mà bạn sử dụng. Ví dụ:
Code:
// ==UserScript==
// @name reverse
// @namespace Zzbaivong
// @grant none
// ==/UserScript==

document.body.style.transform = "rotate(180deg)";


Bạn có thể cài trực tiếp Userscript vào trình duyệt nhân Chromium, tuy nhiên nó chỉ cho phép các khóa @name, @namespace, @description, @version, @match, @include, @exclude và một số API (không bắt buộc dùng @grant) GM_log, GM_openInTab, GM_addStyle, GM_xmlhttpRequest (chỉ trong cùng nguồn, tương đương @connect self). Ví dụ:
Code:
// ==UserScript==
// @match http://github.com/*
// ==/UserScript==

GM_openInTab("https://github.com/baivong/Userscript");

Tags: #userscript #extension #tutorial #browser

[TUTs] Việt hóa URL

Diễn đàn: TUTsTrả lời: 28Lượt xem: 8796

 20.11.13 21:09

Mặc dù Forumtion đã câp nhật URL theo tiêu đề từ rất lâu, tuy nhiên đến nay vẫn không hỗ trợ Tiếng Việt.
Cách thường dùng nhất hiện nay là cài đặt ngôn ngữ hệ thống về Tiếng Anh, cách này không tiện với những diễn đàn mà thành viên ít dùng Tiếng Anh, hơn nữa URL cũng không hiển thị tốt với Tiếng Việt có dấu (lỗi mất chữ đ).
Bài viết này, mình sẽ hướng dẫn cách tạo URL theo tiêu đề mà không phụ thuộc vào ngôn ngữ diễn đàn.

Demo

Topics tagged under tutorial on DEVs forumvi Url10
URL theo tiêu đề ở diễn đàn Tiếng Việt


Phần 1

Sửa URL trên thanh địa chỉ trình duyệt

ACP >> Display >> Templates >> QLTT >> overall_header
Tìm:
Code:
<title>{SITENAME_TITLE}{PAGE_TITLE}</title>

Thêm vào bên dưới:
Code:
<script type="text/javascript">
//<![CDATA[
function lang_vi(a) {
    a = a.toLowerCase();
    a = a.replace(/\u00e0|\u00e1|\u1ea1|\u1ea3|\u00e3|\u00e2|\u1ea7|\u1ea5|\u1ead|\u1ea9|\u1eab|\u0103|\u1eb1|\u1eaf|\u1eb7|\u1eb3|\u1eb5/g, "a");
    a = a.replace(/\u00e8|\u00e9|\u1eb9|\u1ebb|\u1ebd|\u00ea|\u1ec1|\u1ebf|\u1ec7|\u1ec3|\u1ec5/g, "e");
    a = a.replace(/\u00ec|\u00ed|\u1ecb|\u1ec9|\u0129/g, "i");
    a = a.replace(/\u00f2|\u00f3|\u1ecd|\u1ecf|\u00f5|\u00f4|\u1ed3|\u1ed1|\u1ed9|\u1ed5|\u1ed7|\u01a1|\u1edd|\u1edb|\u1ee3|\u1edf|\u1ee1/g, "o");
    a = a.replace(/\u00f9|\u00fa|\u1ee5|\u1ee7|\u0169|\u01b0|\u1eeb|\u1ee9|\u1ef1|\u1eed|\u1eef/g,
        "u");
    a = a.replace(/\u1ef3|\u00fd|\u1ef5|\u1ef7|\u1ef9/g, "y");
    a = a.replace(/\u0111/g, "d");
    a = a.replace(/\W+/g, "-");
    a = a.replace(/^\-+|\-+$/g, "");
    a = a.replace(/(-group)$/, "");
    return a.replace(/(-page-\d+)$/, "")
}
var path = location.pathname,
    canonical = path + location.search + location.hash;
/(\-category|\-forum|\-topic|\-group)/.test(path) && history.replaceState(null, null, canonical.slice(1).replace(/(\-category|\-forum|\-topic|\-group)/, "-" + lang_vi(document.title)));
//]]>
</script>



Phần 2

Sửa URL liên kết (tùy chọn)

Tạo file javascript, đặt In all the pages.

Code:
$(function() {
    $("a[href^='/c'], a[href^='/f'], a[href^='/t']").attr({
        href: function() {
            var a = $.trim($(this).text());
            if ("" != a) return this.href.replace(location.origin, "").replace(/(\-category|\-forum|\-topic)/, "-" + lang_vi(a.replace(/Re:\s/i, "")))
        }
    });
});



Ngoài lề

ligerv từng bàn về Việt hóa URL có tốt cho SEO không, vì ở đây là dùng javascript, mình cũng không chắc về vụ SEO nhưng xem trên Google analytics thì nó hiển thị URL Tiếng Việt, có vẻ là chỉ cần chạy trước mã theo dõi của Google là được.


Nguồn

Zzbaivong (devs.forumvi.com)
Tags: #mod #tutorial #việt-hóa #permarklink


Back to top