發表文章

Smarty->foreach 迴圈抓出第一圈跟最後一圈的方法-教學撰寫:徐嘉裕Neil hsu

圖片
Xoops是使用Smarty樣板引擎,雖然有些判斷在php端就能處理,但是像系統佈景區塊之類的還是用Smarty的code來處理會比較方便,不用再另外寫一堆PHP程式,這裡分享一個在Smarty->foreach 迴圈抓出第一圈跟最後一圈的方法,使用first及last參數即可。

例如像下圖,需要抓出迴圈的第一圈跟最後一圈然後定義CSS做樣式樣的變化!




方法如下

<{foreach item=blockmenulayers from=$block.category name=blockmenulayers}>

<div class=' <{if $smarty.foreach.blockmenulayers.first eq true}>firstbox<{/if}>
<{if $smarty.foreach.blockmenulayers.last eq true}>lastbox<{/if}>panel-titlebox'>

內容內容內容內容內容............

</div>

<{/foreach}>

說明:
<{if $smarty.foreach.blockmenulayers.first eq true}>firstbox<{/if}>
//如果是第一圈first值為true顯示firstbox

<{if $smarty.foreach.blockmenulayers.last eq true}>lastbox<{/if}>
//如果是最後一圈last值為true顯示lastbox

所以class隨迴圈顯示的值就會是!

第一圈->firstbox

最後一圈->lastbox

扣除第一圈跟最後一圈->panel-titlebox

這樣就有三種css樣式可以定義了,讓版面更靈活美觀!!

有需要的朋友參考看看

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

CSS運算式calc() 數值運算-教學撰寫:徐嘉裕Neil hsu

在開發不規格佈景時需要用到隨物件調整CSS的top位置的功能,原本都是用JQuery計算在輸出的,後來發現原來css也能做數值運算,用calc() 這樣就能在smarty迴圈中定義的css並給予計算,然後自動調整物件的top位置,基本上來說只要式css的物件樣式都能計算

例如:

top: calc(60px + <{$a}>px);

<{$a}>為迴圈數預設為1,這樣每回圈一次top的數值+1輸出即為61,62,63......

也還能作其他的計算

width: calc(50% + 8px)
/* 意思是 50% 的寬度 + 上 8px */

width: calc(50% + -8px)
/* 意思是 50% 的寬度 + 上 -8px,也等於 '50% - 8px' */

+:加
-:減
*:乘。其中一個運算參數必須是數字 (number)
/:除。除數必須是數字,除數不可為零,會造成 HTML 解析錯誤。


有需要的朋友參考看看!

參考教學:https://5xruby.tw/posts/css-calc/

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

Xoops佈景區塊標題使用jQuery函數str.substr()限制輸出字元總數-教學撰寫:徐嘉裕Neil hsu

圖片
在開發xoops佈景時如果標題字數太長,我們通常會設個預設高度然後用overflow: hidden;隱藏被折行的內容,正常條件下這部分是沒問題的,但如果佈景標題想做些特別的設計,像是在文字右邊加上一些裝飾圖文,如果沒有限制輸出字元總數就會很麻煩!

舉例來說,如果要做文字右邊為斜角裝飾,文字區塊為display: inline;線內元素,文字沒段行之前都是正常的像下圖這樣



但如果文字段行後,原本的斜角就會跑到段行的結束點去



這樣畫面就不好看了,原因如下圖說明:


解決方法只能用jQuery函數str.substr()限制輸出字元總數,讓文字不要折行,這樣右邊距就不會跑到折行的下方,方法如下!


1、在佈景的<{$block.title}>標籤前面加上class定義好讓jQuery取值

<span class='blocktitle blocktitleto<{$block.id}>' name='<{$block.id}>'><{$block.title}></span>

備註說明:<{$block.id}>為區塊的id,我們用它來當作class的前綴


2、在佈景的js檔加上以下code

//顯示字元限制
$(document).ready(function(){
$(".blocktitle").each(function(index) {
$idname = $(this).attr("name");
var str=$(".blocktitleto"+$idname).text();
$(".blocktitleto"+$idname).text(str.substr(0,25));
});
});

備註說明str.substr(0,25) 藍字為擷取字串起始點,紅字為擷取字元總數


然後來看看剛剛被折行的區塊是否正常顯示



因為字元有輸出限制所以沒折行,右邊的斜線裝飾框就能正常顯示在區塊的右邊距了!


備註說明:如果是自行開發模組不用那麻煩,只要在php輸出加上
mb_substr($Title,0,25,'utf8');  即可!

有需要的朋友參考看看…

解決Xoops清除暫存檔後樣板$xoops_module_header不會產生jquery.js的方法!-教學撰寫:徐嘉裕Neil hsu

用過Xoops的朋友應該都有遇過這問題,就是會員登入後如果吧暫存樣板檔清除或重新產生暫存樣板檔,佈景樣板的<{$xoops_module_header}>並不會引入jquery.js,除非開啟的區塊中本身有引入jquery.js,這將導致佈景有用到jQuery特效的套件都會失效,所以我們需另外寫一支程式來補強這部分的問題,方法如下。

1、在佈景檔樣板檔中找到<{$xoops_module_header}>變數,因為每個佈景開發者的樣板檔名跟配置都不一樣,所以建議就一個一個檔去搜尋,一定會有的。


2、在<{$xoops_module_header}>前面加上以下的code

<!--module_header-->
<{php}>
if(!preg_match("/jquery.js/i", $this->_tpl_vars['xoops_module_header'])) {
$module_header="<script src='".XOOPS_URL."/modules/neillibrary/js/jquery.js' type='text/javascript'></script>";
}
echo $module_header;
<{/php}>

<{$xoops_module_header}>

//紅字為讀取預設jquery.js路徑,可以修改為自己需要放置jquery.js的位置
這樣就ok了,如果佈景的<{$xoops_module_header}>沒有產生jquery.js時就讀預設的jquery.js,如果<{$xoops_module_header}>中已經有jquery.js則不讀取預設jquery.js,也能防止jquery.js重複引入的問題。

教學心得撰寫:徐嘉裕 Neil hsu

修改CentOS7->Xampp->MariaDB->sql_mode的方法(資料庫模式修改)-教學撰寫:徐嘉裕Neil hsu

圖片
之前寫過一篇修改本地端Windows架設xampp的sql_mode嚴格模式設定方法,有需要的朋友可以參考看看!
https://neohsuxoops.blogspot.com/2019/12/1048-mariadb-sqlfor-windows.html

現在的問題是本地端Windows架設的xampp跟CentOS7架設的Lampp的sql_mode完全不一樣!

本地端(Windows)
sql_mode=NO_ZERO_IN_DATE,NO_ZERO_DATE,NO_ENGINE_SUBSTITUTION

伺服器端(CentOS7)
sql_mode=STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

當然如果以模組開發者的角度是採用更為嚴謹的資料庫模式設定,也就是伺服器端的資料庫模式來開發Xoops模組,所以我們開發的Xoops模組基本上這兩種模式都能運行!


但問題來了,Xoops還是有許多不錯的免費模組可以安裝,而且客戶也會自行安裝不是我們開發的模組,假設客戶端的sql_mode為超嚴謹模式,那這些模組都無法使用,會產生客戶管理網站的困擾,解決方法只能修改客戶端sql_mode改為較為寬鬆的
sql_mode=NO_ZERO_IN_DATE,NO_ZERO_DATE,NO_ENGINE_SUBSTITUTION
設定,這樣不管是我們開發的模組,還是客戶自己去安裝的模組就都能正常運作了,
修改CentOS7->Xampp->MariaDB->sql_mode的方法如下:

1、找到以下目錄,用筆記本打開
/opt/lampp/etc/my.cnf

2、找到[mysqld],在參數最下面加上
sql_mode = NO_ZERO_IN_DATE,NO_ZERO_DATE,NO_ENGINE_SUBSTITUTION
※預設是沒有sql_mode

[mysqld]
user=mysql
port=3306
socket=/opt/lampp/var/mysql/mysql.sock
key_buffer=16M
max_allowed_packet=1M
table_open_cache=64
sort_buffer_size…

10.4.8-MariaDB->SQL嚴格模式設定方法(for-windows)-教學撰寫:徐嘉裕Neil hsu

圖片
說起來也奇怪至今仍不解哪出問題了?本地端跟客戶端同樣都是安裝XAMPP-7.3.11版,但客戶端的sql_mode設定卻和本地端不相同,導致許多模組本地端是正常的但上傳到客戶端後都無法使用,資料存取出錯或無法寫入,經過檢查發現XAMPP的windows版本跟CentOS版本my.ini配置是不一樣的!

先來看一下my.ini設定->windows版

sql_mode=NO_ZERO_IN_DATE,NO_ZERO_DATE,NO_ENGINE_SUBSTITUTION

資料庫設定是使用

NO_ZERO_IN_DATE
NO_ZERO_DATE
NO_ENGINE_SUBSTITUTION

再來看CentOS->my.ini設定

sql_mode=STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

資料庫設定是使用

STRICT_TRANS_TABLES
ERROR_FOR_DIVISION_BY_ZERO
NO_AUTO_CREATE_USER
NO_ENGINE_SUBSTITUTION

差別在時間格式及預設值部分,為了讓本地端跟客戶端的設定一致,所以修改本地端的my.ini吧sql_mode替換為以下的設定值

sql_mode=STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION


重新啟用MYSQL後再SQL輸入SELECT @@GLOBAL.sql_mode看設定是否有生效!





如果顯示設定值跟my.ini中設定一樣就可以了,關於資料庫sql_mode常用值說明可以參考這個網站

http://xstarcd.github.io/wiki/MySQL/MySQL-sql-mode.html

先讓本地端跟客戶端設定一致,然後才來調整SQL語法,才能做升級工作喔!!

教學心得撰寫:徐嘉裕 Neil hsu

使用htaccess進行網站轉址的方法-教學撰寫:徐嘉裕Neil hsu

分享一些常用的.htaccess網站轉址方法!有需要的朋友參考看看!

//網址轉換
RewriteEngine on
RewriteCond %{HTTP_HOST} ^123.88.88.666$ [NC]
RewriteRule ^(.*)$ http://www.blogger.com [R=301,L]

這樣可以吧網站的IP:123.88.88.666轉換成http://www.blogger.com但不包含所帶變數及路徑

//網址轉換包含路徑檔名變數
RewriteEngine on
RewriteCond %{HTTP_HOST} ^123.88.88.666$ [NC]
RewriteRule ^(.*)$ http://www.blogger.com%{REQUEST_URI} [L,R=301]

這樣可以吧網站的IP:123.88.88.666轉換成http://www.blogger.com包含路徑檔名及變數

例如: http://123.88.88.666/index.php?id=123 轉換後   http://www.blogger.com/index.php?id=123

//HTTP轉HTTPS包含路徑檔名變數
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

自動吧網站的http轉換為https包含路徑檔名及變數

把需要轉址的code貼到伺服器根目錄中的.htaccess文件裡面在重啟apache即可套用新設定


教學心得撰寫:徐嘉裕 Neil hsu

jQuery變更結構中id名和class名的方法-教學撰寫:徐嘉裕Neil hsu

使用attr()函數可以變更網頁結構中的id名和class名,達到css樣式或是js功能切換的目的,方法如下!

//HTML結構

<div id='boxid1'  class='boxclass1'>內文內文........</div>

//更換Id名稱

$("#boxid1").attr('id','boxid2');

這樣結構中的id由原本的boxid1更換為boxid2


//更換Class名稱

$(".boxclass1").attr('class','boxclass2');

這樣結構中的class由原本的boxclass1更換為boxclass2

有需要的朋友參考看看

心得教學撰寫:徐嘉裕 neil hsu

擷取臺中市教育局校園活動新聞的PHP程式,可用於Xoops自訂區塊中-教學撰寫:徐嘉裕Neil hsu

圖片
首先要先感謝台中市喀哩國小資訊老師提供的原始程式碼,這樣讓我節省很多時間,不用再去開發網頁爬蟲程式,這裡就按照原始程式碼修改為兩個樣式!直接可以顯示臺中市教育局校園活動新聞內容

首先區要知道所屬學校的網址,這樣程式才能去爬行撈資料,查詢學校網址的方法如下:

1、先進入臺中市校園活動新聞首頁
http://www.tc.edu.tw/SchoolNews/show

2、找到右下角的學校發表排行區塊

3、找到自己學校點進去,上面的網址就是該學校活動新聞網址,之後的程式需要貼入


樣式一:區塊輪播樣式




//PHP程式碼

echo "<script type='text/javascript' src='http://www.tc.edu.tw/js/jquery-1.6.4.min.js'></script> <script type='text/javascript' src='http://www.tc.edu.tw/js/plugins/jquery.cycle.all.min.js'></script> <script type='text/javascript'> $('#school_news').cycle({         fx:     'turnDown',         delay:  -2000,         speed:  2500 ,         timeout:  5000 ,         pause:1    }); </script>

$show_num=1;//顯示幾則新聞,大於1則會有輪播效果
//取得新聞
$url = "http://www.tc.edu.tw/SchoolNews/show/school/id/546";  //貼上校園活動新聞網址
$contents = addslashes(file_get_contents($url));
$contents = str_replace (addslashes('href="/'), addslashes(' href…

仿CSS的nth-child功能用PHP做一個用迴圈數帶出固定1.2.3的數值重複function-教學撰寫:徐嘉裕Neil hsu

圖片
CSS的nth-child其實是很好用的,但唯一的限制是指定的物件必須為相連,而且無法對子物件做樣式設定,例如以下結構就無法用nth-child來定義.thumbnail的樣式!

<ul class="row">
<li class="col-md-4">
<div class="thumbnail"><img>......略</div>
</li>
<li class="col-md-4">
<div class="thumbnail"><img>......略</div>
</li>
<li class="col-md-4">
<div class="thumbnail"><img>......略</div>
</li>
</ul>

物件必須相連,nth-child是用物件的順序來定義樣式的,如果要做以下的效果固定迴圈3個區塊3種樣式用nth-child是無法實現的!!

當然是還有解決方法,Xoops是使用smarty樣板引擎,在foreach裡面用<{cycle values="box01,box02,box03"}>來定義class也是可以,但如果有做了AJAX的分類切換功能,那被切換的頁面是讀ajax.php,所以smarty的cycle又不能用了,無法兼顧。

最終的解決辦法還是要靠PHP,利用迴圈吧固定1.2.3的倍數整除後回傳數值,然後再輸出到樣板或直接輸出PHP上,這樣就沒問題了!寫了一個自動分3區塊樣式的function有需要的朋友參考看看!

//PHP-CODE
function blocksclassbox($key="",$i="",$type="",$prefix=""){
$nthchilds="".$prefix."box01"; //初始值