聚會時間公告: 因應COSCUP 2011, Kalug 8月份休會一次

九月 1, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» Laravel 4.2 繁體中文文件完整上線

Laravel PHP Framework

Laravel 是目前最火紅的 PHP Framework,但是對於第一次接觸 Framework 的使用者,安裝或學習方面一定會遇到重重困難,而為了降低學習門檻,網路上集結很多好朋友一起加入翻譯,經過了半年時間,快速的完成 4.2 版本的翻譯文件,雖然 4.3 版本在年底即將推出。這次要好好感謝 Facebook Laravel Taiwan 群組,透過台北的小聚會來定期 review 及分配翻譯項目,才可以在這麼短的時間完成翻譯內容,果然團結力量大。目前線上內容已經翻譯完成,但是還需要網路上各位大大來潤稿,Laravel TW 的 Github 在這裡,若要參與翻譯,請直接看 Docs Repo,有人常常問我,不會 Git 可以幫忙嗎?答案是當然可以阿,可以直接將介面切換到瀏覽模式,找到底下符號,按下編輯,修改完成,拉到底下按下送出就可以了喔

laravel_github

最後附上 Laravel 台灣官網,還沒嘗試過 Laravel 可以直接先看中文文件。

八月 18, 2014
» export unsigned apk

去年 Android SDK export unsigned apk package 方法改了, 改成
jarsigner -verbose -keystore ~/.android/debug.keystore CV.webview.apk androiddebugkey

Keystore password: android

The post export unsigned apk appeared first on Kevinwatt's Blog.

八月 12, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» Laravel 不同開發環境設定

Laravel PHP Framework

Laravel 本來預設的 Environment Configuration 是透過 Domain Name 來區分,程式碼 bootstrap/start.php 如下

<?php
$env = $app->detectEnvironment(array(
    'local' => array('your-machine-name'),
));

我們可以根據上述程式碼產生不同的開發環境,像是 develop, production, staging… 等,根據不同的 Domain 給予不同的環境設定檔。但是根據使用 Domain Name 來區分各種不同的環境換產生兩種問題

  • 如果想單一 Domain 跑多種環境?
  • 多個 Domain 增加 Nginx 或 Apache 的設定檔

老實講用 Domain 來分類蠻不方便的,如果突然想要在同一個 Domain 使用不同的環境設定,又要改 Domain mapping。所以 Laravel 也不是強制要使用這方法,我們可以透過增加 environment.php 來決定目前專案跑哪一種環境設定,該程式碼只有一行

<?php

return "production";
/* End of bootstrap/environment.php */

那當然我們也要將 detectEnvironment 改成

$env = $app->detectEnvironment(function() {

    // Defined in the server configuration
    if ( isset( $_SERVER['APP_ENVIRONMENT'] ) ) {
        return $_SERVER['APP_ENVIRONMENT'];

    // Look for ./environment.php
    } elseif ( file_exists( __DIR__ . '/environment.php' ) ) {
        return include __DIR__ . '/environment.php';

    // set default configuration
    } else {
        return 'local';
    }

});

Apaceh 可以直接在設定檔內定義變數如下,Laravel 可以透過 $_SERVER['APP_ENVIRONMENT'] 取環境變數。如果沒有設定 Apache 變數,則讀取 bootstrap/environment.php,最後才會讀取預設值。

SetEnv APP_ENVIRONMENT development

八月 7, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» 推薦 Sublime Text UI Theme Spacegray

Sublime_Text_Logo

不管在 Windows 或 Linux 環境,我都是使用 Sublime Text 編輯器,推薦這套編輯器的原因無非就是有強大的 Plugin 套件,這次來推薦撰寫程式碼的 UI Theme,好的 UI Theme 可以讓程式設計師的眼睛感覺到很舒服,Spacegray UI ThemeRGBA.tw 網站管理者 Even Wu 推薦。安裝方式很簡單 Ctrl + Shift + p 叫出命令列視窗,找到 Install Packages 後,搜尋 Theme - Spacegray

sublime_1

上面是安裝完成後,把底下設定加入到 User Settings (Sublime Text -> Preferences -> Settings - User)

"color_scheme": "Packages/Theme - Spacegray/base16-eighties.dark.tmTheme",
"spacegray_sidebar_font_xlarge": true,
"spacegray_sidebar_tree_xlarge": true,
"spacegray_tabs_auto_width": true,
"spacegray_tabs_font_xlarge": true,
"spacegray_tabs_xlarge": true,
"theme": "Spacegray.sublime-theme",

重新打開編輯器,就可以看到新的樣貌,左邊 sidebar 的字體及寬度整個變大,眼睛就不用這麼吃力了。

七月 24, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» 升級 PHP Facebook SDK 到 4.0.x 版本

CodeIgniter

最近幫公司建立 Staging 環境,申請了新的 FB App 來,用原本 Facebook v3.2.3 SDK 發現已經不能 work 了,去翻了 Facebook Platform Changelog,看到今年 4 月 30 號以後申請的 App 會強制走 v2.0 Auth 機制,所以原本用 php sdk 3.2.3 版本的話,完全無法呼叫 Auth 2.0 API,導致整個網站爛掉,當然線上的網站是不會隨意換 App ID 及 secret,免得怎麼爆掉的都不知道。這次來教學在 CodeIgniter 轉換 PHP Facebook SDK,可以直接參考官方 4.0.0 的教學,原本 3.2.3 版本直接下載程式碼,放到 library 目錄,直接 include 就可以取得 Facebook 個人資料,4.0.0 版本以後,請先確認系統是否升級為 PHP 5.4 版本以上,並且支援 Composer 安裝,當然如果不用 Composer 也可以,只是要 include 很多檔案,真的比較麻煩。

先在根目錄建立 composer.json 內容填入

{
  "require" : {
    "facebook/php-sdk-v4" : "4.0.*"
  }
}

接著執行 composer install,系統會自動建立 vendor 目錄。在 application/libraries 建立 lib_login.php 檔案,並且寫入底下程式碼

<?php  if (! defined('BASEPATH')) exit('No direct script access allowed');

/**
* Name: Facebook Login Library
*
* Author: appleboy
*
*/

require 'vendor/autoload.php';

use Facebook\FacebookSession;
use Facebook\FacebookRequest;
use Facebook\GraphUser;
use Facebook\FacebookRequestException;
use Facebook\FacebookRedirectLoginHelper;

class Lib_login
{
    /**
     * CodeIgniter global
     *
     * @var string
     **/
    protected $ci;

    /**
     * __construct
     *
     * @return void
     * @author Ben
     **/
    public function __construct()
    {
        $this->ci =& get_instance();
        $this->ci->load->library('session');
        $this->ci->config->load('facebook');

        if (! isset($_SESSION)) {
            session_start();
        }
    }

    public function facebook()
    {
        $facebook_default_scope = explode(',', $this->ci->config->item("facebook_default_scope"));
        $facebook_app_id = $this->ci->config->item("facebook_app_id");
        $facebook_api_secret = $this->ci->config->item("facebook_api_secret");

        // init app with app id and secret
        FacebookSession::setDefaultApplication($facebook_app_id, $facebook_api_secret);

        // login helper with redirect_uri
        $helper = new FacebookRedirectLoginHelper(site_url('login/facebook'));
        // see if a existing session exists
        if (isset($_SESSION) && isset($_SESSION['fb_token'])) {
            // create new session from saved access_token
            $session = new FacebookSession($_SESSION['fb_token']);

            // validate the access_token to make sure it's still valid
            try {
                if (!$session->validate()) {
                    $session = null;
                }
            } catch (Exception $e) {
                // catch any exceptions
                $session = null;
            }
        }

        if (!isset($session) || $session === null) {
            // no session exists

            try {
                $session = $helper->getSessionFromRedirect();
            } catch(FacebookRequestException $ex) {
                // When Facebook returns an error
                // handle this better in production code
                print_r($ex);
            } catch(Exception $ex) {
                // When validation fails or other local issues
                // handle this better in production code
                print_r($ex);
            }
        }

        // see if we have a session
        if (isset($session)) {
            // save the session
            $_SESSION['fb_token'] = $session->getToken();
            // create a session using saved token or the new one we generated at login
            $session = new FacebookSession($session->getToken());

            // graph api request for user data
            $request = new FacebookRequest($session, 'GET', '/me');
            $response = $request->execute();
            // get response
            $graphObject = $response->getGraphObject()->asArray();
            $fb_data = array(
                'me' => $graphObject,
                'loginUrl' => $helper->getLoginUrl($facebook_default_scope)
           );
            $this->ci->session->set_userdata('fb_data', $fb_data);

        } else {
            $fb_data = array(
                'me' => null,
                'loginUrl' => $helper->getLoginUrl($facebook_default_scope)
           );
            $this->ci->session->set_userdata('fb_data', $fb_data);
        }

        return $fb_data;
    }
}

最後寫簡單 controller

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Login extends CI_Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->load->library(array('session', 'lib_login'));
    }

    /**
     * facebook login
     *
     * @return void
     * @author appleboy
     **/
    public function facebook()
    {
        $fb_data = $this->lib_login->facebook();

        // check login data
        if (isset($fb_data['me'])) {
            var_dump($fb_data);
        } else {
            echo '<a href="' . $fb_data['loginUrl'] . '">Login</a>';
        }
    }
}

/* End of file login.php */
/* Location: ./application/controllers/login.php */

打開瀏覽器,直接執行 http://xxxx/login/facebook 就可以看到 Facebook 登入連結。所以程式碼都放在 Githubcodeigniter-facebook-php-sdk-v4,歡迎取用。

七月 20, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» Automating your workflow with Gulp.js

gulp

今年 2014 COSCUP 在 7/19,20 中研院舉辦,由於 JSDC 今年比往年還要晚半年舉辦,所以本來想投在 JSDC 的議程,就先拿到投到 COSCUP 議程。去年 JSDC 講了 Javascript command line tool GruntJS 介紹,講完經過半年,Gulp.js 就出來了,我馬上跳過去嘗試,用過之後,就像變了心的女朋友,回不來了,底下是 Gulp.js Slides。

Automating your workflow with Gulp.js from Bo-Yi Wu

最後提到 Slush.js 這套 streaming scaffolding system,我寫了 html5 template engine generator,產生最簡單的開發環境以及 Gulp.js 設定檔,大家可以透過底下安裝嘗試:

$ npm install -g slush bower
$ npm install -g slush-html5-template

產生專案檔案

$ slush html5-template

這套 Slush html5 generator 程式檔來自 html5-template-engine

七月 4, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» 在 Debian 安裝 Percona Xtradb Cluster 5.5.34 注意事項

percona

最近幫公司安裝新的三台機器,全部上 Debian 7.5 Server 版本,統一安裝 Percona Xtradb Cluster 最新版本 5.5.37。設定完第一台 Node,並且透過底下指令 boot up 成第一台 PXC。

$ /etc/init.d/mysql bootstrap-pxc

後續第二台要啟動跟第一台進行 SST,寫到一半直接噴底下錯誤訊息

WSREP_SST: [ERROR] Cleanup after exit with status:32 (20140702 10:57:28.004) WSREP_SST: [INFO] Removing the sst_in_progress file (20140702 10:57:28.006) 140702 10:57:28 [ERROR] WSREP: Process completed with error: wsrep_sst_xtrabackup –role ‘joiner’ –address ’192.168.1.101′ –auth ‘xxxxx:xxxxxx’ –datadir ‘/var/lib/mysql/’ –defaults-file ‘/etc/mysql/my.cnf’ –parent ’16042′: 32 (Broken pipe) 140702 10:57:28 [ERROR] WSREP: Failed to read uuid:seqno from joiner script. 140702 10:57:28 [ERROR] WSREP: SST failed: 32 (Broken pipe)

MySQL Performance Blog 找到一篇 5.5.34 Release Note,裡面提到在 5.5.34 版本以後,請使用 xtrabackup-v2 這是之前的 xtrabackup 重新命名過來的。如果重新啟動,還是持續出現此問題的話,請將系統的 MySQL Data 目錄清空,重新跑 SST 拉資料。

$ rm -rf /var/lib/mysql/* $ /etc/init.d/mysql restart

基本上這樣就可以了,另外 MySQL 裝好時,預設都沒有開啟任何 Log 紀錄,請務必將 Log 打開,不然怎麼 Debug,底下附上 Debian 的 my.cnf 設定

innodb_log_file_size = 64M
server-id               = 2
log_bin                 = /var/log/mysql/mysql-bin.log
log_error                      = /var/log/mysql/mysql-error.log
log_queries_not_using_indexes  = 1
slow_query_log                 = 1
slow_query_log_file            = /var/log/mysql/mysql-slow.log
long_query_time                = 1
default_storage_engine=InnoDB
binlog_format=ROW
log_slave_updates

另外 /etc/mysql/conf.d/wsrep.cnf

[MYSQLD]
wsrep_provider=/usr/lib/galera2/libgalera_smm.so
wsrep_cluster_address=gcomm://192.168.1.100,192.168.1.102
wsrep_sst_auth=xxxxx:xxxxx
wsrep_provider_options="gcache.size=2G"
wsrep_cluster_name=Percona
wsrep_sst_method=xtrabackup-v2
wsrep_node_name=db_02
wsrep_slave_threads=4
log_slave_updates
innodb_locks_unsafe_for_binlog=1
innodb_autoinc_lock_mode=2

注意 wsrep_sst_method 務必使用 xtrabackup-v2,如果是 CentOS 系統無此 xtrabackup-v2 指令時,請透過 ln 指令 Link 過去即可。結論就是沒事別亂升級系統,另外第二台要啟動進行 SST 時,可以打開看 innobackupex.backup.log 內是否有錯誤訊息,後續 Node 無法啟動的原因也會紀錄在此。

七月 1, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» 在 Ubuntu 建置 OpenWrt 編譯環境

openwrt-logo

紀錄一下如何在用 VirtualBox 架設 Ubuntu OpenWrt 編譯環境,請記住不要下載 Ubuntu Server Disk 來安裝,會遇到很多奇怪的問題,為了避免編譯出錯,請選擇 Ubuntu 12.04 Desktop 版本,安裝時空間請盡量調大,反正 VirtualBox 也不會吃掉這麼多空間,用多少吃多少。Ubuntu 安裝完成後,請先安裝 openssh server 套件。完成後透過 VirtualBox Network 開啟 22 port forwarding。

# 有 aptitude 指令
$ aptitude -y install openssh-server
# 無 aptitude 指令
$ apt-get -y install openssh-server

由於是安裝桌面版本,所以一開始就會直接打開 lightdm 服務,請透過之前寫的文章 Ubuntu 停止使用 GUI 介面 12.04 LTS 來把桌面停用,這樣開機就直接進去 Text mode 了,避免浪費記憶體在桌面。最後補上相依性套件安裝

$ aptitude -y install build-essential bison flex gettext g++ help2man help2man zlib1g-dev libssl-dev gawk unzip

如果編譯過程有看到 script 檔編譯不過,可能就要換 Bash 環境編譯,請先備份 /bin/sh

$ cp -r /bin/sh /bin/sh2
$ ln -sf /bin/bash /bin/sh

完整的 GCC 套件相依性安裝可以直接看 Github 上面的安裝紀錄

六月 25, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» Ngnix 搭配 PHP-FPM 噴 php5-fpm.sock failed (13: Permission denied)

nginx-logo

Nginx 搭配 PHP-FPM 已經是架設 PHP 伺服器基本入門款了,這次升級 CentOS 機器完後,發現 Log 一直噴出底下訊息

nginx error connect to php5-fpm.sock failed (13: Permission denied)

透過 Stackoverflow 查到這篇解答 nginx error connect to php5-fpm.sock failed (13: Permission denied),裡面提到兩種作法,其中一解法是直接修改 /var/run/php5-fpm.sock 為 666,讓其他使用者可以直接存取此檔案,但是此作法在下次重新開機後一樣會出現同問題,最終解法請修改 /etc/php-fpm.d/www.conf 如果是搭配 Nginx 請使用底下設定

user = nginx
group = nginx
; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server. Many
; BSD-derived systems allow connections regardless of permissions.
; Default Values: user and group are set as the running user
;                 mode is set to 0666
listen.owner = nginx
listen.group = nginx
listen.mode = 0666

六月 17, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» Linode 推出每月 10 美金方案

linode_logo_gray

Linode 慶祝 11 週年慶,推出每月只要 10 美金的 VPS 方案,其實這方案就是原本最低的 Linode 2GB 直接打對折啦。流量每月 2TB,記憶體 1G,24GB SSD 硬碟空間,對外頻寬到 125 Mbps,總對外骨幹還是維持在 40 Gbps。重點是 Linode 現在可以用小時付費,但是每個月只要 10 美金,其實真的很便宜,草創時期用 Linode 真的是最好的方案,看來 DigitalOcean 的出現,這兩年讓 Linode 成長不少,也代表的以前的 Linode 賺很大 XD,補上現在的方案表

Plans and Pricing - Linode

六月 12, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» 用 Google PageSpeed Insights 計算 Desktop 或 Mobile 網站分數

new-google-logo-knockoff

相信工程師在調整網站效能一定會使用 Google PageSpeed Insights 來得到測試效能數據報表,但是這僅限於使用 Chrome 或 Firefox 瀏覽器。每次跑 PageSpeed 時候,Chrome 就會出現哀號,並且吃下許多記憶體。有沒有 command line 可以直接用 Google PageSpeed Insights 測試 Desktop 或 Mobile 的分數。Google 工程師 @addyosmani 寫了一套 PageSpeed Insights for Node – with reporting 稱作 PSI,可以直接透過 Node 來產生基本 report,這 report 真的算很基本,跟 Chrome 的 extension 跑起來的 report 是不一樣的。這工具可以用來紀錄每次 deploy 網站時的一些數據變化。底下附上 Google 網站報告

google_psi_report

此工具是透過 gpagespeed 完成,如果你有用 GruntJS 可以直接參考 grunt-pagespeed。使用 psi command line 非常簡單,透過底下指令就可以正確產生出上面報表

$ npm install -g psi
$ psi http://www.google.com

如果有用 GulpJS 可以寫成兩個 Task 來跑

var gulp = require('gulp');
var psi = require('psi');
var site = 'http://www.html5rocks.com';
var key = '';

// Please feel free to use the `nokey` option to try out PageSpeed
// Insights as part of your build process. For more frequent use,
// we recommend registering for your own API key. For more info:
// https://developers.google.com/speed/docs/insights/v1/getting_started

gulp.task('mobile', function (cb) {
  psi({
    // key: key
    nokey: 'true',
    url: site,
    strategy: 'mobile'
  }, cb);
});

gulp.task('desktop', function (cb) {
  psi({
    nokey: 'true',
    // key: key,
    url: site,
    strategy: 'desktop'
  }, cb);
});

上面程式碼來自 psi-gulp-sample,psi 有提供 callback function

function(err, data){
  console.log(data.score);
  console.log(data.responseCode);
  console.log(data.id );
}

上面的 Task 可以改成

gulp.task('desktop', function (cb) {
  psi({
    nokey: 'true',
    // key: key,
    url: site,
    strategy: 'desktop'
  }, function(err, data){
    console.log(data.score);
    console.log(data.responseCode);
    console.log(data.id );
    cb();
  });
});

用此工具來紀錄每次網站更新後的測試數據,對於調整 Web Performance 來說是一個可以參考的指標。如果 API 使用量很大,請記得申請 Google API Key。

六月 11, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» 安全使用 JavaScript Global Variables

剛開始學習 JavaScript 時候,一定會大量使用 Global Variables。但是使用 Global Variables 的同時,請務必使用 var 宣告,而不是直接使用阿,否則會常常遇到 ReferenceError 的錯誤。

function addToBlockList (item) {
  block_List.push(item);
}

addToBlockList ("add 127.0.0.1");

執行後你可以發現 console 噴出 Uncaught ReferenceError: block_List is not defined,加上一個判斷試試看。程式碼改成底下

function addToBlockList (item) {
  if (block_list) {
    block_List.push(item);
  }
}

addToBlockList ("add 127.0.0.1");

會噴出一樣的錯誤訊息,原因也是 block_List is not defined,最後將程式碼換成底下

function addToBlockList (item) {
  if (window.block_list) {
    window.block_List.push(item);
  }
}

addToBlockList ("add 127.0.0.1");

就可以正常跑了,也不會出現任何錯誤訊息,建議大家不要寫這樣的程式碼,能夠少用 window.xxxx 這種全域變數就盡量少用,不要任意宣告或修改 window 全域變數,上面程式碼可以換成底下會更好

(function() {
  var block_list = [];
  var addToBlockList = function (item) {
    if (block_list) {
      block_list.push(item);
    }
  };
    
  addToBlockList("127.0.0.1");
  console.log(block_list);
  
})();

這樣可以避免渲染 window Global Variable。如果你是用 CoffeeScript 來寫,可以寫成底下

(->
  block_list = []
  addToBlockList = (item) ->
    block_list.push item  if block_list
    return

  return
)()

但是我建議可以使用 block_list? 寫法

(->
  block_list = []
  addToBlockList = (item) ->
    block_List?.push item
    return

  return
)()

轉成的 JavaScript 會是

(function() {
  var addToBlockList, block_list;
  block_list = [];
  addToBlockList = function(item) {
    if (typeof block_List !== "undefined" && block_List !== null) {
      block_List.push(item);
    }
  };
})();

五月 26, 2014

Yuren's Info Area
yurinfore
Yuren's Info Area is about »

tag cloud

» 搬家了

改到 blog.yurenju.info 去,文章量太多了沒搬過去,新文章請那邊看。

五月 25, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» 認識現今 Google 搜尋引擎

感謝 @Ly Cheng 針對第三點補充

new-google-logo-knockoff

1995 年 JavaScript 第1版出現,到了 1998 年 Google 推出第一代搜尋引擎,當時的 Google 根本不用在乎網頁如何使用 CSS 或 JavaScript,而當時的網頁也顯少使用 JavaScript 及 CSS。轉眼間到現在 2014 年,如今現在的 Web,已經離不開 JavaScript 及 CSS 了,而目前 SPA (Single Page Application) 的流行,也造成 Google 搜尋引擎讀取資料的困擾,所以 Google 團隊目前也正在朝這方向努力邁進。

傳統的網頁,Google 根本不需要在乎 JavaScript 或 CSS,直接從 Http Response 拿到 Body 內的資料進行分析,然而 JavaScript 的盛行,已經改變了此作法,Google 再也不能從 Body 內準確的拿到資料,原因就是現今的網頁,都已經由 JavaScript 透過 AJAX 方式跟後端存取資料,這樣對於 Google 搜尋引擎是非常不好的結果。

Google 為了改善此問題,現階段也開始著手改善爬蟲,讓爬蟲可以正確執行 JavaScript,當然也要根據 Client 端是否有打開 JavaScript。由於現在大多數的網站已經漸漸變成 SPA 方式,看到如今盛行的 JavaScript Framework 像是 Backbone.jsAngularJS 等。Google Webmaster 也開始正視這問題。

為了能讓 Google 可以正確取得網頁資料,底下有些資訊可以提供給開發者,可以對 Google 爬蟲更友善

  • 請不要將 JavaScript 或 CSS 寫入 robots.txt,這樣只是讓 Google 無法正確拿到 JavaScript 檔案
  • 注意 Server 不要拒絕 crawl requests,也就是要有能力承受 crawl 讀取 XD
  • 讓網頁可以支援舊版瀏覽器或尚未實做 JavaScript 的搜尋引擎,一樣可以正確取得網頁內容
  • JavaScript 寫的太複雜,導致 Google crawl 無法正確執行
  • 使用 JavaScript 移除 content 遠大於新增 content,避免影響 Google 做 index

現在 Google Webmaster Tools 也著手進行後台開發,讓開發者可以正確看到 Google crawl 行為。

此篇文章參考 Understanding web pages betterIt took Google’s Web crawlers 15 years to come to terms with JavaScript

五月 23, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» Gulp.js 工具包

gulp

本篇來整理關於 Gulp.js 的一些 GUI 工具,對於不瞭解 Gulp.js 可以參考之前我寫的 The streaming build system Gulp,會紀錄這篇最主要是看到有人在 Github 發了這篇 Is there any GUI tool for Gulp? 而 Gulp.js 底層作者 @robrich 跳出來列出了很多工具,整理如下

如果開發環境為 Apple Mac 你可以直接裝 @sindresorhus 寫的 gulp-app,或者是 g0v 作者 clkao 開發的 gullet。看大家喜歡哪些工具,請自行安裝。我比較推薦 Gulp Dev Tools for Chrome,可以在瀏覽器上直接執行 Gulp 所有 Task,如果之前有玩過 Grunt.js 大家應該都知道也有 Grunt Devtools

有使用 CoffeeScript 寫 Gulp.js 請務必在 gulpfile.coffee 加上

module.exports = gulp

接著修改 gulpfile.js 如下

require('coffee-script/register');
var gulp = require('./gulpfile.coffee');
module.exports = gulp;

程式碼可以直接參考 html5-template-engine

五月 9, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» 免費下載 Percona MySQL eBooks

percona

玩 MySQL 的一定知道 Percona,這次 Percona MySQL 推出免費電子書,電子書內容是從 MySQLPerformanceBlog 裡面精心挑選文章收錄,文章內容也幾乎都是 MySQL 專家寫出來的,電子書內容包含了MySQL server, Percona Server, Percona XtraDB Cluster, MySQL performance, and MySQL troubleshooting,所有的電子書都是免費下載。

更多主題可以直接參考 MySQL eBooks

五月 8, 2014
» 自己的無線電自己修 – UV-5R

Bafong UV-5R Tower

去年為了登山用途,連續團購了好幾打中國製造的便宜業餘無線電 – 福建省南安市寶鋒電子有限公司的 UV-5R.英文名稱是 Baofeng,不過由於商標的權力衝突關係,目前已經逐漸改成 Pofung. 此款支援 UHF/VHF 雙頻守聽、 FM 電台功能,這款無線電改版多次,市面上有多種型號。中國售價大多不超過一千台幣,進口需額外負擔運費與關稅等,仍然相當便宜,因為實在太便宜了,深受登山客、業餘玩家喜愛,就連烏克蘭的民間武裝抗議人士也愛用。(圖為頓內次克政府建築外的親俄士兵)

A pro-Russian protester mans a barricade outside a government building in Donetsk.

A pro-Russian protester mans a barricade outside a government building in Donetsk. Konstantin Chernichkin / Reuters

韌體與硬體

我看過許多種不同的版本,型號有 UV-5R / UV-5RA / UV-5RPlus / UV-5Ra+ / UV5RB / UV5RE 等等千奇百怪針對不同市場的延生版。硬體基本上大同小異,改版主要是外型設計與韌體的改善,加強操作的便利性。

若想知道你所持有的手機是哪一種版本,可以按著 3 開機看韌體版本、按下 6 開機看硬體版本。你若發現韌體版本是 BFB297,那代表是新版的產品,真正的韌體版本資訊無法透過開機訊息查看,必須另外透過軟體檢查。

例如我手上的產品,早期購買版本

  •    BFB229
  •    201002 VER04

後期購入版本則是

  •  BFB297 (實際用軟體查看是 BFB307)
  •  130505N.

韌體功能

基本的韌體功能有

  • VHF/UHF 雙頻無線電對講機. 雙顯示/雙待機/跨段收發
  • 省電功能
  • 語音導引
  • 手電筒功能
  • 鍵盤鎖功能
  • 語音保密裝置
  • 點陣雙排顯示
  • 128組記憶頻道
  • 帶收音機功能
  • VOX聲控發射功能