Merge pull request #514 from bjrambo/pr/ncenterlite-widget

로그인 위젯을 통해서 알림센터 위젯을 생성합니다.
This commit is contained in:
BJRambo 2016-05-30 10:37:35 +09:00
commit 0ff86b4027
16 changed files with 714 additions and 18 deletions

View file

@ -30,6 +30,15 @@
<title xml:lang="ko">사용 안 함</title>
</options>
</var>
<var name="use_ncenter_widget" type="select">
<title xml:lang="ko">알림센터 로그인 위젯 사용</title>
<options value="Y">
<title xml:lang="ko">사용함</title>
</options>
<options value="N">
<title xml:lang="ko">사용 안 함</title>
</options>
</var>
<var name="layout_type" type="select" default="auto">
<title xml:lang="ko">레이아웃 타입</title>
<options value="auto">

View file

@ -440,6 +440,11 @@
<a href="#" class="btn_top"><i class="xi-angle-up"><span class="blind">{$lang->cmd_move_up}</span></i></a>
<!-- /TOP -->
<!-- Ncenter login widget -->
<!--@if($layout_info->use_ncenter_widget == 'Y')-->
<img class="zbxe_widget_output" widget="login_info" skin="ncenter_login" colorset="layout" widget_cache="0m" ncenter_use="yes" />
<!--@end-->
<!-- Login widget -->
<section cond="$layout_info->use_login_widget != 'N'" class="login_widget" style="display:none"|cond="$XE_VALIDATOR_ID != 'layouts/xedition/layout/1' || !$XE_VALIDATOR_MESSAGE">
<load target="./css/widget.login.css" />

View file

@ -64,8 +64,10 @@ $lang->ncenterlite_io_about = 'You can activate or inactivate every function of
$lang->ncenterlite_on = 'Active';
$lang->ncenterlite_off = 'Inactive';
$lang->ncenterlite_display = 'Display Notifications';
$lang->ncenterlite_display_y = 'Yes';
$lang->ncenterlite_display_n = 'No';
$lang->ncenterlite_display_all = 'All display';
$lang->ncenterlite_display_pc = 'Only PC';
$lang->ncenterlite_display_mobile = 'Only Mobile';
$lang->ncenterlite_display_none = 'Not display.';
$lang->ncenterlite_display_about = 'You can hide notifications from Notification Center Lite if you are using a layout or widget that handles notifications for you.';
$lang->ncenterlite_mention_target = 'Mention target';
$lang->ncenterlite_mention_target_about = 'Mention target can be nicknames or IDs (@Nickname or @ID).';

View file

@ -74,8 +74,10 @@ $lang->ncenterlite_on = '동작';
$lang->ncenterlite_only_message = '쪽지만';
$lang->ncenterlite_off = '동작 안 함';
$lang->ncenterlite_display = '알림 표시 여부';
$lang->ncenterlite_display_y = '표시';
$lang->ncenterlite_display_n = '표시하지 않음';
$lang->ncenterlite_display_all = '모두 사용';
$lang->ncenterlite_display_pc = 'PC만 표시';
$lang->ncenterlite_display_mobile = '모바일만 표시';
$lang->ncenterlite_display_none = '표시하지 않음';
$lang->ncenterlite_display_about = '사용하는 레이아웃이나 위젯에 알림을 표시하는 기능이 있는 경우 중복을 막기 위해 알림센터의 알림을 숨길 수 있습니다.';
$lang->ncenterlite_mention_target = '멘션 타겟';
$lang->ncenterlite_mention_target_about = '멘션 알림을 @아이디 소유자에게 보낼지 @닉네임 소유자에게 보낼지 선택할 수 있습니다.';

View file

@ -705,7 +705,7 @@ class ncenterliteController extends ncenterlite
return new Object();
}
if($config->display_use == 'N')
if($config->display_use == 'mobile' && !Mobile::isFromMobilePhone() || $config->display_use == 'pc' && Mobile::isFromMobilePhone() || $config->display_use == 'none')
{
return new Object();
}

View file

@ -20,7 +20,7 @@ class ncenterliteModel extends ncenterlite
{
$config->use = array('message' => 1);
}
if(!$config->display_use) $config->display_use = 'Y';
if(!$config->display_use) $config->display_use = 'all';
if(!$config->mention_names) $config->mention_names = 'nick_name';
if(!$config->mention_suffixes)

View file

@ -21,14 +21,14 @@
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->ncenterlite_display}</label>
<label class="x_control-label" for="display_use">{$lang->ncenterlite_display}</label>
<div class="x_controls">
<label class="x_inline">
<input type="radio" id="display_use_y" name="display_use" value="Y" checked="checked"|cond="$config->display_use == 'Y'" /> {$lang->ncenterlite_display_y}
</label>
<label class="x_inline">
<input type="radio" id="display_use_n" name="display_use" value="N" checked="checked"|cond="$config->display_use == 'N'" /> {$lang->ncenterlite_display_n}
</label>
<select name="display_use" id="display_use">
<option value="all" selected="selected"|cond="$config->display_use == 'all'">{$lang->ncenterlite_display_all}</option>
<option value="none" selected="selected"|cond="$config->display_use == 'none'">{$lang->ncenterlite_display_none}</option>
<option value="pc" selected="selected"|cond="$config->display_use == 'pc'">{$lang->ncenterlite_display_pc}</option>
<option value="mobile" selected="selected"|cond="$config->display_use == 'mobile'">{$lang->ncenterlite_display_mobile}</option>
</select>
<p class="x_help-block">{$lang->ncenterlite_display_about}</p>
</div>
</div>

View file

@ -31,4 +31,20 @@
<name xml:lang="zh-TW">NAVER</name>
<name xml:lang="tr">NAVER</name>
</author>
<extra_vars>
<var id="ncenter_use" type="select">
<name xml:lang="ko">알림센터 사용</name>
<name xml:lang="en">Use the ncenterlite</name>
<options>
<value>yes</value>
<name xml:lang="ko">사용함</name>
<name xml:lang="en">Enabled</name>
</options>
<options>
<value>no</value>
<name xml:lang="ko">사용 안 함</name>
<name xml:lang="en">Disabled</name>
</options>
</var>
</extra_vars>
</widget>

View file

@ -1,5 +1,6 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* @class login_info
* @author NAVER (developers@xpressengine.com)
@ -20,12 +21,50 @@ class login_info extends WidgetHandler
// Set a path of the template skin (values of skin, colorset settings)
$tpl_path = sprintf('%sskins/%s', $this->widget_path, $args->skin);
Context::set('colorset', $args->colorset);
// Specify a template file
if(Context::get('is_logged')) $tpl_file = 'login_info';
else $tpl_file = 'login_form';
$is_logged = Context::get('is_logged');
$oMemberModel = getModel('member');
$memberConfig = $oMemberModel->getMemberConfig();
$oNcenterliteModel = getModel('ncenterlite');
$ncenter_config = $oNcenterliteModel->getConfig();
if($is_logged)
{
if(!empty($ncenter_config->use) && $args->ncenter_use == 'yes')
{
$logged_info = Context::get('logged_info');
$ncenter_list = $oNcenterliteModel->getMyNotifyList($logged_info->member_srl);
$_latest_notify_id = array_slice($ncenter_list->data, 0, 1);
$_latest_notify_id = $_latest_notify_id[0]->notify;
if($memberConfig->profile_image == 'Y')
{
$profileImage = $oMemberModel->getProfileImage($logged_info->member_srl);
Context::set('profileImage', $profileImage);
}
Context::set('ncenterlite_latest_notify_id', $_latest_notify_id);
if($_COOKIE['_ncenterlite_hide_id'] && $_COOKIE['_ncenterlite_hide_id'] == $_latest_notify_id)
{
return;
}
setcookie('_ncenterlite_hide_id', '', 0, '/');
}
$tpl_file = 'login_info';
}
else
{
$tpl_file = 'login_form';
}
// Get the member configuration
$oModuleModel = getModel('module');
$this->member_config = $oModuleModel->getModuleConfig('member');
if($ncenter_config->zindex)
{
Context::set('ncenterlite_zindex', ' style="z-index:' . $ncenter_config->zindex . ';" ');
}
Context::set('useProfileImage', ($memberConfig->profile_image == 'Y') ? true : false);
Context::set('ncenterlite_list', $ncenter_list->data);
Context::set('ncenterlite_page_navigation', $ncenter_list->page_navigation);
Context::set('_ncenterlite_num', $ncenter_list->page_navigation->total_count);
Context::set('member_config', $this->member_config);
// Set a flag to check if the https connection is made when using SSL and create https url
@ -33,9 +72,12 @@ class login_info extends WidgetHandler
$useSsl = Context::getSslStatus();
if($useSsl != 'none')
{
if(strncasecmp('https://', Context::getRequestUri(), 8) === 0) $ssl_mode = true;
if(strncasecmp('https://', Context::getRequestUri(), 8) === 0)
{
$ssl_mode = true;
}
}
Context::set('ssl_mode',$ssl_mode);
Context::set('ssl_mode', $ssl_mode);
// Compile a template
$oTemplate = &TemplateHandler::getInstance();

View file

@ -0,0 +1,377 @@
#nc_container {
z-index:99;
position:fixed;
bottom:0;
right:0;
margin:0;
padding:0;
width:330px;
height:58px;
border-bottom:1px solid;
font-size:12px;
line-height:20px;
}
#nc_container.nc_login {
height:28px;
}
#nc_container a {
padding:0;
font-size:12px;
text-decoration:none;
}
#nc_container ul.me_menu {
display:block;
margin:0;
list-style:none;
line-height:28px;
}
#nc_container ul.nc_memu {
display:block;
margin:0;
padding:4px;
list-style:none;
line-height:20px;
}
#nc_container ul.nc_memu {
border-bottom:1px solid #0c0c0c;
}
#nc_container ul.nc_memu.guest {
border-bottom: 0;
}
#nc_container ul.me_menu {
border-top:1px solid #505050;
}
#nc_container ul.me_menu img {
vertical-align:middle;
margin-left:5px;
}
#nc_container ul.me_menu li {
float:left;
height:28px;
padding:0 5px;
border-right:1px solid #0c0c0c;
border-left:1px solid #505050;
}
#nc_container ul.me_menu li:first-child{
border-left:0;
}
#nc_container ul.me_menu li:last-child{
border-right:0;
}
#nc_container ul:after {
content:"";
display:block;
clear:both;
}
#nc_container ul.me_menu li {
display:inline-block;
height:28px;
width:auto;
background:transparent!important;
}
#nc_container ul.nc_memu li{
display:inline-block;
padding:0 5px;
height:20px;
width:auto;
background:transparent!important;
}
#nc_container ul li.fLeft {
float:left;
}
#nc_container ul li.fRight {
float:right;
}
#nc_container ul li a.notify {
display:block;
float:left;
}
#nc_container a.close {
display:block;
}
#nc_container .nc_profile img {
width:20px;
height:20px;
vertical-align:top;
}
#nc_container a.notify .num {
padding:1px 2px;
border:0;
border-radius:3px;
-webkit-border-radius:3px;
-moz-border-radius:3px;
font-size:12px;
font-weight:700;
font-family:Gulim,"lucida grande",tahoma,verdana,arial,sans-serif;
}
#nc_container .list {
display:none;
position:absolute;
left:0;
bottom:58px;
max-width:330px;
width:330px;
box-sizing:border-box;
-moz-box-sizing:border-box;
-webkit-box-sizing:border-box;
-o-box-sizing:border-box;
}
#nc_container.nc_login .list {
bottom:28px;
}
#nc_container a.readall {
display:none;
float:left;
margin:0 4px;
font-size:11px;
font-weight:700;
}
#nc_container .listscroll {
overflow-y:auto;
overflow-x:hidden;
}
#nc_container .list ul {
overflow:hidden;
margin:-1px 0;
padding:0;
list-style:none;
}
#nc_container .list li {
margin:-1px 0;
border:1px solid #555;
border-width:1px 0;
}
#nc_container .list li img {
float:left;
margin-right:5px;
width:45px;
height:45px;
border:0;
}
#nc_container .list li a {
display:block;
overflow:hidden;
padding:10px;
font-size:12px;
}
#nc_container .list span.ago {
display:block;
font-size:10px;
}
#nc_container .list .more {
display:block;
padding:10px;
text-align:center;
}
#nc_container a:hover,#nc_container .list li a:hover,#nc_container .list .more:hover {
text-decoration:none;
}
@media only screen and (max-device-width:480px) {
#nc_container {
position:relative;
height:auto;
}
#nc_container .list {
top:2px;
position:relative;
}
#nc_container .list ul {
display:block;
position:relative;
}
#nc_container ul.nc_memu:after {
content:"";
display:block;
visibility:hidden;
height:0;
clear:both;
}
#nc_container .listscroll {
overflow:visible;
}
.ncenterlite_block {
display:none;
}
}
#nc_container { border-bottom-color:#555; background-color:#333; color:#B0B0B0; opacity:0.95;}
#nc_container a { color:#B0B0B0; }
#nc_container a:hover { color:#B0B0B0; }
#nc_container strong { color:#F3F3F3; }
#nc_container .list { background-color:#333; filter:alpha(opacity=95); opacity:0.95; -moz-opacity:0.95; }
#nc_container .list li { border-color:#555; }
#nc_container .list li a:hover { background-color:#555; }
#nc_container .list span.ago { color:#D4AF37; }
#nc_container .list .more { background: #555; }
#nc_container a.readall { display:none; color:#555; color:#D83722;}
#nc_container a.notify { color:white; }
#nc_container a.notify .num { background-color:#D83722; color:white; }
#nc_container ul.nc_menu li { padding-right:5px; }
/* zocial */
#account-signup [class*="entypo-"]:before {
font-family: 'entypo', sans-serif;
}
#account-signup h2 {
display:block;
position:relative;
padding:10px;
height:30px;
color:rgba(255,255,255,.8);
margin-left:12px;
font-size: 25px;
}
.nc_login .list {
background: #272125;
font-family: 'Roboto', sans-serif;
}
#account-signup form.account-signup {
position:relative;
margin: 50px auto;
width: 380px;
height: auto;
}
#account-signup input.user,
#account-signup input.pass{
padding: 16px;
border-radius:7px;
border:0px;
background: rgba(255,255,255,.2);
display: block;
margin: 15px;
width: 212px;
color:white;
font-size:18px;
height: 20.5px;
}
#account-signup input.user {
margin-top:0;
}
.nc_login .list li a {
padding:10px 10px 10px 15px !important;
}
.nc_login .list ul {
margin:10px 0px -1px 0 !important;
}
#account-signup input.user:focus,
#account-signup input.pass:focus{
outline-color: rgba(0,0,0,0);
background: rgba(255,255,255,.95);
color: #e74c3c;
}
input[id="keep_signed"] {
display: none;
}
input[id="keep_signed"] + label{
display: inline-block;
cursor: pointer;
position: relative;
padding-left: 25px;
margin-left: 15px;
font-size: 13px;
}
input[id="keep_signed"]+ label:before {
content: "";
display: inline-block;
width: 20px;
height: 20px;
margin-right: 10px;
position: absolute;
left: 0;
bottom: 1px;
background-color: #ccc;
border-radius: 2px;
box-shadow: inset 0px 1px 1px 0px rgba(0, 0, 0, .3), 0px 1px 0px 0px rgba(255, 255, 255, .8);
}
input[id="keep_signed"]:checked + label:before {
content: "\2713";
text-shadow: 1px 1px 1px rgba(0, 0, 0, .2);
font-size: 18px;
font-weight:800;
color: #fff;
background: #c14d18;
text-align: center;
line-height: 18px;
}
#account-signup button.submit {
float:right;
height: 121px;
width: 50px;
border: 0px;
background: #e74c3c;
border-radius:7px;
padding: 10px;
color:white;
font-size:22px;
margin-right:10px;
}
#account-signup .inputUserIcon {
position:absolute;
top:68px;
right: 80px;
color:white;
}
#account-signup .inputPassIcon {
position:absolute;
top:135px;
right: 80px;
color:white;
}
#account-signup input::-webkit-input-placeholder {
color: white;
}
#account-signup input:focus::-webkit-input-placeholder {
color: #e74c3c;
}

View file

@ -0,0 +1,82 @@
//<![CDATA[
(function ($) {
$(function () {
function setCookie(n, v, d) {
var e = "";
if (d) {
var dt = new Date();
dt.setTime(dt.getTime() + (d * 24 * 60 * 60000));
e = "; expires=" + dt.toGMTString();
}
document.cookie = n + "=" + v + e + "; path=/";
}
var n = $('#nc_container');
$('.close', n).click(function () {
setCookie('_ncenterlite_hide_id', '{$ncenterlite_latest_notify_id}', 1);
n.hide().next('div').hide();
return false;
});
$('.readall', n).click(function () {
exec_xml('ncenterlite', 'procNcenterliteNotifyReadAll');
$('.close', n).triggerHandler('click');
return false;
});
$('a.notify', n).click(function () {
$('.list', n).toggle();
$('.readall', n).toggle();
return false;
});
$(document).click(function (e) {
var t = $(e.target);
if (!t.is('#nc_container') && t.parents('#nc_container').length == 0) {
if ($('.list', n).is(':visible')) {
$('.list', n).hide();
$('.readall', n).hide();
return false;
}
}
});
var $listWrap = $('.list ul', n);
var $btnMore = $('.more', n);
$btnMore.click(function () {
var page = $(this).data('page');
var $item_html = $('<li><a><span class="msg"></span><span class="ago"></span></a></li>');
var $profileImg = $('<img class="nc_profile_img" alt="" />');
$.exec_json('ncenterlite.getMyNotifyListTpl', {'page': page}, function (ret) {
if (!ret.list.data) return;
for (var i in ret.list.data) {
if (ret.list.data.hasOwnProperty(i)) {
var item = ret.list.data[i];
var $html = $item_html.clone();
if (ret.useProfileImage == 'Y') {
var $img = $profileImg.clone();
if (!item.profileImage) item.profileImage = request_uri + 'modules/ncenterlite/skins/default/img/p.png';
$img.attr('src', item.profileImage);
$html.find('a').prepend($img);
}
$('span.msg', $html).html(item.text);
$('span.ago', $html).html(item.ago);
$('a', $html).attr('href', item.url);
if (i == 0) $html.attr('id', 'ncenterlite_page_' + ret.list.page.cur_page);
$listWrap.append($html);
}
}
$listWrap.animate({scrollTop: (ret.list.page.cur_page - 1) * 265}, 800);
if (ret['list'].page.total_page <= ret.list.page.cur_page) {
$btnMore.remove();
}
}, ['list']);
$(this).data('page', ++page);
return false;
});
});
})(jQuery);
//]]>

View file

@ -0,0 +1,11 @@
<filter name="widget_login" module="member" act="procMemberLogin">
<form>
<node target="user_id" required="true" filter="user_id" />
<node target="password" required="true" />
</form>
<parameter />
<response callback_func="completeLogin">
<tag name="error" />
<tag name="message" />
</response>
</filter>

View file

@ -0,0 +1,48 @@
<load target="./css/ncenter.css" />
<load target="./js/ncenter.js" type="body" />
<div id="nc_container" class="nc_login" {$ncenterlite_zindex}>
<ul class="nc_memu guest">
<li class="nc_profile fLeft">
<block cond="$useProfileImage">
<img cond="!$profileImage" src="{Context::getRequestUri()}modules/ncenterlite/skins/default/img/p.png" alt="my profile" class="nc_profile_img" />
</block>
<strong>손님</strong>
</li>
<li class="fLeft">
<a class="notify" href="#">
로그인해주세요!
</a>
</li>
</ul>
<div class="list">
<form id="account-signup" action="{getUrl('','act','procMemberLogin')}" method="post" ruleset="@login" class="account">
<fieldset id="acField">
<input type="hidden" name="act" value="procMemberLogin"/>
<input type="hidden" name="success_return_url" value="{htmlspecialchars(getRequestUriByServerEnviroment(), ENT_COMPAT | ENT_HTML401, 'UTF-8', false)}"/>
<input type="hidden" name="xe_validator_id" value="widgets/login_info/skins/default/login_form/1"/>
<div cond="$XE_VALIDATOR_MESSAGE && $XE_VALIDATOR_ID == 'widgets/login_info/skins/default/login_form/1'"
class="message {$XE_VALIDATOR_MESSAGE_TYPE}">
<p>{$XE_VALIDATOR_MESSAGE}</p>
</div>
<h2><i class="xi-user"></i>{$lang->cmd_login}</h2>
<button class="submit"><i class="xi-user-check"></i></button>
<span class="inputUserIcon"><i class="xi-user"></i></span>
<input name="user_id" id="user_id" type="text" class="user" placeholder="{$lang->user_id}" required cond="$member_config->identifier != 'email_address'"/>
<input name="user_id" id="user_id" type="email" class="user" placeholder="{$lang->email_address}" required cond="$member_config->identifier == 'email_address'"/>
<span class="inputPassIcon"><i class="xi-key"></i></span>
<input name="password" id="user_pw" type="password" class="pass" required placeholder="{$lang->password}"/>
<p class="keep">
<input type="checkbox" name="keep_signed" id="keep_signed" value="Y"/>
<label for="keep_signed">{$lang->keep_signed}</label>
</p>
<ul class="help">
<li><a href="{getUrl('act','dispMemberSignUpForm')}">{$lang->cmd_signup}</a></li>
<li><a href="{getUrl('act','dispMemberFindAccount')}">{$lang->cmd_find_member_account}</a></li>
</ul>
</fieldset>
</form>
</div>
</div>

View file

@ -0,0 +1,59 @@
<load target="./css/ncenter.css" />
<load target="./js/ncenter.js" type="body" />
<div id="nc_container" {$ncenterlite_zindex}>
<ul class="nc_memu">
<li class="nc_profile fLeft">
<block cond="$useProfileImage">
<img cond="$profileImage" src="{$profileImage->src}" alt="my profile" class="nc_profile_img" />
<img cond="!$profileImage" src="{Context::getRequestUri()}modules/ncenterlite/skins/default/img/p.png" alt="my profile" class="nc_profile_img" />
</block>
<strong>{$logged_info->nick_name}</strong> {$lang->ncenterlite_sir}!
</li>
<li class="fLeft">
<a class="notify" href="#">
<!--@if($_ncenterlite_num > 1)-->
{sprintf($lang->ncenterlite_messages, $ncenterlite_page_navigation->total_count)}
<!--@else-->
{sprintf($lang->ncenterlite_message, $ncenterlite_page_navigation->total_count)}
<!--@endif-->
</a>
<a cond="$ncenterlite_page_navigation->total_count >= 1" href="#" class="readall">{$lang->ncenterlite_delete_all}</a>
</li>
<li class="fRight"><a class="close" href="#">× Close</a></li>
</ul>
<ul class="me_menu">
<li class="nc_profile fLeft">
<block cond="$useProfileImage">
<img cond="$profileImage" src="{$profileImage->src}" alt="my profile" class="nc_profile_img" />
<img cond="!$profileImage" src="{Context::getRequestUri()}modules/ncenterlite/skins/default/img/p.png" alt="my profile" class="nc_profile_img" />
</block>
<strong>{$logged_info->nick_name}</strong>
</li>
<li>
<a href="{getUrl('act','dispMemberLogout')}" >{$lang->cmd_logout}</a>
</li>
<li>
{$lang->last_login}: {zDate($logged_info->last_login, "Y-m-d")}
</li>
<li cond="$logged_info->is_admin == 'Y'" >
<a href="{getUrl('', 'module','admin')}" title="{$lang->admin}" class="admin">{$lang->cmd_management}</a>
</li>
</ul>
<div class="list">
<ul>
<li loop="$ncenterlite_list => $o">
<a href="{$o->url}">
<block cond="$useProfileImage">
<img src="{$o->profileImage}"|cond="$o->profileImage" src="{Context::getRequestUri()}modules/ncenterlite/skins/default/img/p.png"|cond="!$o->profileImage" alt="" class="nc_profile_img" />
</block>
<span class="msg">{$o->text}</span><span class="ago">{$o->ago}</span>
</a>
</li>
</ul>
<a cond="$ncenterlite_page_navigation->total_count > 5" class="more" href="#" data-page="2">{$lang->ncenterlite_more}</a>
</div>
</div>

View file

@ -0,0 +1,7 @@
<filter name="widget_logout" module="member" act="procMemberLogout">
<form />
<response>
<tag name="error" />
<tag name="message" />
</response>
</filter>

View file

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<skin version="0.2">
<title xml:lang="ko">RX 알림센터 로그인 스킨</title>
<description xml:lang="ko">RX 알림센터겸용 로그인 스킨입니다.</description>
<version>1.0</version>
<date>2016-05-27</date>
<link>http://bjrambo.com</link>
<author email_address="qw5414@naver.com" link="http://bjrambo.com">
<name xml:lang="ko">NAVER</name>
</author>
<colorset>
<color name="layout">
<title xml:lang="ko">레이아웃에 맞춤</title>
<title xml:lang="jp">レイアウトに合わせる</title>
<title xml:lang="zh-CN">随布局</title>
<title xml:lang="en">레이아웃에 맞춤</title>
<title xml:lang="zh-TW">隨版面</title>
</color>
<color name="white">
<title xml:lang="ko">하얀색(기본)</title>
<title xml:lang="jp">白(デフォルト)</title>
<title xml:lang="zh-CN">白色(默认)</title>
<title xml:lang="en">White (default)</title>
<title xml:lang="zh-TW">白色(預設)</title>
</color>
<color name="black">
<title xml:lang="ko">검은색</title>
<title xml:lang="jp"></title>
<title xml:lang="en">Black</title>
<title xml:lang="zh-CN">黑色</title>
<title xml:lang="zh-TW">黑色</title>
</color>
</colorset>
</skin>