在Apache環境下為網頁資料夾加密

學習網頁開發的時候,難免會需要自行架設伺服器在本機上,但一旦為自己的電腦安裝了伺服器之後,只要電腦一連上網,全世界任何人只要使用你在網路上的IP就可以連上你的伺服器。

於是我們想要設定使用者名稱與密碼來保護我們自己的伺服器,以限定能夠瀏覽的使用者。而為了做到這件事,我們會需要兩個檔案:.htpasswd、與.htaccess

為伺服器新增使用者

首先我們需要產生一個存放帳號密碼的.htpasswd檔案,建議是放在網頁根目錄再上層的其他地方以避免他人從網路上存取。

例如要新增的使用者名稱叫做user,產生方法如下。

sudo htpasswd -c /path/to/.htpasswd user

此時系統會提示你要輸入密碼,Enter確定後會要再輸入一次,以確保剛剛輸入密碼正確。

如果你想繼續增加一個使用者叫做user2,可以在終端機再這樣輸入。

sudo htpasswd /path/to/.htpasswd user2

你可以為user2設定另一個完全不同的密碼。

.htpasswd檔案裡面,帳號會直接儲存、而密碼會記錄一個用MD5算出的雜湊值(看起來就是一個亂碼才不會被發現),所以我們看到剛剛做出來的.htpasswd檔案裡面寫成這樣:

user:$apr1$dxTa0IZA$B8XPOXcm5geDT17eJ2VYf1
user2:$apr1$lzxsIfXG$tmCvCfb49vpPFwKGVsuYz.

分別記錄兩個使用者(user與user2)的帳號與密碼雜湊值,之後伺服器就可以用同樣的算法去做密碼驗證。所以其實如果不用終端機的話,也可以到這個網站來產生我們想要的帳號與密碼雜湊值,一個使用者寫一行,或者你也可以自己寫演算法XD

保護根目錄

接著我們在想保護的資料夾裡面,新增一個.htaccess檔案寫入以下文字來告訴伺服器:這個目錄需要有權限才能進入,如果該檔案已經存在的話就直接把文字加在裡面。

AuthType Basic
AuthName "My Protected Area"
AuthUserFile /path/to/.htpasswd
Require valid-user

不知道怎麼寫的話,也可以到這個網站把產生的文字存成檔案,直接放在想保護的目錄裡就可以了。

弄好之後,再次進入我們自己的網站,搞定!

補充說明

.htaccess檔案內我們剛剛新增的內容,其實要寫在伺服器設定檔也是可以的,可以參考這個網誌

另外,如果想要修改密碼的話,其實就等於再做一次使用者設定,例如我們要修改user2的密碼。

sudo htpasswd /path/to/.htpasswd user2

參考資料

  1. DigitalOcean
  2. [教學]對網頁啟用密碼驗證 (Apache) | 辛比誌
  3. 對網頁目錄設定需要帳號密碼來登入 – htaccess @ 黃昏的甘蔗

在WordPress中將分類按照階層排列

目標

假設現在有一篇文章的分類包含以下多項,且彼此之間有階層關係。

  • 關東
    • 東京
      • 代官山
      • 澀谷
    • 神奈川
      • 橫濱

所以我們想要將這些分類,依照原本的階層順序顯示為:關東、東京、代官山、澀谷、神奈川、橫濱。在Wordpress中預設以name排序:代官山、東京、橫濱、澀谷、神奈川、關東,而其他比較有意義的排序法大概也就是按文章數量countquery查詢工具),但也並非想要的排列。

有些Plugin可以自訂分類排序,例如:

  • WP Term Order
  • Category Order and Taxonomy Terms Order
  • Custom Taxonomy Order

但是能夠改的排序,限為同層分類的排序,例如你可以把自訂把「澀谷」擺到「代官山」前面,或者讓「神奈川」整個群組都比「東京」先出現,依然不是我們要的功能。

只好來實做看看。

取得所有分類

首先要取得某篇文章的所選分類,可以用get_the_category來取得一個包含所有分類項目Object的Array,再利用array_map把這些分類的名稱單獨挑出來。

$object_id = get_the_ID();
$categories = get_the_category( $object_id );

$terms = implode( '、', array_map(function($item) { return $item->name; }, $categories ));
echo $terms; // 代官山、東京、橫濱、澀谷、神奈川、關東

或者,也可以使用wp_get_object_terms來取得任意自訂分類。

$object_id = get_the_ID();
$taxonomies = 'category'; // 這邊我們就選擇預設分類
$args = array( 'fields' => 'all' ); // options arguments
$categories = wp_get_object_terms( $object_id, $taxonomies, $args );

$terms = implode( '、', array_map(function($item) { return $item->name; }, $categories ));
echo $terms; // 代官山、東京、橫濱、澀谷、神奈川、關東

我們發現:欸?階層不見了,最上層的「關東」表示憤怒竟然排在最後!!!先不要管為什麼,但接下來我們就要利用分類項目中的parent屬性,來為每個項目進行認親的動作,以達到優先以階層排序的目的。

為分類找階層排序

懶得看文章的話程式碼在這裡,使用方法就是把wp_get_object_terms改成get_object_terms_hierarchical就可以惹。

<?php
// 點兩下這裡看原始碼
/**
  * Make terms retrieved by wp_get_object_terms() organized hierarchically.
  *
  * Use this function instead of wp_get_object_terms() to get a hierarchically
  * structured array or term data.
  *
  * This function takes the terms returned by wp_get_object_terms() and organizes
  * them into a hierarchical array with the parent's children (and grandchildren)
  * stored in nested arrays (within the 'children' item).
  *
  * @see wp_get_object_terms() for parameters.
  *
  * @return array $terms Hierarchilized $terms array.
  */
function get_object_terms_hierarchical( $object_ids, $taxonomies, $args = array() ) {
  $return_flat = true;
  $tree  = array();
  $terms = wp_get_object_terms( $object_ids, $taxonomies, $args );
  $ids = array_map(function($item) { return $item->term_id; }, $terms);
  if ( ! empty( $terms ) ) {
    foreach ( $terms as $term ) {
      if ( $term->parent == 0 || !in_array($term->parent, $ids) ) {
        if ( $return_flat ) {
          array_push($tree, $term);
          get_child_terms( $term->term_id, $terms, $tree );
        } else {
          $tree[ $term->term_id ] = $term;
          $tree[ $term->term_id ]->children = get_child_terms( $term->term_id, $terms );
        }
      }
    }
  }
      
  return $tree;
}
  
/**
 * Organizes the child terms.
  *
  * This is a recursive function.
  *
  * @param interval $parent_id The parent ID to retrieve the children terms of.
  * @param array  $terms The term data.
  *
  * @return array Returns nested child terms.
  */
function get_child_terms( $parent_id, $terms, &$order_terms = null ) {
  $children = array();
  foreach ( $terms as $term ) {
    if ( $term->parent == $parent_id ) {
      if ( $order_terms ) {
        array_push($order_terms, $term );
        get_child_terms( $term->term_id, $terms, $order_terms );
      } else {
        $children[ $term->term_id ] = $term;
        $children[ $term->term_id ]->children = get_child_terms( $term->term_id, $terms );
      }
    }
  }
  return $children;
}

第18行的$return_flat設定輸出為單層Array或者維持階層,設定為false的話子項目會存在children這個key裡。

測試看看。

$object_id = get_the_ID();
$taxonomies = 'category'; // here we use the default
$args = array( 'fields' => 'all' ); // options arguments

$categories = wp_get_object_terms( $object_id, $taxonomies, $args );
$terms = implode( '、', array_map(function($item) { return $item->name; }, $categories ));
echo $terms; // 關東、東京、代官山、澀谷、神奈川、橫濱

關東終於拿下他該有的位置了,很好!我們搞定。

解釋一下

事實上在後台設定了分類間的階層關係,也只會在Wordpress資料庫中新增一個parent欄位描述某個分類的上層id,所以資料本身是沒有分層的,我們必須再自己重新配對好它們的從屬關係才行。

事實上,Wordpress自己則是用了一個叫Walker類的方法,也一樣可以取得正確的階層分布,其基本原理也是會去「走」遍所有分類去做認親。

$object_id = get_the_ID();
$categories = get_the_category( $object_id );
$cat_ids = array_map( function($item) { return $item->term_id; },  $categories );
$args = array(
    'include' => $cat_ids,// 我們只取文章有使用到的分類 id 們
    'hierarchical' => true,
    'title_li' => '',   // 移除第一個大項目寫「分類」
    'style' => '',      // 設定成 list 以外的字串以避免輸出 ul>li
    'separator' => '、' // 將預設的 <br /> 改為中文頓號 
);
$terms = wp_list_categories( $args );
echo $terms; // 代官山、東京、橫濱、澀谷、神奈川、關東

成功!那你說我用wp_list_categories就好啦?不行。

假如今天沒有選用任何最上層分類的話,這裡就會出現bug。我們考慮同樣的分類階層,例如有一篇文章沒有勾選「關東」,只選用了其中的

  • 神奈川
    • 橫濱

這時候用Wordpress的內建函式wp_list_categories會得到

echo $terms; // 橫濱、神奈川

那欸阿餒?改用get_object_terms_hierarchical看看。

echo $terms; // 神奈川、橫濱

成功啦!

參考資料

  1. EricBusch/get_object_terms_hierarchical
  2. WordPress/get_the_category
  3. WordPress/wp_get_object_terms
  4. WordPress/wp_list_categories

在MacOS上啟用vhost虛擬主機

我們可以在Mac上使用預載好的Apache伺服器,就可以在瀏覽器網址輸入localhost來使用。除此之外,也可以透過設定打開個人資料夾,就可以把開發完成的網站都丟進去做測試。不過個人認為彈性更大、且簡潔的作法是直接設定vhost虛擬主機,透過和hosts搭配,就可以在本機端上部署多個任意網域。

例如:

  • dev.apple
  • dev.banana
  • dev.chocolate

欸,都是吃的是有多餓!不過這樣就可以為專案分門別類惹⋯⋯望向那凌亂的桌面,現實世界跟虛擬世界都一樣亂⋯⋯正文開始。

打開虛擬主機

首先要修改設定檔,進入終端機Terminal輸入:

sudo vi /etc/apache2/httpd.conf

在大約行數#517的位置,將下列行取消註解(把#字號刪掉)

#Include /private/etc/apache2/extra/httpd-vhosts.conf

這樣以來伺服器就會引入httpd-vhosts.conf這個設定檔,以設定不同網域分別對應的根目錄路徑。

設定網域根目錄

接下來就要修改vhost的設定,打開設定檔

sudo vi /etc/apache2/extra/httpd-vhosts.conf

例如我們把想資料夾/Users/aName/foo指派為dev.com對應的根目錄的話,就可以在內文插入

<VirtualHost *:80>
    DocumentRoot "/Users/aName/foo"
    ServerName dev.com
    ServerAlias www.dev.com
</VirtualHost>

設定網域指向

我們把網域對應到根目錄之後還要設定hosts,才能讓瀏覽器在本機端找到網域對應的實體ip位址,以現在的例子就是要把dev.com指到127.0.0.1,就是localhost的IP。首先打開hosts檔案

sudo vi /etc/hosts

加入這一行

127.0.0.1 dev.com

設定完成後,重啓伺服器就搞定。

sudo apachectl restart

權限處理

第一種:看不到網頁

如果在瀏覽器網址欄輸入dev.com遇到錯誤顯示

Forbidden
You don't have permission to access / on this server.

回到vhost設定檔,在設定dev.com的區塊</VirtualHost>標籤之前加入以下設定

<Directory "/Users/aName/foo">
    Options FollowSymLinks Multiviews Indexes
    MultiviewsMatch Any
    AllowOverride All
    Require all granted
</Directory>

再重新啟動伺服器,就好。

第二種:網頁程式沒有寫入權限

如果是看到

Forbidden
You don't have permission to access /folder/ on this server.
Server unable to read htaccess file, denying access to be safe

或是這類網頁檔案沒有權限寫入資料夾的狀況

The deployment path above must be writable by PHP in order to extract the archive file.

這裡會出現許多種作法,當然我們是可以利用chown -R修改資料夾及其內所有檔案權限為_www:_www,但是發現這樣在每次修改檔案的時候都要輸入密碼,因為此時檔案的擁有者不是自己,會變成類似在修改電腦系統檔案那樣很麻煩,所以我選擇把網頁的使用者跟群組乾脆改成自己,比較一勞永逸。

回到vhost設定檔,在設定dev.com的區塊<VirtualHost>標籤之外的地方加入以下設定

<IfModule unixd_module>
    User username
    Group staff
</IfModule>

其中,username請換成個人的使用者帳號名稱。然後再重新啟動伺服器,就好。

參考資料

  1. 在MacOS上使用Apache+PHP+MySQL
  2. 如何開啟個人資料夾

後記

雖然之前已經設定過了,但OS更新似乎會把原有的設定給覆蓋掉,結果又要重新設定一次⋯⋯覺得很麻煩於是做個記錄。

還有遇到問題再補(揍飛

3D Exhibition

Concept

Inspired from Codrops – Experimental 3D Room Exhibition Layout, but added further more functions! Now you can click every single image to get closer to it, and also available to read description and story behind photos.

Design

Origin post from Codrops is use 3D room as background only, but today I make it more joyful to play around. By separating the .content into .content-top and .content-bottom, we are now able to click on images behind scene! Then, I reuse the .info element with dynamically loading HTML content, so every picture can get its own information written side by side.

Also, I simplify navigation arrows animation to make it less distraction from focusing at gallery, modify color transition to menu icons so get more natural behavior, and add left/right arrow keyboard navigation supported.

On mobile phone, you can even tilt the device to change viewing perspective of room to get more closer to photo you are interested.

Playground

ひより/Hiyori/日和

前言

台灣人出國旅遊最熱門的國家,就是日本。無論在任何季節,都有著許多特色景點的國家,春天賞櫻、夏天新綠、秋天紅葉、以及冬天白雪。櫻花的粉紅,象徵一個旅遊部落格的開始,以此開始逐漸成長茁壯,與一般遊記式的景點介紹不同,著重在更多資訊的分享,以景點的特色風情為主、以個人的旅遊經驗為輔,並且透過精心拍攝及挑選的照片,希望傳遞給讀者最真實的感動。

簡介

偶爾會有的食記,除了名店以外也會介紹特色的小店,每一篇文章底下的資訊欄,都可以幫助讀者更快速的找到所需要的相關情報,讓人無須迷失在其他類似的遊記中。

首頁的三篇焦點文章,是作者為自己最近生活的最佳註解,亦提供最合時宜的當季精選。有需要的人則可以立即透過首頁的行動按鈕,傳送信息聯絡作者,洽詢相關的合作機會。

Hiyori在日文裡是晴天的意思,希望每一趟旅程,都成為美好的回憶、心情也放晴:)

SNW 2018

The 2018 Silicon Nanoelectronics Workshop is a satellite workshop of the 2018 VLSI Symposia sponsored by the IEEE Electron Device Society. It will be held on June 17-18, 2018 at the Hilton Hawaiian Village in Honolulu, Hawaii USA. This will be the 24th workshop in the annual series. Original papers on nanometer-scale devices and technologies that utilize silicon or which are based on novel materials on silicon substrates are welcome.

Go to site

Kotoba 和和字典

設計

後端基於CI的框架實作了一個日語字典網站,前端則運用MUI CSS實現Material Design的風格。註冊只需要使用者名稱,登入後可以把單字加入最愛,並且可以根據需求自行分類。歡迎大家進來玩玩~用手機的話還可以利用iOS的「加入主畫面」功能、或Android的「新增至主螢幕」功能,將網站設為常用桌面捷徑。

資料來源: weblio辞書

Go to page

待更新項目

  • 其他語言支援:英語、中文等
  • 更多個人化設定
  • PWA化

デザイン

バックエンドはCIに基づいてオンライン辞書を、フロントエンドはMUI CSSを基にしてMaterial Designを実装してみた。新規登録にUsernameだけ、登録したら、単語の管理や分類などをご自由に。よければ是非使ってみてください。携帯端末を利用する場合、iOSのSafari又はAndroidのChromeで「ホーム画面に追加」機能でショートカット作成することができる。

Hanabi

簡介

練習了JS對Canvas的操作,並且利用requestAnimationFrame以利瀏覽器以最大效能渲染煙火點。每一個產生的煙火約有500個煙火點,利用不斷堆疊的透明黑色,製造出殘影的效果。透過對煙火物件Property的改變,可以輕易達到改變顏色的效果。

在不同的參數設定下,意外產生出規律圖形。有一個如梅花般的效果,於是就保留下來了,有空會在新增更多的種類,並且為顏色做最佳化,有些色彩實在不像是煙火XD

玩法

  1. 選擇煙火種類,可用鍵盤數字選擇
  2. 用滑鼠左鍵綻放你的天空

Go to page

待更新項目:

  • 將陸續增加煙火種類,並且預訂新增背景。

IEDMS 2017

設計

以交大的藍色為基底,帶出學術研討會的專業感。並藉由東門城,帶出交通大學的所在地——新竹。輪播的圖片廣告演講訊息,側邊欄顯示最新消息。

介紹

IEDMS 2017 為台灣年度的半導體專業學術研討會,由國內各大學輪流舉辦,並邀請知名國內外講者做 Short Course 講座以及發表相關議題演講,同時提供各校在學學生一個發表自己論文的機會。台上以英文簡介講解、台下亦設有海報區供參與人員交流,是為各大專院校學生出國參與世界級研討會的前哨站。

Go to site

Computer Vision Research Center

視覺:方。

  • 由方形的監視螢幕來監控
  • 由方塊構成的電腦分析
  • 以方格來辨識其中模糊的資訊
  • 將格子像素變小亦即代表解析度的提升。

色調:調整過的紅藍綠

  • 紅藍綠三原色乃光的三原色,無論是視覺或是螢幕顯示都可以由三原色來解析,是最符合電腦視覺的三個顏色,微調後使之成為網站設計時的基本顏色。
  • 暗藍色暗喻未知的背景,並利用輔色的紅色框框來顯示掃描、偵測的功能。
  • 亮藍色代表已知的事物,代表研發中心所發展的技術以及內容,都爐火純青且公開透明,歡迎各廠商來洽談。

整體網站編排

  • 將導覽列設計在下方,有如在操作 Windows 作業系統,左邊的直欄就是開始工作列。
  • 整個中心網站,就像是一部電腦。從研發中心開始,將為您帶來最先進的科技之意。
  • 另外,在版面安排的時候,會考量各區塊的重量配置,希望儘量達到視覺上的平衡,並且期望在各螢幕大小上都有最佳的瀏覽體驗。

安心政府 i-Gov

前言

很幸運的跟幾個朋友合作,參加了一秒搞懂政府網站創意競賽,並且在最後獲得了獎項。

簡介

安心政府 i-Gov 為一整合多方政府單位資訊的入口網站,網站內容以簡單的介面設計與直覺的圖示標明,讓民眾方便快速操作,滿足日常的使用需求。現今,網路空間已經成為生活資訊的取得來源,然而要從海量網頁與超連結中找到明確的資訊,其實非常困難。而民眾生活面臨的大小事,又與政府單位息息相關,所以政府單位更需要單一整合入口,便於民眾瀏覽與操作。

實作

本網站以使用者角度出發,思考、設計出符合使用趨勢與現代風格的入口網站。

JapanEx 制縣傳說

來由

始祖経県値用了Flash技術將日本依據個人的旅遊程度上色,不過輸入方式是最原始的HTML Input元素,不僅難以填寫並且缺乏直觀的地理位置概念,此外Flash早已被各大瀏覽器給放棄使用。我第一次知道這個遊戲是在IG貼文上看到,發現是這個Android App,但無奈我用的是iPhone不能玩,於是心血來潮用SVG自己做一個。

設計

先在Illustrator把日本的圖形畫好之後,每個形狀會帶入圖層名稱作為其ID的標籤,於是就可以在HTML裡被使用。多國語言有搭配Vue.js的Template做樣板,動態載入翻譯文字。

至於計分數的方法,考量到分享的用途,又不想大費周章使用資料庫,於是就索性全部塞在網址裡了XD 缺點就是網址變太長,有點醜就是了。

玩法

  1. 按一下曾到訪過的地區,選擇符合的選項,朝向把47個都道府縣都收集滿的等級235吧!
  2. 可以分享到Facebook上,或者自行保存下來,還可以增加客製化的簽名檔喔。

2018.09.18 更新:

  1. 新增英文版

2018.05.30 更新:

  1. 縣名更正
  2. 所屬地區修正

其他地區版本

感謝熱心的網友們,把日本以外的地區完成,讓我們一起來製作專屬於自己的地圖吧!

台灣:https://travel.tonypai.com.tw/
香港:http://www.thelittleprince.hk/hongkong/

Solar System

1969年阿姆斯壯搭乘美國阿波羅11號登陸月球,現在,你可以透過手機裡的瀏覽器,前往太陽系的每一個角落。針對地球,甚至看得到燈火通明的夜晚!我們不必成為太空人,就能上太空看地球。

設計

利用了開學前的寒假,全力投入的結晶,研究Three.js的物體包覆,以及Camera 的使用,搭配Raycaster已獲取滑鼠在3D視圖中的座標向量所指到的目標等。資料方面則收集了來自NASA官網的行星資訊,從Planet Pixel Emporium下載到大量高品質的地圖素材等,練習使用Require.js,另外由於圖檔較大,在預載之後用到了Microcache.js來做緩存,並且自行寫了函式僅在當下星球使用高畫質圖檔,以減緩瀏覽器渲染的負擔,使畫面更為流暢。

在固定行星上,會將其公轉軸拉至水平面,才不會有畫面歪斜的問題,可以確保最好的星球追蹤品質。

Play Ground

點擊星球,就能夠飛往該行星,以當地視角,一覽不同的宇宙風光,顛覆你對世界的想像。如果太遠或者太小,亦可以透過左側的導覽列,選擇想要前往的星球。


預計更新

  • 將陸續新增各個行星的資訊頁面,以提供更多精彩的行星故事。
  • 多國語言

Taiwan Bike Map

前言

台灣近年來風行租借單車的服務,但是有礙於北部跟南部使用不同的租借系統,缺乏一個統一的入口可以查詢租借地點以及查看車位狀況,於是便動手寫了一個,結合Google Map API的定位系統,搭配後端使用CodeIgniter框架,以及到Open Data抓取腳踏車輛的地點座標等相關資料,並且為了使標記看起來不至於太擁擠,用了MarkerClusterer.js來做統整,可一目瞭然租借點的分佈。

實作

點擊腳踏車站點,可看剩餘車位以及可借車數。用手機可以查看即時的現在地,以方便參考相對位置。地圖資訊每分鐘更新一次。

Go to page

涵蓋範圍

Youbike

  • 台北市
  • 新北市
  • 桃園市
  • 新竹市
  • 苗栗縣
  • 台中市
  • 彰化縣
  • 屏東縣

T-Bike

  • 台南市

CityBike

  • 高雄市