跳到主要內容

Xoops模組開發->使用xlanguage3.1RC多國語言模組配合的程式修改-教學撰寫:徐嘉裕Neil hsu

xlanguage是一套可以切換Xoops語言的模組,也能透過語言標籤來切換語言內容,以達成網站多國語言的目的,xlanguage3.1RC可以完全兼容Xoops2.5.10,而且也已經被Xoops官網收錄於官方模組中,直接安裝起來用能使用了,我已經吧xlanguage模組中文化完成了,有需要的朋友可以點以下連結下載。

xlanguage3.1RC中文化下載

https://drive.google.com/file/d/1Wz8tcHLE-xtM8vwa0_NfVAyH8Xjewwv2/view?usp=sharing


雖然說安裝起來並設定好語言開啟區塊就能使用



但經過實際測試,還是有很多問題需要在其他模組寫程式套件來配合運作,才能達到100%完美應用,否則使用上還是很多不便利的地方,以下為修改模組紀錄彙整。

1、xlanguage的語言切換作用機制主要有兩段,一部分是吧user選擇的語言儲存到setcookie裡面在讀取對應的模組語言包,這部分可以切換UI的語言,另一部分則是資料字段的轉換,例如

[tw]這是中文標題[/tw][en]This is the Chinese title[/en]

所以如果選擇中文顯示[tw]這是中文標題[/tw]中字段,選擇英文則顯示[en]This is the Chinese title[/en],語言標籤會被去掉,但這作用並不是在sql資料導出時做字段判斷,而是用伺服器頂層的Java吧所有PHP輸出的變數都掃過一次比對後擷取語言標籤內容,好處是不用在模組資料輸出去做字串擷取所有的模組都能使用,但會產生一個問題,如果不是輸出頁面的變數,像是幕後傳參寄發E-mail,就無法做語言判斷,反而會吧全部字串都給輸出,像是這樣


收到通知信的人大概也一頭霧水吧,什麼碗糕?解決辦法就是另外寫一個資料轉換function給幕後讀取資料時使用,code如下:

◎吧xlanguagePlugin()放到function.php裡面

//取得指定模組module資料表值
function modulesmidvar($modulesid="",$var=""){
$modulevar=empty($var) ? 'mid' : $var; // get TRUE
$module_handler =& xoops_gethandler('module');
$xoopsModule =& $module_handler->getByDirname($modulesid);
if(!empty($xoopsModule)) $mid = $xoopsModule->getVar($modulevar);
return $mid;
}

//xlanguage輔助插件-資料轉換
function xlanguagePlugin($var=""){
global $xoopsConfig;

//判斷xLanguage是否啟用
if(empty(modulesmidvar($modulesid="xLanguage",$val="isactive"))) return $var;

//讀取xlanguage_base資料表
$dbneme="xlanguage_base";
$where=" where lang_name='".$xoopsConfig['language']."'";
$langvar=moduledb($dbneme,$where);
//起始標籤
$startvar="[".$langvar['lang_code']."]";
//結束標籤
$endvar="[/".$langvar['lang_code']."]";
if(!empty(substr(CatchStrfunction($var,$startvar,$endvar),mb_strlen($startvar, "utf-8"),-mb_strlen($endvar, "utf-8")))){
$resultvar=substr(CatchStrfunction($var,$startvar,$endvar),mb_strlen($startvar, "utf-8"),-mb_strlen($endvar, "utf-8"));
}else{
$resultvar=$var;
}
return $resultvar;
}

◎在郵寄的php中引入function.php,並吧需要轉換語言標籤的字串變數放入,像這樣
$title=xlanguagePlugin($var=$title);

這樣幕後傳參時xlanguagePlugin會自動按照語言標籤擷取對應的內容,寄出的郵件也就不會有語言標籤了。


2、剛剛前面有講到xlanguage模組語言標籤切換機制在伺服器的JAVA,所以如果用CK編輯器編輯語言字串內容時會被自動轉換為當前語言內容



這樣語言標籤都不見了儲存後進資料表也只剩中文字串,不就變成每編輯一次就要在重新建立一次資料,還好這部分xlanguage已經有做基本判斷,如果資料類型為htmlspecialchars()則輸出完整字串不做擷取

$value="".htmlspecialchars($enshow['introduction']).""




這樣就沒問題了,為了方便寫了一個批次轉換htmlspecialchars的function,直接於資料表陣列輸出時使用即可,CODE如下:

◎吧htmlspecialcharsbatch()放到function.php裡面

//批次轉換htmlspecialchars
function htmlspecialcharsbatch($allowvar="",$eachvar=""){
while (list($var, $value) = each($eachvar)) {
if(in_array($var,$allowvar)){
 $valuevar[$var]=htmlspecialchars($value);
}else{
 $valuevar[$var]=$value;
}
}
return $valuevar;
}

◎於PHP讀取資料回傳陣列值處使用htmlspecialcharsbatch()

//批次轉換htmlspecialchars
$enshow=htmlspecialcharsbatch($allowvar=array("companyname","applicant","brief","introduction"),$eachvar=$enshow);

//$eachvar為輸入資料陣列的變數

其中array就是需要轉換為htmlspecialchars格式的變數NAME。


3、這是最重要的輔助程式套件開發,就是語言標籤錯誤時無害化處理,有時候管理人員在輸入標籤時可能會少打一個標籤,例如

[tw]這是中文標題[tw][en]This is the Chinese title[/en]

[tw]這是中文標題[/tw][en]This is the Chinese title[/en

tw]這是中文標題[/tw][en]This is the Chinese title[/en]

剛剛講了xlanguage擷取字串機制在伺服器端的JAVA,如果標籤打錯了網站又用了很多JS程式像是瀑布流阿?圖片撥放器特效阿,整個前端的頁面就會一面空白,開PHP除錯也沒用因為作用機制不是在PHP上,所以很難查錯的,解決辦法就是在資料insert及update的地方寫一個標籤檢查無害化處理的function,由於我習慣是吧insert及update都function後放在neillibrary模組的function.php裡面,所以就改這一處就好了,全部引用neillibrary模組function.php的模組就通通都能做標籤檢查及無害化處理,code如下。


◎吧xlanguageCheck()放到function.php裡面

//xlanguage模組標籤檢查無害化處理
function xlanguageCheck($dbname="",$returnid="",$type=""){
global $xoopsConfig;

//取得欄位KEY值
list($var, $value) = each($moduledbList=moduledb($dbneme=$dbname,$where=""));

//開啟資料表
$whereDB=" where `".$var."`='".$returnid."'";
$dbdata=moduledb($dbneme=$dbname,$where=$whereDB);
//讀取xlanguage_base資料表
$langvar=databasetablewhile($dbneme="xlanguage_base",$where="");
//標籤檢查區
while (list($var, $value) = each($langvar)) {
foreach($dbdata as $key=> $val){
if( preg_match("/(?:".$langvar[$var]['lang_code'].")/i", $val)   and  (preg_match("/(\[".$langvar[$var]['lang_code']."\])/i", $val)  or preg_match("/(\[\/".$langvar[$var]['lang_code']."\])/i", $val)    )){  //抓出符合條件
if ((!preg_match("/(\[".$langvar[$var]['lang_code']."\])/i", $val) or !preg_match("/(\[\/".$langvar[$var]['lang_code']."\])/i", $val)  )) {  //比對完全符合條件
$updatevar[$key]="[".$langvar[$var]['lang_code']."][error]".$val."[/error][/".$langvar[$var]['lang_code']."]";  //無害化處理
}
}
}
}
//組合資料生成set
if(!empty($updatevar)){
$setvar.=" set";
while (list($var, $value) = each($updatevar)) {
$setvar.=" ".$var."='".$value."'  ,";
 }
$set=" ".substr($setvar,0,-1)." ".$whereDB."";
update($dbname,$set);  //寫入資料表
}
}

◎然後在insert的地方加上xlanguageCheck檢查及無害化

//新增一筆資料
function insert($dbname="",$values=""){
global $xoopsDB; 
$sql = "insert into " . $xoopsDB->prefix($dbname) . " ".$values."";
$xoopsDB -> queryF($sql) ;
$returnid=$xoopsDB->getInsertId();

//判斷xLanguage是否啟用
if(!empty(modulesmidvar($modulesid="xLanguage",$var="isactive")))
xlanguageCheck($dbname,$returnid,$type=""); //xlanguage模組標籤檢查無害化處理
return $returnid;
}

◎然後在update的地方加上xlanguageCheck檢查及無害化

//更新資料單一筆
function update($dbname="",$set="",$back=""){
global $xoopsDB; 
$sql      = "update " . $xoopsDB->prefix($dbname) . " ".$set."";
$xoopsDB->queryF($sql) or web_error($sql);

$moduledbList=moduledb($dbneme=$dbname,$where=" ".strstr($set,'where')." ");
//取得欄位KEY值
list($var, $value) = each($moduledbList);
$returnid=$value; //回傳更新欄位值

//判斷xLanguage是否啟用
if(!empty(modulesmidvar($modulesid="xLanguage",$var="isactive")))
xlanguageCheck($dbname,$returnid,$type=""); //xlanguage模組標籤檢查無害化處理
$returnid=empty($back) ? $returnid : true; // get TRUE
return $returnid;
}

這樣即使標籤寫錯也會自動加上[error]跟正確的語言標籤再存入資料庫,像是這樣


故意寫錯(紅字少結尾/)

[tw]尼爾網站設計工坊[tw][en]Neil Website Design Workshop[/en]

儲存後會變成





[tw][error][tw]尼爾網站設計工坊[tw][en]Neil Website Design Workshop[/en][/error][/tw]

無害化處理後頁面不會變空白,看到[error]標籤出現就知道有出錯,也方便管理者修正!!


4、最後一項程式修改屬於佈景端,因為中文跟英文字數不一樣,英文字數多所以應該字要比較小,還有行距間距也要調整,所以必須針對其他語言做樣式樣的調校才能達到瀏覽最佳化的目的,方法如下。

◎在佈景的tpl資料夾裡面找到引入佈景css的樣板,打開編輯

//原佈景引入css檔
<link href="<{xoImgUrl}>/css/style/style.css" rel="stylesheet" media="all">

//新增加語言css引入檔
<link href="<{xoImgUrl}>/css/language/<{$xoops_langcode}>style.css" rel="stylesheet" media="all">

<{$xoops_langcode}>標籤會輸出Xoops的語言,所以切換成英文時就會是en,css組合後形成enstyle.css

◎在佈景放置body標籤的地方加上css定義,class="<{$xoops_langcode}>"

◎在佈景的css資料夾裡面加上language資料夾,再放置enstyle.css黨

這樣就能在enstyle.css裡面定義語言為英文的css樣式
.en #header {
font-size: 80%;
line-height: 50%
}

其他語言也能再language資料夾中增加css檔來對應


完成這四項修改後使用xlanguage模組就會順的不要不要的,不會再有什麼奇怪的問題了,以上為爆肝工作心得分享,有需要的朋友參考看看!


工作心得撰寫: 徐嘉裕 Neil hsu

留言

這個網誌中的熱門文章

好用的windows備份檔案dos指令XCOPY-教學撰寫:徐嘉裕Neil hsu

要快速的備份某個硬碟全部資料到備份硬碟中,雖然是可以用windows內建的備份與還原,但如果重灌windows可會有key不同而無法還原的問題,還要改一堆設定煩死了,直接用dos指令XCOPY來做檔案的複製就很快了,資料也不會丟失,好朋友可以參考看看!! 首先開啟windows所有程式->附屬應用程式->開啟命令提示字元! 然後輸入以下指令 XCOPY C:\xxx   F:\xxx /s 藍字的 C:\xxx  為複製檔案來源位置例如要複製整個C槽就輸入 C:\ 綠色的   F:\xxx 為複製目的位置,例如要放到F槽的備份資料夾,就輸入  F:\ 備份 紅字的 S 為複製類型參數,可以自行修改為以下的參數設定: ================================================================= /A    只複製設定成保存屬性的檔案,不要改變屬性的設定。 /M    只複製設定成保存屬性的檔案,並清除保存屬性。 /D:m-d-y  複製指定日期當天或之後變更的檔案。如果沒給日期,只複製那些來源檔案日期比目的檔案日期為新的檔案。 /EXCLUDE:file1[+file2][+file3]...         指定檔案清單字串。每個字串應在不同行。如果有字串對應到要進行複製的檔案絕         對路徑的任何部分,這個檔案會被排除複製。例如,指定字串         \obj\ 或 .obj 的話,會排除所有在 obj 目錄下副檔名是.obj 的檔案複製。 /P    在建立每個目的檔案時顯示提示。 /S    複製每個目錄及其包含的子目錄,不複製空目錄。 /E    複製每個目錄及其包含的子目錄,也複製空目錄。/S 與 /E相同,能夠用來修改 /T。 /V    驗證每個新檔案。 /W    在複製之前提示您按鍵繼續。 /C    如果錯誤發生時也繼續複製。 /I    如果目的不存在且複製一個以上的檔案的話,就假設指定的目的一定是目錄。 /Q    在複製時不要顯示檔名。 /F    在複製時顯示來源及

jQuery取得下拉選單selected中數值與內容的方法

假設選單狀態為: <select id='selectname '> <option value='v1' data-id="d1">選單A</option> <option value='v2' data-id="d2">選單B</option> <option value='v3' data-id="d3">選單C</option> </select> 以jQuery取得選單數值與內容方法如下: 1、取得下拉選單 value 數值的方法 $selectname=$('#selectname').val(); alert($selectname); //顯示選單中 selected 狀態的value數值v1 or  v2  or  v3。 2、取得下拉選單中 data-id 數值的方法 $data-id= $(this).find(':selected').attr('data-id'); alert($data-id); //顯示選單中 selected 狀態的data-id數值d1 or  d2 or  d3。 3、取得下拉選單中 文字 的方法 $selecttext=$(this).find(':selected').text(); alert($selecttext); //顯示選單中 selected 狀態的文字內容,如選單A or  選單B or 選單C。 教學撰寫:徐嘉裕 Neil hsu

CentOS7啟用ssh的設定方法-教學撰寫:徐嘉裕Neil hsu

安裝好CentOS7後可以在圖形化介面中點選右鍵->開啟服務器修改設定後啟用SSH設定,方法如下: 1、先安裝openssh套件 sudo yum install openssh* 2、用 gedit 開啟sshd_config編輯 (不要用vi很難編輯的) sudo gedit /etc/ssh/sshd_config 3、增加可連線SSH帳號 AllowUsers admin (此欄位需要自行新增) 4、修改PORT吧 # 註解拿掉 (可以改成8022PORT或其他PORT都可以) Port 22 搜尋PermitRootLogin吧 # 註解拿掉 PermitRootLogin no 再來把這兩行的 # 註解拿掉 PermitEmptyPasswords no PasswordAuthentication yes 搜尋Protocol設定使用SSHv2連線 Protocol 2 sudo systemctl restart sshd.service    重新啟動service sudo systemctl enable sshd.service    設定開機啟動SSH sudo semanage port -a -t ssh_port_t -p tcp 22      防火牆允許22 PORT 或 sudo firewall-cmd --permanent --zone=public --add-port=22/tcp 重新載入防火牆設定 sudo firewall-cmd --reload sudo  netstat -ant | grep :22 查看 22PORT 查詢現在SELinux設定清單中的SSH服務有哪些Port sudo semanage port -l | grep ssh ssh_port_t tcp 8022, 22 怎麼測試? 格式:登入帳號@IP或主機名稱 指令:-p SSH服務Port號 sudo ssh -p 22 admin@192.168.1.100 如設定的Port在清單中 ,那就表示SSH設定完成防火牆也開啟列外了,之後再用遠端的PuTTY輸入 IP/Port 連線,然後輸入 帳號/密碼,就能用SSH連線進入主機了, 在透