<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8234469307359212140</id><updated>2024-11-01T19:01:22.992+08:00</updated><category term="Python"/><category term="Mac"/><category term="Spring"/><category term="GAE"/><category term="Eclipse"/><category term="iOS"/><category term="Raspberry Pi"/><category term="Tornado"/><category term="Webapp2"/><category term="iOS7"/><category term="Arch Linux"/><category term="Google"/><category term="AWS"/><category term="RabbitMQ"/><category term="Play Framework"/><category term="Vim"/><category term="Java Web"/><category term="Web"/><category term="Django"/><category term="Android"/><category term="Docker"/><category term="JavaScript"/><category term="Linux"/><category term="Sublime Text"/><category term="CKeditor"/><category term="Heroku"/><category term="Nexus 7"/><category term="Nginx"/><category term="PHP"/><category term="Swift"/><category term="Dropbox"/><category term="Hubot"/><category term="Chat"/><category term="PostgreSQL"/><category term="Vagrant"/><category term="Webpack"/><category term="AngularJS"/><category term="CSS"/><category term="Cassandra"/><category term="Chrome"/><category term="Gitlab"/><category term="Java"/><category term="Jekyll"/><category term="React"/><category term="SCSS"/><category term="SSH"/><category term="Win7"/><title type='text'>ALL OF ME</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://hatemegalaxy.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>242</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-7373239741746623949</id><published>2017-12-16T14:27:00.001+08:00</published><updated>2017-12-16T14:27:16.690+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><category scheme="http://www.blogger.com/atom/ns#" term="Swift"/><title type='text'>iOS 開發教學 - 暸解 CALayer 2/2 ( iOS Development - An introduction to CALayer Part 2 )</title><content type='html'>在&lt;a target=&quot;_blank&quot; href=&quot;https://hatemegalaxy.blogspot.com/2017/12/ios-calayer-ios-development.html&quot;&gt;&lt;b&gt;上一篇文章&lt;/b&gt;&lt;/a&gt;中提到了&lt;b&gt;CALayer&lt;/b&gt;，也在文章中針對了 Layer 的定義與基本用法做了簡單的示範，但是其實 Layer 還有許多更進階的用法。因此，我想透過此篇文章繼續介紹 Layer 的其他應用，暸解本篇內容對於之後對於設定、控制 View 能更得心應手。最後，本篇文章是基於 &lt;b&gt;Swift 4&lt;/b&gt; 的環境下進行。
&lt;!--
(&amp;nbsp;If you want to read this article in English, you can visit &lt;a target=&quot;_blank&quot; href=&quot;&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;here&lt;/span&gt;&lt;/a&gt;&amp;nbsp;)
--&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br/&gt;
&lt;h1&gt;&lt;b&gt;Layer 可以有 Sub Layer&lt;/b&gt;&lt;/h1&gt;
如同 View 可以增加 Sub View 一樣，Layer 也一樣可以擁有多個 &lt;b&gt;Sub Layer&lt;/b&gt;，這代表了我們可以利用這些 Sub Layer 呈現一些比較複雜的視覺效果。我們先來撰寫一個簡單的範例來感受一下 Sub Layer，範例如下：
&lt;pre&gt;&lt;code class=&quot;swift round5px&quot;&gt;import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 新增 View 並設定長寬為 200 x 200
        let myView = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
        // 設定 View 的 Layer 背景顏色
        myView.layer.backgroundColor = UIColor.yellow.cgColor
        // 置中 View
        myView.center = CGPoint(x: self.view.center.x, y: self.view.center.y)
        // 將 View 加入畫面中
        self.view.addSubview(myView)

        // 新增一個額外的 CALayer
        let layer = CALayer()
        // 設定 Layer 長寬為 120 x 120
        layer.bounds = CGRect(x: 0, y: 0, width: 120, height: 120)
        // 設定 Layer 背景顏色
        layer.backgroundColor = UIColor.blue.cgColor
        // 置中 Layer
        layer.position = CGPoint(x: myView.bounds.midX, y: myView.bounds.midY)
        // 將 Layer 設定為 View 的 Sub Layer
        myView.layer.addSublayer(layer)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}
&lt;/code&gt;&lt;/pre&gt;
完成後啟動 iOS 模擬器，畫面應該看起來如下圖：
&lt;br/&gt;&lt;br/&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgicaakQEhUsEU_jPvyjk1kJv5DrKDpQmSOdlXM4vb7K7PilBVjWoNobm0rG5BG8bX0K8i0YrsBbeVlplBKGBdITaqzimWUFaLl7GQjRbDVzK2nwrElBpaLai1k7llKWMm-CsSOG2YJ4kXx/s1600/calayer-1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgicaakQEhUsEU_jPvyjk1kJv5DrKDpQmSOdlXM4vb7K7PilBVjWoNobm0rG5BG8bX0K8i0YrsBbeVlplBKGBdITaqzimWUFaLl7GQjRbDVzK2nwrElBpaLai1k7llKWMm-CsSOG2YJ4kXx/s400/calayer-1.png&quot; width=&quot;225&quot; height=&quot;400&quot; data-original-width=&quot;447&quot; data-original-height=&quot;794&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br/&gt;&lt;br/&gt;
沒錯，看起來就像一般的圖層重疊起來，那是因為在這個範例中我只簡單地增加一個 Sub Layer 並只設定背景顏色，這個範例只是讓你暸解 Sub Layer 的存在。一旦了解後，我們可以進一步深入 Layer 強大的功能：結合 &lt;b&gt;CABasicAnimation&lt;/b&gt;。
&lt;br/&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;hr/&gt;
&lt;h1&gt;替 Layer 增加動畫&lt;/h1&gt;
接下來我們將要讓 Layer 活起來。除了之前提到的屬性可以設定外，我們還可以將 Layer 結合 &lt;b&gt;CABasicAnimation&lt;/b&gt;。在這篇文章中，我們還是專注在 Layer 上，你目前只需要知道 CABasicAnimation 是一個產生動畫效果的物件。而 Layer 要如何使用它呢？以下的範例，我將會替 Layer 加入淡入淡出的效果，並重複 5 次。程式碼如下：
&lt;pre&gt;&lt;code class=&quot;swift round5px&quot;&gt;import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 新增 View 並設定長寬為 200 x 200
        let myView = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
        // 設定 View 的 Layer 背景顏色
        myView.layer.backgroundColor = UIColor.yellow.cgColor
        // 置中 View
        myView.center = CGPoint(x: self.view.center.x, y: self.view.center.y)
        // 將 View 加入畫面中
        self.view.addSubview(myView)

        // 新增 CABasicAnimation 物件，並設定 Opacity (透明度)屬性將會被操控
        let animation = CABasicAnimation(keyPath: &quot;opacity&quot;)
        // 設定 Opacity 起始值
        animation.fromValue = 0
        // 設定 Opacity 最終值
        animation.toValue = 1
        // 設定動畫所需時間
        animation.duration = 3
        // 設定重複次數
        animation.repeatCount = 5
        animation.autoreverses = true
        // 將 CABasicAnimation 加入至 View 的 Layer 中
        myView.layer.add(animation, forKey: &quot;opacity&quot;)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}
&lt;/code&gt;&lt;/pre&gt;
若按照上面的程式執行，你會看到淡入淡出的動畫效果。這邊就不將畫面貼上來了。透過上面的例子，你可以發現 Layer 加上 Sub Layer 並搭配 CABasicAnimation 可以完成更多特殊、強大的視覺效果。在接下來的文章中，我們將開始介紹更多元件，也會陸續提到 Layer 與 CABasicAnimation 相關的資料。
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Environment :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;macOS&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;Swift 4&lt;br /&gt;
&lt;br/&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/7373239741746623949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/7373239741746623949'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/12/ios-calayer-22-ios-development.html' title='iOS 開發教學 - 暸解 CALayer 2/2 ( iOS Development - An introduction to CALayer Part 2 )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgicaakQEhUsEU_jPvyjk1kJv5DrKDpQmSOdlXM4vb7K7PilBVjWoNobm0rG5BG8bX0K8i0YrsBbeVlplBKGBdITaqzimWUFaLl7GQjRbDVzK2nwrElBpaLai1k7llKWMm-CsSOG2YJ4kXx/s72-c/calayer-1.png" height="72" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-4475575137522176236</id><published>2017-12-15T01:41:00.001+08:00</published><updated>2017-12-16T14:28:54.237+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><category scheme="http://www.blogger.com/atom/ns#" term="Swift"/><title type='text'>iOS 開發教學 - 暸解 CALayer 1/2 ( iOS Development - An introduction to CALayer Part 1)</title><content type='html'>我們之前利用了&lt;a target=&quot;_blank&quot; href=&quot;https://hatemegalaxy.blogspot.com/2017/12/ios-storyboard-ios-development-basic.html&quot;&gt;&lt;b&gt;兩個篇幅介紹了 Storyboard&lt;/b&gt;&lt;/a&gt;，現在可以更進一步深入 iOS 開發。在這篇文章中我想先介紹 &lt;b&gt;CALayer&lt;/b&gt;，為什麼呢？因為在 iOS 開發中常常會使用到許多不同的 &lt;b&gt;View&lt;/b&gt;，而每一個 View 都是藉由 CALayer ( 或稱 Layer ) 來處理視覺上的效果與內容，所以先認識 CALayer 會幫助之後的開發工作。最後，本篇文章是基於 &lt;b&gt;Swift 4&lt;/b&gt; 的環境下進行。
&lt;!--
(&amp;nbsp;If you want to read this article in English, you can visit &lt;a href=&quot;https://devforgalaxy.github.io/en/ios-an-introduction-to-storyboard-pt2-en.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;here&lt;/span&gt;&lt;/a&gt;&amp;nbsp;)
--&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br/&gt;
&lt;h1&gt;&lt;b&gt;什麼是 CALayer&lt;/b&gt;&lt;/h1&gt;
根據官方的文件，我們從字面上可以了解 &lt;b&gt;CALayer&lt;/b&gt; ( 或稱 &lt;b&gt;Layer&lt;/b&gt; ) 是一個物件，它專門負責管理圖像內容，而且你可以透過它來呈現特殊的視覺效果。換句話說，Layer 提供了比較簡單的方式滿足開發者對於 Graphics 相關的需求，所以開發者不需要自己去操作底層。更白話一點來說，我們可以透過 Layer 來設定圖形內容、大小、位置或者是特殊的動畫效果等等。而 &lt;b&gt;UIView&lt;/b&gt; ( 或稱 &lt;b&gt;View&lt;/b&gt; ) 其實也只是一個包著 Layer 的物件，因此我們使用 View 的時候其實是透過 Layer 幫我們處理視覺上的效果，而其他的部分則由 View 自己來處理。所以你也可以理解成 View 表面上是負責處理所有事情，而實際上它將所有圖形、視覺上的任務轉交給 Layer 處理。
&lt;br/&gt;
&lt;br/&gt;
&lt;hr/&gt;
&lt;h1&gt;如何使用 Layer&lt;/h1&gt;
如同上一段所說，Layer 主要是負責圖像、視覺上的處理。所以，我將透過幾個簡單的例子來示範怎麼使用 Layer。首先，新增一個 Single View App，然後新增一個 View 到畫面中。首先，我們來設定背景顏色與外框顏色：
&lt;pre&gt;&lt;code class=&quot;swift round5px&quot;&gt;import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var demoView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // 設定 Layer 背景顏色
        demoView.layer.backgroundColor = UIColor.yellow.cgColor
        // 設定 Layer 邊框的寬度
        demoView.layer.borderWidth = 6.0
        // 設定 Layer 邊框的顏色
        demoView.layer.borderColor = UIColor.gray.cgColor
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}
&lt;/code&gt;&lt;/pre&gt;
若按照上面範例所做，你的畫面看起來會像這樣：
&lt;br/&gt;&lt;br/&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyuv8Ibof6hTk5dTILfr_f5g-jLqmlghE5GSX4Od12iErbAO78scAbtch3Wr_g2gvCjts_RTIIbivWwCu-BBl7YIOEeXY52EQ9OOA6oNfV5GTFMri0r4vHT0C-loGiYxhid5r2v0X-tDAI/s1600/calayer-1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyuv8Ibof6hTk5dTILfr_f5g-jLqmlghE5GSX4Od12iErbAO78scAbtch3Wr_g2gvCjts_RTIIbivWwCu-BBl7YIOEeXY52EQ9OOA6oNfV5GTFMri0r4vHT0C-loGiYxhid5r2v0X-tDAI/s400/calayer-1.png&quot; width=&quot;225&quot; height=&quot;400&quot; data-original-width=&quot;447&quot; data-original-height=&quot;794&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br/&gt;&lt;br/&gt;
接下來繼續設定 Layer 其他的屬性，我們來嘗試將 View 的邊框變成圓角的形狀：
&lt;pre&gt;&lt;code class=&quot;swift round5px&quot;&gt;import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var demoView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // 設定 Layer 背景顏色
        demoView.layer.backgroundColor = UIColor.yellow.cgColor
        // 設定 Layer 邊框的寬度
        demoView.layer.borderWidth = 6.0
        // 設定 Layer 邊框的顏色
        demoView.layer.borderColor = UIColor.gray.cgColor
        // 設定 Layer 邊框圓角的彎度
        demoView.layer.cornerRadius = 20
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}
&lt;/code&gt;&lt;/pre&gt;
加入圓角的設定後，你的畫面應該看起來像這樣：
&lt;br/&gt;&lt;br/&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqm_7R8pXle7j8dyHqP-O4E4A21yJF9l1AgubbQ6zbJAg7vw8D9SQbH5ZSUUUVGgV962Q3fOAfTQ553XlTln4vxNvEK3jCCYh9-kCUw7p7fILpWB2q02HkExabmaYSQ2E-Z6vz562RdwBy/s1600/calayer-2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqm_7R8pXle7j8dyHqP-O4E4A21yJF9l1AgubbQ6zbJAg7vw8D9SQbH5ZSUUUVGgV962Q3fOAfTQ553XlTln4vxNvEK3jCCYh9-kCUw7p7fILpWB2q02HkExabmaYSQ2E-Z6vz562RdwBy/s400/calayer-2.png&quot; width=&quot;225&quot; height=&quot;400&quot; data-original-width=&quot;447&quot; data-original-height=&quot;794&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br/&gt;&lt;br/&gt;
以上的兩個範例只是讓你稍微對 Layer 的控制有一個簡單的認識，你可以透過它設定透明度、加入圖片甚至是加上陰影。但是它的用途不僅僅如此，我們還可以利用Layer 做更多特別的效果。我將在接下來的文章中介紹更多關於 Layer 的用法，繼續閱讀 &lt;a target=&quot;_blank&quot; href=&quot;https://hatemegalaxy.blogspot.com/2017/12/ios-calayer-22-ios-development.html&quot;&gt;&lt;b&gt;iOS 開發教學 - 暸解 CALayer 2/2&lt;/b&gt;&lt;/a&gt;。
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Environment :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;macOS&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;Swift 4&lt;br /&gt;
&lt;br/&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/4475575137522176236'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/4475575137522176236'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/12/ios-calayer-ios-development.html' title='iOS 開發教學 - 暸解 CALayer 1/2 ( iOS Development - An introduction to CALayer Part 1)'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyuv8Ibof6hTk5dTILfr_f5g-jLqmlghE5GSX4Od12iErbAO78scAbtch3Wr_g2gvCjts_RTIIbivWwCu-BBl7YIOEeXY52EQ9OOA6oNfV5GTFMri0r4vHT0C-loGiYxhid5r2v0X-tDAI/s72-c/calayer-1.png" height="72" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-6967429698824084529</id><published>2017-12-11T03:00:00.001+08:00</published><updated>2017-12-12T22:32:38.093+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><category scheme="http://www.blogger.com/atom/ns#" term="Swift"/><title type='text'>iOS 開發教學 - 暸解 Storyboard 2/2 ( iOS Development - A basic introduction to Storyboard Part 2 )</title><content type='html'>在上一篇&lt;a target=&quot;_blank&quot; href=&quot;https://hatemegalaxy.blogspot.com/2017/12/ios-storyboard-ios-development-basic.html&quot;&gt;暸解 &lt;b&gt;Storyboard&lt;/b&gt;&lt;/a&gt; 的文章中，用很簡單的方式介紹了關於 Storyboard 的基礎概念， 而此篇文章將根據上一篇的內容作一些補充說明。建議從上一篇先開始閱讀，基本概念掌握後閱讀此篇較適合。最後，本篇文章是基於 &lt;b&gt;Swift 4&lt;/b&gt; 的環境下進行。(&amp;nbsp;If you want to read this article in English, you can visit &lt;a href=&quot;https://devforgalaxy.github.io/en/ios-an-introduction-to-storyboard-pt2-en.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;here&lt;/span&gt;&lt;/a&gt;&amp;nbsp;)
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br/&gt;
&lt;h1&gt;&lt;b&gt;設定 Storyboard 初始場景&lt;/b&gt;&lt;/h1&gt;
之前有提到每一個 iOS 應用程式都會擁有一個進入點 (Entry Point)，我們可以透過 Storyboard 上的箭頭來指定要使用哪一個場景 (Scene) 當作進入點，但該箭頭其實是可以被刪除的。若你不小心誤刪的話，系統會不知道進入點是哪一個造成運作不正常。這時候我們可以使用 &lt;b&gt;Attributes Inspector&lt;/b&gt; 來指定應用程式的進入點，選擇你想使用的場景然後將選項 &lt;b&gt;Is initial View Controller&lt;/b&gt; 打勾即可。操作畫面參考下圖：
&lt;br/&gt;&lt;br/&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTenHDBTvRf8j1wiVXz92EJusL_BigI9nMlpw_IYHvFLEA_WmDW7ddbM8-VnjT43jU_ZVmVp-T5kNDAhvIsP1QXW3V_eDw73xUDgoqljsBYcrt20Pno0KyzwqY1xnlnWYJgx4fImrFbVok/s1600/Screen+Shot+2017-12-11+at+2.13.56+AM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTenHDBTvRf8j1wiVXz92EJusL_BigI9nMlpw_IYHvFLEA_WmDW7ddbM8-VnjT43jU_ZVmVp-T5kNDAhvIsP1QXW3V_eDw73xUDgoqljsBYcrt20Pno0KyzwqY1xnlnWYJgx4fImrFbVok/s1600/Screen+Shot+2017-12-11+at+2.13.56+AM.png&quot; data-original-width=&quot;260&quot; data-original-height=&quot;300&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br/&gt;&lt;br/&gt;
&lt;h1&gt;設定 ViewController 的 Class&lt;/h1&gt;
在上一篇文章中，我提到了我們可以利用程式碼來設定、控制 &lt;b&gt;ViewController&lt;/b&gt;，但我們需要新增 &lt;b&gt;Swift&lt;/b&gt; 檔案 (.swift) 來達成。接下來我來一步一步示範。按照上一篇的內容，建立一個 Tabbed 應用程式之後，在專案資料夾內新增一個 Swift 檔案，選擇 &lt;b&gt;Cocoa Touch Class &lt;/b&gt;，參考下面步驟：
&lt;br/&gt;&lt;br/&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGwSTUwSGgp4udJ1oZYaDxdIyWM9mhRfdJLbGnsi5fhjxtyhYZR5OFgzNL84IKgSwST8JPuU6Y5y8cC9xr7_FsTNDOGjpfjSGOy6kZK1ce1BvuD-6DqLgLPLTunkyDfnurccmvM1Th-pnA/s1600/Screen+Shot+2017-12-11+at+2.33.16+AM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGwSTUwSGgp4udJ1oZYaDxdIyWM9mhRfdJLbGnsi5fhjxtyhYZR5OFgzNL84IKgSwST8JPuU6Y5y8cC9xr7_FsTNDOGjpfjSGOy6kZK1ce1BvuD-6DqLgLPLTunkyDfnurccmvM1Th-pnA/s640/Screen+Shot+2017-12-11+at+2.33.16+AM.png&quot; width=&quot;640&quot; height=&quot;453&quot; data-original-width=&quot;728&quot; data-original-height=&quot;515&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br/&gt;&lt;br/&gt;
然後輸入你的檔案名稱，並設定 &lt;b&gt;Subclass of&lt;/b&gt; 為 &lt;b&gt;UIViewController&lt;/b&gt;，參考下圖：
&lt;br/&gt;&lt;br/&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiASF9KnotEFqOe-_fEdYuIAbpk4Rmi7l4XtDLCOdYsVTXAdn7jiBmNAwSu-HKPvvuUVyz06mVCFX41ZuVYMb0NmwEvTJ8rTResd9LTEzukneJBgxXF2BxQwuajSYSg0K6DZNDGR7I2Ubiy/s1600/Screen+Shot+2017-12-11+at+2.34.03+AM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiASF9KnotEFqOe-_fEdYuIAbpk4Rmi7l4XtDLCOdYsVTXAdn7jiBmNAwSu-HKPvvuUVyz06mVCFX41ZuVYMb0NmwEvTJ8rTResd9LTEzukneJBgxXF2BxQwuajSYSg0K6DZNDGR7I2Ubiy/s640/Screen+Shot+2017-12-11+at+2.34.03+AM.png&quot; width=&quot;640&quot; height=&quot;457&quot; data-original-width=&quot;720&quot; data-original-height=&quot;514&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br/&gt;&lt;br/&gt;
現在我們已經成功建立了 Swift 檔案，但這個時候 Storyboard 還不知道你要透過這個檔案來控制 ViewController。因此我們必須要進一步設定它。在 Storyboard 畫面中點選你想要設定的 ViewContoller，然後在右邊的 &lt;b&gt;Identity Inspector&lt;/b&gt; 中的 Class 欄位加入你剛剛輸入的檔名。參考下圖：
&lt;br/&gt;&lt;br/&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizlhvLzU30nMp5KBb82vEQT_uWVhobOOU-QEFDMhuSYTINxMjb8qswMM9903-Fmg9a4v0f70b0mRNbRHL2IQnD_LP_6p-aJPAz32YaOxo5-BaAP9kNCcIR-3Zpt-qqSY_J70Kbg2yFUVfo/s1600/Screen+Shot+2017-12-11+at+2.48.44+AM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizlhvLzU30nMp5KBb82vEQT_uWVhobOOU-QEFDMhuSYTINxMjb8qswMM9903-Fmg9a4v0f70b0mRNbRHL2IQnD_LP_6p-aJPAz32YaOxo5-BaAP9kNCcIR-3Zpt-qqSY_J70Kbg2yFUVfo/s1600/Screen+Shot+2017-12-11+at+2.48.44+AM.png&quot; data-original-width=&quot;259&quot; data-original-height=&quot;232&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br/&gt;&lt;br/&gt;
設定完成後，你就可以在 Swift 檔案中設定、控制你剛剛選擇的 ViewController。至於要如何寫程式控制 ViewController，我們會需要好幾個篇幅來好好的介紹它，畢竟幾乎所有的場景都會需要用到它。之後在實作的文章裡，會陸續補充 Storyboard 資料。
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Environment :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;macOS&lt;br /&gt;
&lt;br/&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/6967429698824084529'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/6967429698824084529'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/12/ios-storyboard-22-ios-development-basic.html' title='iOS 開發教學 - 暸解 Storyboard 2/2 ( iOS Development - A basic introduction to Storyboard Part 2 )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTenHDBTvRf8j1wiVXz92EJusL_BigI9nMlpw_IYHvFLEA_WmDW7ddbM8-VnjT43jU_ZVmVp-T5kNDAhvIsP1QXW3V_eDw73xUDgoqljsBYcrt20Pno0KyzwqY1xnlnWYJgx4fImrFbVok/s72-c/Screen+Shot+2017-12-11+at+2.13.56+AM.png" height="72" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-3372772745315437398</id><published>2017-12-02T18:11:00.000+08:00</published><updated>2017-12-12T01:54:54.047+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><category scheme="http://www.blogger.com/atom/ns#" term="Swift"/><title type='text'>iOS 開發教學 - 暸解 Storyboard 1/2 ( iOS Development - A basic introduction to Storyboard Part 1)</title><content type='html'>為了打好 iOS 開發的基礎，我們需要先稍微暸解 &lt;b&gt;Storyboard&lt;/b&gt; 是怎麼運作的，所以我將在這篇文章中簡單介紹 Sotryboard 的運作流程以及 Storyboard 與你的程式碼 (.swift) 是怎麼連結起來的。最後，本篇文章是基於 &lt;b&gt;Swift 4&lt;/b&gt; 的環境下進行。(&amp;nbsp;If you want to read this article in English, you can visit &lt;a href=&quot;https://devforgalaxy.github.io/en/ios-an-introduction-to-storyboard-en.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;here&lt;/span&gt;&lt;/a&gt;&amp;nbsp;)
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br/&gt;
&lt;h1&gt;&lt;b&gt;Storyboard 運作流程&lt;/b&gt;&lt;/h1&gt;
Storyboard 是一個很方便的功能，但你知道當 iOS App 啟動時它是如何運作的嗎？首先，當 App 啟動時系統會先把 &lt;b&gt;Info.plist&lt;/b&gt; 的資料載入，這樣它才知道要使用哪一個 Storyboard。這時候你可以打開 Info.plist 仔細看，其中應該會有一欄為 &lt;b&gt;Main storyboard file base name&lt;/b&gt;，然後它的值為 Main。這說明了 Info.plist 告訴系統去使用檔名為 Main 的 Storyboard。如此一來，系統就會根據你的 Main.storyboard 內容，按著你的 App 設計 (劇本) 執行。
&lt;br/&gt;&lt;br/&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlRjB5lsymiqs4c5DfOi-NVPfKmggRzhGHl3oDd2IYXXjD38InCQoZmIwB1fRKxLoY6XkMmMjgQbvZcH9lLb30CITXTkqkMP31tlyAaAtS_akf2dFxhyphenhyphenD29g6d34h3ZlA6gBXpuuJXZfKO/s1600/storyboard-1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlRjB5lsymiqs4c5DfOi-NVPfKmggRzhGHl3oDd2IYXXjD38InCQoZmIwB1fRKxLoY6XkMmMjgQbvZcH9lLb30CITXTkqkMP31tlyAaAtS_akf2dFxhyphenhyphenD29g6d34h3ZlA6gBXpuuJXZfKO/s1600/storyboard-1.png&quot; data-original-width=&quot;520&quot; data-original-height=&quot;102&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br/&gt;&lt;br/&gt;
為了進一步認識 Storyboard，先打開 Xcode 新建一個 Tabbed App，點選 Main.storyboard 後你可以看到有一個箭頭指向一個 Tab Bar Controller，這代表我們 App 的第一個進入點 (Entry Point)，換句話說 iOS App 啟動後這裡就是第一個使用者會看到、使用到的畫面，它也是一個很重要的地方，因為若我們需要初始化一些設定就可以在這邊完成。參考下圖：
&lt;br/&gt;&lt;br/&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7XWAQkdFd2KGEbOWpkJ12-GScI7m9pobt7eBR_Lr_cSHgA3T-7jw2dq5Qv_nxsXce64fkeQSKpNjMRk7BDGXqhSWXo7AL4lwA0bdbEuO3FLoloPnwkaeeN0U4PkBQMw6_ixYFMx38GSzS/s1600/storyboard-2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7XWAQkdFd2KGEbOWpkJ12-GScI7m9pobt7eBR_Lr_cSHgA3T-7jw2dq5Qv_nxsXce64fkeQSKpNjMRk7BDGXqhSWXo7AL4lwA0bdbEuO3FLoloPnwkaeeN0U4PkBQMw6_ixYFMx38GSzS/s1600/storyboard-2.png&quot; data-original-width=&quot;506&quot; data-original-height=&quot;224&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br/&gt;&lt;br/&gt;
上圖中的箭頭是可以拖拉，也就是你可以拖拉那個箭頭到不同的地方。隨著你的 App 設計 (劇本) 的不同，使用者可能需要切換不同的操作畫面，你就需要加入更多的操作畫面，而這時候你的 Storyboard 就會類似下面的架構：
&lt;br/&gt;&lt;br/&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrEXvs4HC8ZLbLqJ8seuEO4DtBp7K6PP54zweKi3tt1uoMf-BIYTYKjzEaUag70mBVVxTofZChoCc6Ox8MeD34j8AEk1f3rWpcOhyphenhyphenLVJsKkf-noaZPr-mzrAxFZPmbjegk_zYNljYxepz6/s1600/storyboard-3.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrEXvs4HC8ZLbLqJ8seuEO4DtBp7K6PP54zweKi3tt1uoMf-BIYTYKjzEaUag70mBVVxTofZChoCc6Ox8MeD34j8AEk1f3rWpcOhyphenhyphenLVJsKkf-noaZPr-mzrAxFZPmbjegk_zYNljYxepz6/s640/storyboard-3.png&quot; width=&quot;607&quot; height=&quot;640&quot; data-original-width=&quot;720&quot; data-original-height=&quot;759&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br/&gt;&lt;br/&gt;
上圖說明了使用者進入了 App 後，我們可以透過按鈕或程式設定讓使用來進入 (切換) 到不同的操作畫面，所以你也可以看到有兩個箭頭延伸出來至不同的 View。以上讓你簡單地認識 Storyboard 以及其扮演的角色，簡單來說它就是一個將你的 App 架構、流程圖像化，讓開發及設計的過程更簡化的功能。而開發者也可以明確知道操作畫面是如何彼此連結的，當然還有很多細節可以討論，之後實作時會補充更多資訊，但我們這邊只給你一個基本的認識。
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;h1&gt;初步了解 ViewController&lt;/h1&gt;
上面在介紹 Storyboard 時一直提到操作畫面以及 View (畫面中一個一個的長方塊)，其實它們就是一個一個的 &lt;b&gt;ViewController&lt;/b&gt;。它們的功用是什麼呢？你可以把 ViewController 當作是一個操作畫面的容器，一個操作畫面是由好多東西組成的，例如：按鈕、文字方塊、圖片等等。我們把這些元件放進容器 ViewController 裡，然後我們透過 ViewController 來進行更細部、有效的管理。
&lt;br/&gt;&lt;br/&gt;
但是我們要如何寫程式來設定、控制 ViewController ? 這時候我們就可以建立 Swift 程式檔案 (.swift) 然後加入程式碼，最後透過 Xcode 將 ViewController 的 Class 指定到我們新建 .swift 檔案內的 Class。這樣系統就會知道這個 ViewController 要使用這個 Class 內的程式碼。概念參考下圖：
&lt;br/&gt;&lt;br/&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqbs2Cq3z1ZcCZXlPoDVdqodzv3XwyfkfnOIbCBUf4x8u5djePXB35S2yVtswv8ODf8dIGxuDOOHIgY-M2cWPG3hdC_trLIo6QqwBDQsty5WNaspukL6o2DrG9oMure380UyPAohszVVT4/s1600/storyboard-4.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqbs2Cq3z1ZcCZXlPoDVdqodzv3XwyfkfnOIbCBUf4x8u5djePXB35S2yVtswv8ODf8dIGxuDOOHIgY-M2cWPG3hdC_trLIo6QqwBDQsty5WNaspukL6o2DrG9oMure380UyPAohszVVT4/s1600/storyboard-4.png&quot; data-original-width=&quot;571&quot; data-original-height=&quot;265&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br/&gt;&lt;br/&gt;
在這篇文章中，雖然我們還沒開始動手實作，但先初步認識 Storyboard 與 ViewController 會對之後的開發有很大的幫助。請繼續閱讀&lt;a target=&quot;_blank&quot; href=&quot;https://hatemegalaxy.blogspot.com/2017/12/ios-storyboard-22-ios-development-basic.html&quot;&gt;&lt;b&gt;iOS 開發教學 - 暸解 Storyboard 2/2&lt;/b&gt;&lt;/a&gt;。
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Environment :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;macOS&lt;br /&gt;
&lt;br/&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/3372772745315437398'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/3372772745315437398'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/12/ios-storyboard-ios-development-basic.html' title='iOS 開發教學 - 暸解 Storyboard 1/2 ( iOS Development - A basic introduction to Storyboard Part 1)'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlRjB5lsymiqs4c5DfOi-NVPfKmggRzhGHl3oDd2IYXXjD38InCQoZmIwB1fRKxLoY6XkMmMjgQbvZcH9lLb30CITXTkqkMP31tlyAaAtS_akf2dFxhyphenhyphenD29g6d34h3ZlA6gBXpuuJXZfKO/s72-c/storyboard-1.png" height="72" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-270163650485660484</id><published>2017-11-13T01:02:00.000+08:00</published><updated>2017-11-15T02:46:48.547+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="React"/><category scheme="http://www.blogger.com/atom/ns#" term="Webpack"/><title type='text'>React 教學 - 減少 React App 大小 ( Reduce React app&#39;s size using Webpack )</title><content type='html'>開發 React 應用程式時，比較常遇到的問題就是 bundle.js 或其他檔案太大，導致頁面載入時間過長。但透過 Webpack 與一些優化技巧可以大幅減少整個應用程式大小。因此，本篇將介紹如何利用 Webpack 減少 React 應用程式大小。(&amp;nbsp;If you want to read this article in English, you can visit &lt;a href=&quot;https://devforgalaxy.github.io/en/2017/11/13/reduce-react-app-size-en.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;here&lt;/span&gt;&lt;/a&gt;&amp;nbsp;)
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br/&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;使用 Webpack 預設優化套件&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
Webpack 本身已經有一些預設的套件可以幫助我們縮小 JS 檔案，你可以在&lt;a style=&quot;color: #6fa8dc;&quot; target=&quot;_blank&quot; href=&quot;http://webpack.github.io/docs/list-of-plugins.html#optimize&quot;&gt;這邊&lt;/a&gt;找到相關資料。首先，我們先用 UglifyJsPlugin 來盡可能地減少 JS 檔案大小，設定如下：
&lt;pre&gt;&lt;code class=&quot;javascript round5px&quot;&gt;plugins: [
  new webpack.optimize.UglifyJsPlugin()
]
&lt;/code&gt;&lt;/pre&gt;
當然，你可以利用其他 Webpack 預設的優化套件進行更細部的設定，但這邊先介紹比較入門的方式。
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;使用 CSS 優化套件&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
除了 JS 檔案之外，也別忘了盡可能減少 CSS 檔案大小，針對 CSS 檔案我們可以利用 optimize-css-assets-webpack-plugin。安裝方式：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;npm install --save-dev optimize-css-assets-webpack-plugin&lt;/code&gt;&lt;/pre&gt;
設定如下：
&lt;pre&gt;&lt;code class=&quot;javascript round5px&quot;&gt;const OptimizeCssAssetsPlugin = require(&#39;optimize-css-assets-webpack-plugin&#39;)
...
plugins: [
  new webpack.optimize.UglifyJsPlugin(),
  new OptimizeCssAssetsPlugin()
]
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;使用壓縮檔案套件&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
這個算是常見的優化手段，將靜態資源壓縮。一般來說，後端也會提供壓縮檔案的功能，但若我們在 Build React 應用程式時就將壓縮檔建立好會更節省系統資源。所以，我們可以利用 compression-webpack-plugin 套件來達成，首先安裝：
&lt;pre&gt;&lt;code class=&quot;javascript round5px&quot;&gt;npm install --save-dev compression-webpack-plugin&lt;/code&gt;&lt;/pre&gt;
接著設定 Webpack 設定檔：
&lt;pre&gt;&lt;code class=&quot;javascript round5px&quot;&gt;const CompressionPlugin = require(&#39;compression-webpack-plugin&#39;)
const OptimizeCssAssetsPlugin = require(&#39;optimize-css-assets-webpack-plugin&#39;)
...
plugins: [
  new webpack.optimize.UglifyJsPlugin(),
  new OptimizeCssAssetsPlugin(),
  new CompressionPlugin({
    asset: &quot;[path].gz[query]&quot;,
    algorithm: &quot;gzip&quot;,
    test: /\.js$|\.css$|\.html$/,
    threshold: 0,
    minRatio: 0.8
  })
]
&lt;/code&gt;&lt;/pre&gt;
相信這幾個步驟已經可以大幅減少 React 應用程式大小，但其實還有更多的優化方式。不過，此篇先列出利用 Webpack 套件就可以輕易地達成的方法，希望有幫助到你！
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Environment :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;Unix-like System&lt;br /&gt;
Reference :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;&lt;a href=&quot;https://webpack.js.org&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;Webpack&lt;/span&gt;&lt;/a&gt;&lt;br/&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/270163650485660484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/270163650485660484'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/11/react-react-app-reduce-react-apps-size.html' title='React 教學 - 減少 React App 大小 ( Reduce React app&#39;s size using Webpack )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-4611734628705341894</id><published>2017-11-09T02:05:00.002+08:00</published><updated>2017-11-10T02:24:22.898+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="SCSS"/><category scheme="http://www.blogger.com/atom/ns#" term="Webpack"/><title type='text'>Webpack 教學 - 編譯 SCSS 檔案 ( Webpack - Compile and convert SCSS files into a single CSS file)</title><content type='html'>Webpack 是一個很強大的工具，而且已有取代 Gulp 的趨勢。因爲不僅可以透過它來編譯與合併 JS 檔案，還可以透過其他 Loader 來處理其他檔案，例如將 SCSS 檔案編譯成 CSS。因此，本篇將介紹如何利用 Webpack 單純地將 SCSS 檔案編譯並合併成一個 CSS 檔案，這邊將不會討論如何處理在 JS 中引入的 CSS。(&amp;nbsp;If you want to read this article in English, you can visit &lt;a href=&quot;https://devforgalaxy.github.io/en/2017/11/09/webpack-complie-scss-into-css-en.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;here&lt;/span&gt;&lt;/a&gt;&amp;nbsp;)
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br/&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;前置作業&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
Webpack 能如此強大是因為它擁有許多 Loader，要透過 Webpack 編譯 SCSS 檔案必須安裝 Sass-loader 與其他套件，所以我們先來安裝所需 Loader 與套件：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;npm install --save-dev css-loader sass-loader node-sass extract-text-webpack-plugin
&lt;/code&gt;&lt;/pre&gt;
安裝後，接著來調整 Webpack 設定檔。
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;修改 Webpack 設定檔&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
讓我們將剛剛安裝的 Loader 與套件加入設定檔，這裡將介紹比較入門的設定方式，參考如下：
&lt;pre&gt;&lt;code class=&quot;javascript round5px&quot;&gt;const path = require(&#39;path&#39;);
const ExtractTextPlugin = require(&#39;extract-text-webpack-plugin&#39;);

module.exports = {
  entry: [
    ...
    path.join(__dirname, &#39;path&#39;, &#39;to&#39;, &#39;scss&#39;, &#39;style1.scss&#39;),
    path.join(__dirname, &#39;path&#39;, &#39;to&#39;, &#39;scss&#39;, &#39;style2.scss&#39;)
  ],
  output: {
    ...
  },
  module: {
    rules: [{
      test: /\.(scss)$/,
      loader: ExtractTextPlugin.extract([&#39;css-loader&#39;, &#39;sass-loader&#39;])
    }]
  },
  plugins: [
    ...
    new ExtractTextPlugin({
      filename: &#39;path/to/css/style.css&#39;
    })
  ]
};
&lt;/code&gt;&lt;/pre&gt;
Webpack 的設定方式有很多種而且可以更深入的設定，以上是一個比較簡單的範例。
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Environment :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;Unix-like System&lt;br /&gt;
Reference :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;&lt;a href=&quot;https://webpack.js.org&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;Webpack&lt;/span&gt;&lt;/a&gt;&lt;br/&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;&lt;a href=&quot;https://github.com/webpack-contrib/sass-loader&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;Sass-loader&lt;/span&gt;&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/4611734628705341894'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/4611734628705341894'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/11/webpack-scss-webpack-compile-and.html' title='Webpack 教學 - 編譯 SCSS 檔案 ( Webpack - Compile and convert SCSS files into a single CSS file)'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-7378241984712291674</id><published>2017-10-31T00:33:00.000+08:00</published><updated>2017-11-04T02:08:13.397+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Jekyll"/><title type='text'>Jekyll - 實現隨機文章功能 ( Jeykll - Generate random post links when refreshing page )</title><content type='html'>Jekyll 是一個很方便的網站、部落格產生器，它的功能夠簡潔就是專注在產生一個靜態網站。但也因為這樣，有一些需要動態產生的東西無法透過 Jekyll 直接實現。例如：每當使用者進入頁面，讓網頁產生隨機文章連結。所以，本篇將介紹如何利用 Jekyll 實現隨機文章的功能。(&amp;nbsp;If you want to read this article in English, you can visit &lt;a href=&quot;https://devforgalaxy.github.io/en/2017/10/30/jekyll-add-random-post-link-to-page-en.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;here&lt;/span&gt;&lt;/a&gt;&amp;nbsp;)
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br/&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;產生 JSON 檔案&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
首先，我們來了解實現這個功能的方法。Jekyll 是沒辦法完成任何動態的功能，但是我們可以在 Jekyll 產生靜態頁面時順便建立一個 JSON 檔案，而該檔案匯集你所有文章的名稱、連結等等。最後，我們只需要在頁面中透過 JS 讀取這個 JSON 檔案並隨機挑選文章來呈現。暸解後，我們先來建立一個 JSON 檔案，例如：posts.json，然後加入以下內容：
&lt;pre&gt;&lt;code class=&quot;json round5px&quot;&gt;---
---
[
{% assign posts = site.posts | where:&quot;your-filter&quot;,&quot;filter-value&quot; %}
{% for post in posts %}
{
    &quot;title&quot;: &quot;{{ post.title }}&quot;,
    &quot;href&quot;: &quot;{{ post.url }}&quot;
}{% unless forloop.last %},{% endunless %}
{% endfor %}
]
&lt;/code&gt;&lt;/pre&gt;
以上只是一個簡單範例，看你需要什麼資料就加進去。每當你開始 build 你的網站時，完整的 posts.json 就會產生在 _site 資料夾內。
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;隨機選取文章資料&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
當我們順利產生完整的 posts.json 之後，我們就可以透過 JavaScript 來實現隨機文章的功能。在頁面中加入以下程式碼：
&lt;pre&gt;&lt;code class=&quot;javascript round5px&quot;&gt; ... 
&amp;lt;script src=&amp;quot;//cdnjs.cloudflare.com/ajax/libs/fetch/2.0.3/fetch.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
$(function() {
  fetch(&#39;/posts.json&#39;)
    .then(function(response) {
      return response.json();
    })
    .then(function(json) {
      // Generate an random index
      var index = Math.floor(Math.random() * json.length);
      // Get the post
      var post = json[index];

      // Do things with post ...
    
    }).catch(function(error) {
      console.error(error);
    });
});
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
以上是一個簡單的範例，剩下的就看你需要怎麼呈現文章的相關資料。
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Environment :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;Unix-like System&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/7378241984712291674'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/7378241984712291674'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/10/jekyll-jeykll-add-random-posts-link-to.html' title='Jekyll - 實現隨機文章功能 ( Jeykll - Generate random post links when refreshing page )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-4602583934875562238</id><published>2017-10-23T14:34:00.000+08:00</published><updated>2017-10-25T01:25:39.113+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Django"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Django 實作教學 - 處理 JSON Request ( Django - Handle JSON request )</title><content type='html'>之前分享了如何透過 Django 回傳 JSON 資料，接著要利用本篇來介紹如何處理 JSON Request。(&amp;nbsp;其他 Django 相關教學可以參考&lt;a href=&quot;https://hatemegalaxy.blogspot.com/2017/10/django-useful-tutorials-for-django-web.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;本篇整理&lt;/span&gt;&lt;/a&gt;。If you want to read this article in English, you can visit &lt;a href=&quot;https://devforgalaxy.github.io/en/2017/10/23/django-handle-json-request-en.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;here&lt;/span&gt;&lt;/a&gt;&amp;nbsp;)
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br/&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;前置作業&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
在開始之前，若你還沒將環境建立起來的話，先安裝 Django 並建立專案：
&lt;pre&gt;&lt;code class=&quot;round5px bash&quot;&gt;# 安裝 Django
python -m pip install Django

# 查看 Django 版本
python -m django --version

# 建立 Django 專案
django-admin startproject &amp;lt;project-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
專案預設結構如下：
&lt;pre&gt;&lt;code class=&quot;round5px python&quot;&gt;project-name/
├── project-name
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;處理 JSON 請求&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
基本上利用 Django 處理 JSON Request 很簡單，當客戶端發起一個帶有 JSON 資料的 Request (如：POST、PUT)，Django 接收到後該資料會存在於 Request 物件的 body 中。暸解後，實作起來就很簡單了，以下為範例：
&lt;pre&gt;&lt;code class=&quot;python round5px&quot;&gt;import json
from django.views import View

class DummyView(View):
    def post(self, request):
        if request.body:
           # Decode data to a dict object
           json_data = json.loads(request.body)

        # Then do things with json_data ...

&lt;/code&gt;&lt;/pre&gt;
當然每次都要重複一樣的動作實在是有點麻煩，因此我們可以利用 View Decorator。
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;利用 Decorator 預先處理 JSON&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
利用 Django 提供的 Decorator (裝飾器) 簡化許多需要重複做的事情。首先新增 decorators.py，然後加入一個名為 dummy_json 的裝飾器，參考以下內容：
&lt;pre&gt;&lt;code class=&quot;python round5px&quot;&gt;import json
from functools import wraps
from django.conf import settings
from django.http import HttpRequest, HttpResponse

def dummy_json(view_func):

    @wraps(view_func)
    def wrapper_view_func(request, *args, **kwargs):
        # Add simple validation
        if request.content_type == &#39;application/json&#39;:
            if request.body:
                # Decode data to a dict object
                request.json = json.loads(request.body)
            else:
                request.json = None
        return view_func(request, *args, **kwargs)
    return wrapper_view_func
&lt;/code&gt;&lt;/pre&gt;
完成後，之後我們就可以在 View 中直接使用 dummy_json，像這樣：
&lt;pre&gt;&lt;code class=&quot;python round5px&quot;&gt;import json
from decorators import *
from django.views import View
from django.utils.decorators import method_decorator

class DummyView(View):

    @method_decorator(dummy_json)
    def post(self, request):
        json_data = request.json
        # Then do things with json_data ...

&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
Environment :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;Unix-like System&lt;br /&gt;
Reference :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;&lt;a href=&quot;https://www.djangoproject.com&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;Django&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/4602583934875562238'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/4602583934875562238'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/10/django-json-request-django-handle-json.html' title='Django 實作教學 - 處理 JSON Request ( Django - Handle JSON request )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-4272067972022084923</id><published>2017-10-11T23:58:00.000+08:00</published><updated>2017-10-23T14:35:16.072+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Django"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Django 教學 - 教學文章彙整 ( Useful tutorials for Django web framework )</title><content type='html'>為了方便其他人參考 Django 相關教學，因此將發表過的文章整理詳細列出。之後若發表其他有關 Django 的文章會同步更新此篇內容。&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;Django 教學文章彙整：&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
(1.)&amp;nbsp;&lt;a href=&quot;https://hatemegalaxy.blogspot.com/2017/05/django-logging-django-configure-logging.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;Django 實作教學 - 設定 Logging&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
(2.)&amp;nbsp;&lt;a href=&quot;https://hatemegalaxy.blogspot.com/2017/05/django-error-404-django-customized.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;Django 實作教學 - 自訂 Error 404 頁面&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
(3.)&amp;nbsp;&lt;a href=&quot;https://hatemegalaxy.blogspot.com/2017/08/django-whitenoise-django-using.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;Django 實作教學 - 使用 WhiteNoise 處理靜態文件&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
(4.)&amp;nbsp;&lt;a href=&quot;https://hatemegalaxy.blogspot.com/2017/09/django-json-django-return-json-response.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;Django 實作教學 - 回傳 JSON 資料&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
(5.)&amp;nbsp;&lt;a href=&quot;https://hatemegalaxy.blogspot.com/2017/10/django-json-request-django-handle-json.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;Django 實作教學 - 處理 JSON Request&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/4272067972022084923'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/4272067972022084923'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/10/django-useful-tutorials-for-django-web.html' title='Django 教學 - 教學文章彙整 ( Useful tutorials for Django web framework )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-281040786740072063</id><published>2017-10-05T16:12:00.000+08:00</published><updated>2017-10-06T17:41:01.032+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Mac"/><title type='text'>Mac - 透過 Command Line 安裝 .dmg 檔案 ( Mac - How to install .dmg through command line )</title><content type='html'>Mac 系統已經將安裝軟體的過程化繁為簡，但有時候還是會需要透過 Command Line 安裝軟體的情況。所以，本篇將介紹如何透過 Command Line 安裝 .dmg 檔案。( 其他 Mac 相關教學可以參考&lt;a href=&quot;http://hatemegalaxy.blogspot.com/2015/04/mac-useful-tutorials-and-resources-for.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;本篇整理&lt;/span&gt;&lt;/a&gt;。If you want to read this article in English, you can visit &lt;a href=&quot;https://devforgalaxy.github.io/en/2017/10/06/mac-install-dmg-through-command-line-en.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;here&lt;/span&gt;&lt;/a&gt;&amp;nbsp;)&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br/&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;透過 Command Line 安裝 .dmg 檔案&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
基本上，整個安裝過程相當單純。簡單來說，我們只需要把 .dmg 檔案掛載，之後將整個檔案複製再把 .dmg 檔案卸載就完成了。首先來掛載檔案：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;sudo hdiutil attach [disk-image-name].dmg&lt;/code&gt;&lt;/pre&gt;
接著進入掛載的檔案中：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;cd /Volumes/[disk-image-name]&lt;/code&gt;&lt;/pre&gt;
進入後，你可以看到 [app-name].app 的資料夾，我們只要把該資料夾整個複製就算安裝完成：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;sudo cp -rf [app-name].app /Applications&lt;/code&gt;&lt;/pre&gt;
安裝完檔案後，只需要將檔案卸載：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;sudo hdiutil detach /Volumes/[disk-image-name]&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
Environment :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;macOS&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/281040786740072063'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/281040786740072063'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/10/mac-command-line-dmg-mac-how-to-install.html' title='Mac - 透過 Command Line 安裝 .dmg 檔案 ( Mac - How to install .dmg through command line )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-1035176059957351988</id><published>2017-10-02T15:33:00.000+08:00</published><updated>2017-10-06T10:41:37.311+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Gitlab"/><category scheme="http://www.blogger.com/atom/ns#" term="SSH"/><title type='text'>Gitlab - 解決 Permission denied (publickey) ( Resolve Gitlab permission denied (publickey) error )</title><content type='html'>Gitlab 為了讓使用者部署程式更方便，它提供了一個功能叫 Deploy Keys，使用者將 SSH Public Key 加入，之後不需要密碼就可以獲得程式庫 read-only 的權限，所以很適合運用在 CI 中。通常在 Unix-like 環境中將對應的 Key 與其使用權限設定好就可以開始 Pull 程式庫，但我仍遇到  Permission denied 的訊息。因此，本篇將介紹如何解決這個問題。(If you want to read this article in English, you can visit &lt;a href=&quot;https://devforgalaxy.github.io/en/2017/10/01/resolve-gitlab-permission-denied-en.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;here&lt;/span&gt;&lt;/a&gt;)&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br/&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;解決 Permission denied (publickey)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
會得到 Permission denied 訊息的情況有很多種，我所遇到的情況是已經將 SSH Key 加入系統中並給予適當的權限，但仍然遇到錯誤訊息：
&lt;pre&gt;&lt;code class=&quot;html round5px&quot;&gt;Cloning into &#39;your-repo&#39;...
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
&lt;/code&gt;&lt;/pre&gt;
後來發現我們只需要在 .ssh 資料夾下增加一個 config 文字檔即可解決此問題：
&lt;pre&gt;&lt;code class=&quot;html round5px&quot;&gt;Host gitlab.com
User git
Hostname gitlab.com
IdentityFile ~/.ssh/id_rsa
IdentitiesOnly yes
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
Environment :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;Unix-like System&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/1035176059957351988'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/1035176059957351988'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/10/gitlab-permission-denied-publickey.html' title='Gitlab - 解決 Permission denied (publickey) ( Resolve Gitlab permission denied (publickey) error )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-4418318357251956342</id><published>2017-09-27T10:58:00.000+08:00</published><updated>2017-10-12T00:02:15.672+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Django"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Django 實作教學 - 回傳 JSON 資料 ( Django - Return a JSON response )</title><content type='html'>處理完用戶端請求後 Django 提供多種回傳資料的方式，JSON 格式則是其中一種，你在網路上也可以找到各種不同回傳 JSON 資料的方式。其實 Django 本身就提供了一個相當簡單的方法，因此本篇就將介紹如何透過 Django 回傳 JSON 資料。(其他 Django 相關教學可以參考&lt;a href=&quot;https://hatemegalaxy.blogspot.com/2017/10/django-useful-tutorials-for-django-web.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;本篇整理&lt;/span&gt;&lt;/a&gt;。If you want to read this article in English, you can visit &lt;a href=&quot;https://devforgalaxy.github.io/en/2017/09/30/django-return-json-response-en.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;here&lt;/span&gt;&lt;/a&gt;)
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br/&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;前置作業&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
在開始設定之前，若你還沒將環境建立起來的話，先安裝 Django 並建立專案：
&lt;pre&gt;&lt;code class=&quot;round5px bash&quot;&gt;# 安裝 Django
python -m pip install Django

# 查看 Django 版本
python -m django --version

# 建立 Django 專案
django-admin startproject &amp;lt;project-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
專案預設結構如下：
&lt;pre&gt;&lt;code class=&quot;round5px python&quot;&gt;project-name/
├── project-name
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;使用 JsonResponse&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
Django 從 1.7 版本就提供了 JsonResponse 這個相當方便的物件讓我們回傳 JSON 資料。首先，它會將 Content-Type 設定成 application/json，最後再將你傳入的參數轉成 JSON 格式並回傳。使用方式如下：
&lt;pre&gt;&lt;code class=&quot;python round5px&quot;&gt;from django.http import JsonResponse
from django.views import View

class SandboxHandler(View):
    def get(self, request):
        data = {
            &#39;name&#39;: &#39;Django&#39;,
            &#39;version&#39;: &#39;1.x&#39;
        }
        return JsonResponse(data)
&lt;/code&gt;&lt;/pre&gt;
值得注意的是，預設可傳入的參數必須是要 dict 型態。若你想要傳入其他型態的物件並輸出成 JSON 格式，你可以加上 safe=False：
&lt;pre&gt;&lt;code class=&quot;python round5px&quot;&gt;return JsonResponse(other_object, safe=False)&lt;/code&gt;&lt;/pre&gt;
最後，若你不想使用內建的 JSON Encoder，你可以自行指定其他的 Encoder：
&lt;pre&gt;&lt;code class=&quot;python round5px&quot;&gt;return JsonResponse(other_object, encoder=OtherJsonEncoder)&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
Environment :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;Unix-like System&lt;br /&gt;
Reference :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;&lt;a href=&quot;https://www.djangoproject.com&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;Django&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/4418318357251956342'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/4418318357251956342'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/09/django-json-django-return-json-response.html' title='Django 實作教學 - 回傳 JSON 資料 ( Django - Return a JSON response )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-4369764052066050708</id><published>2017-09-24T00:27:00.000+08:00</published><updated>2017-09-24T23:44:17.809+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="PostgreSQL"/><title type='text'>PostgreSQL 教學 - 備份與復原資料庫 ( Backup and restore database using PostgreSQL )</title><content type='html'>前一篇介紹了&lt;a href=&quot;https://hatemegalaxy.blogspot.tw/2017/09/postgresql-create-database-and-user.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;使用 PostgreSQL 建立資料庫與使用者&lt;/span&gt;&lt;/a&gt;之後，當然除了新增資料庫之外，我們常常還更需要備份跟復原的方法，因此本篇將介紹如何使用 PostgreSQL 備份與復原資料庫。
( 
&lt;!-- 其他 PostgreSQL 相關教學可以參考&lt;a href=&quot;&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;本篇整理&lt;/span&gt;&lt;/a&gt;&amp;nbsp;。--&gt;
If you want to read this article in English, you can visit &lt;a href=&quot;https://devforgalaxy.github.io/en/2017/09/24/backup-and-restore-database-using-postgresql-en.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;here&lt;/span&gt;&lt;/a&gt; )
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br/ &gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;備份資料庫&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
這裡將介紹最簡單的備份方式，也就是將整個資料庫的資料輸出成檔案 (例如：文字檔)，指令如下：
&lt;pre&gt;&lt;code class=&quot;round5px bash&quot;&gt;pg_dump [資料庫名稱] &gt; /path/to/[備份檔名稱].txt&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;復原資料庫&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
要復原資料庫之前，首先要建立一個空的資料庫：
&lt;pre&gt;&lt;code class=&quot;round5px bash&quot;&gt;psql -c &quot;CREATE DATABASE [資料庫名稱];&quot;&lt;/code&gt;&lt;/pre&gt;
接著將備份檔案寫回資料庫：
&lt;pre&gt;&lt;code class=&quot;round5px bash&quot;&gt;psql [資料庫名稱] &lt; [備份檔名稱].txt&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
Environment :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;Mac OS X&lt;br /&gt;
Reference :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;&lt;a href=&quot;https://www.postgresql.org&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;PostgreSQL&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/4369764052066050708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/4369764052066050708'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/09/postgresql-backup-and-restore-database.html' title='PostgreSQL 教學 - 備份與復原資料庫 ( Backup and restore database using PostgreSQL )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-8056613008039011212</id><published>2017-09-18T17:16:00.000+08:00</published><updated>2017-09-19T22:45:00.990+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="PostgreSQL"/><title type='text'>PostgreSQL 教學 - 快速建立資料庫與使用者 ( Create database and user using PostgreSQL )</title><content type='html'>相信 PostgreSQL 已經成為許多團隊愛用的資料庫，因此本篇文章將介紹如何透過 PostgreSQL 的指令簡單的將資料庫與使用者建立起來，雖然沒難度但仍在這記錄下來供其他人參考。
( 
&lt;!-- 其他 PostgreSQL 相關教學可以參考&lt;a href=&quot;&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;本篇整理&lt;/span&gt;&lt;/a&gt;&amp;nbsp;。 --&gt;
If you want to read this article in English, you can visit &lt;a href=&quot;https://devforgalaxy.github.io/en/2017/09/19/create-database-and-user-using-postgresql-en.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;here&lt;/span&gt;&lt;/a&gt; )
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br/ &gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;建立使用者：&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
首先將目前使用者切換為 postgres，接著執行指令：
&lt;pre&gt;&lt;code class=&quot;round5px bash&quot;&gt;createuser [使用者名稱]&lt;/code&gt;&lt;/pre&gt;
若有安裝 sudo 則可以：
&lt;pre&gt;&lt;code class=&quot;round5px bash&quot;&gt;sudo -u postgres createuser [使用者名稱]&lt;/code&gt;&lt;/pre&gt;
使用者建立完成後，接著修改使用者密碼：
&lt;pre&gt;&lt;code class=&quot;round5px bash&quot;&gt;psql -c &quot;alter user [使用者名稱] with encrypted password &#39;[密碼]&#39;;&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;建立資料庫：&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
一樣以 postgres 使用者身份執行：
&lt;pre&gt;&lt;code class=&quot;round5px bash&quot;&gt;createdb [資料庫名稱]&lt;/code&gt;&lt;/pre&gt;
同樣地，若有安裝 sudo 則可以：
&lt;pre&gt;&lt;code class=&quot;round5px bash&quot;&gt;sudo -u postgres createdb [資料庫名稱]&lt;/code&gt;&lt;/pre&gt;
建立好資料庫後，給予使用者權限操作資料庫：
&lt;pre&gt;&lt;code class=&quot;round5px bash&quot;&gt;psql -c &quot;grant all privileges on database [資料庫名稱] to [使用者名稱];&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
Environment :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;Mac OS X&lt;br /&gt;
Reference :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;&lt;a href=&quot;https://www.postgresql.org&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;PostgreSQL&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/8056613008039011212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/8056613008039011212'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/09/postgresql-create-database-and-user.html' title='PostgreSQL 教學 - 快速建立資料庫與使用者 ( Create database and user using PostgreSQL )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-7000860037744126159</id><published>2017-08-23T00:59:00.000+08:00</published><updated>2017-08-23T21:11:55.364+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Docker"/><title type='text'>Docker 教學 (2) - 解決 Fish Shell 無法設定 docker-machine env ( Resolve fish: Unknown command &#39;export&#39; when executing docker-machine env )</title><content type='html'>本篇將介紹當使用 Fish Shell 設定 docker-machine 參數時遇到錯誤：&lt;span style=&quot;color: #cc668c;&quot;&gt;fish: Unknown command &#39;export&#39;&lt;/span&gt; 的解決方法。雖然使用 Fish Shell 的人可能不多，但還是將解決方法記錄下來供參考。( 其他 Docker 相關教學可以參考&lt;a href=&quot;https://hatemegalaxy.blogspot.com/2016/02/docker-useful-tutorial-for-docker.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;本篇整理&lt;/span&gt;&lt;/a&gt;&amp;nbsp;。If you want to read this article in English, you can visit &lt;a href=&quot;https://devforgalaxy.github.io/en/2017/08/23/resolve-fish-unknown-command-export-for-docker-en.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;here&lt;/span&gt;&lt;/a&gt; )&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br/ &gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;解決 fish: Unknown command &#39;export&#39;：&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
首先，先讓我們來了解 Fish Shell 是怎麼設定 Shell 參數。Fish 跟其他 Shell 不太一樣，它並沒有 &lt;span style=&quot;color: #cc668c;&quot;&gt;export&lt;/span&gt; 指令來設定參數，而是使用：
&lt;pre&gt;&lt;code class=&quot;round5px bash&quot;&gt;set -x [參數名稱] [參數值]&lt;/code&gt;&lt;/pre&gt;
而當我們在使用 &lt;span style=&quot;color: #cc668c;&quot;&gt;eval (docker-machine env your-machine)&lt;/span&gt; 時，其內容為：
&lt;pre&gt;&lt;code class=&quot;round5px bash&quot;&gt;export DOCKER_TLS_VERIFY=&quot;1&quot;
export DOCKER_HOST=&quot;tcp://100.100.100.100:2376&quot;
export DOCKER_CERT_PATH=&quot;/path/to/your/machine&quot;
export DOCKER_MACHINE_NAME=&quot;your-machine&quot;
&lt;/code&gt;&lt;/pre&gt;
所以，Fish 當然沒有辦法認得其中的 export 指令，因此丟出錯誤訊息。而 docker-machine 很貼心的提供解決方式，就是利用 &lt;span style=&quot;color: #cc668c;&quot;&gt;--shell&lt;/span&gt; 參數：
&lt;pre&gt;&lt;code class=&quot;round5px bash&quot;&gt;eval (docker-machine env your-machine --shell=fish)&lt;/code&gt;&lt;/pre&gt;
如此一來，你應該就可以正常的設定 docker-machine 參數。
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Environment :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;Mac OS X&lt;br /&gt;
Reference :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;&lt;a href=&quot;https://fishshell.com&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;Fish Shell&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;&lt;a href=&quot;https://docs.docker.com/machine/&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;Docker Machine&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/7000860037744126159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/7000860037744126159'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/08/docker-2-fish-shell-docker-machine-env.html' title='Docker 教學 (2) - 解決 Fish Shell 無法設定 docker-machine env ( Resolve fish: Unknown command &#39;export&#39; when executing docker-machine env )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-4420584894870543431</id><published>2017-08-03T23:56:00.000+08:00</published><updated>2017-08-04T02:04:34.766+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="AWS"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>AWS - 編譯 Pandoc 並於 AWS Lambda 上執行 ( AWS - Build Pandoc and run it on AWS Lambda )</title><content type='html'>Web 應用程式常常會需要轉換文件格式的功能，例如：HTML 檔轉換成 PDF 檔，或是 TXT 轉換成 MS DOCX 檔案。&lt;span style=&quot;color: #6fa8dc;&quot;&gt;Pandoc&lt;/span&gt; 是一個相當好用的轉換文件工具，加上搭配 AWS Lambda 來實作類似的功能是很合適的。但是 Lambda 在使用上有一些限制，所以要在 Lambda 環境下使用 Pandoc，我們必須先將它編譯好然後上傳至 Lambda 環境再執行它。本篇將介紹如何編譯 Pandoc 並在 AWS Lambda 上使用 Pandoc。( 其他 AWS 相關教學可以參考&lt;a href=&quot;http://hatemegalaxy.blogspot.com/2015/12/aws-useful-tutorial-for-aws.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;本篇整理&lt;/span&gt;&lt;/a&gt;。If you want to read this article in English, you can visit &lt;a href=&quot;https://devforgalaxy.github.io/en/2017/08/04/build-pandoc-and-run-it-on-aws-lambda-en.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;here&lt;/span&gt;&lt;/a&gt; )&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br/&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;前置作業&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
要編譯可在 Lambda 環境下執行的 Pandoc，我們必須先準備一個相似的環境。幸運地是，我們可以利用 &lt;a href=&quot;https://github.com/lambci/docker-lambda&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;docker-lambda&lt;/span&gt;&lt;/a&gt; 所提供的 Docker Image 來建置這個環境。接下來範例將使用 Python 環境，所以選擇適合的 Image：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;docker pull lambci/lambda:build-python2.7&lt;/code&gt;&lt;/pre&gt;
&lt;br/&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;編譯 Pandoc&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
將 Docker 容器建立好後，我們就可以接著來準備編譯 Pandoc ( 注意，進入容器後的預設路徑是 /var/task )：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;# 安裝開發套件
yum -y install gmp-devel freeglut-devel python-devel zlib-devel gcc m4
&lt;/code&gt;&lt;/pre&gt;
除了開發套件外，我們還需要 GHC 與 Cabal：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;# 安裝 GHC
GHC=&#39;https://downloads.haskell.org/~ghc/8.0.1/ghc-8.0.1-x86_64-centos67-linux.tar.xz&#39;
curl -OL $GHC &amp;&amp; tar xf ghc* &amp;&amp; cd ghc* &amp;&amp; ./configure --prefix=/usr &amp;&amp; make install &amp;&amp; cd ..

# 安裝 Cabal
CABAL=&#39;https://www.haskell.org/cabal/release/cabal-install-1.24.0.0/cabal-install-1.24.0.0-x86_64-unknown-linux.tar.gz&#39;
mkdir .bin &amp;&amp; cd .bin &amp;&amp; curl -OL $CABAL &amp;&amp; tar xf cabal* &amp;&amp; cd ..
&lt;/code&gt;&lt;/pre&gt;
開始執行編譯：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;# 編譯 Pandoc
.bin/cabal sandbox init &amp;&amp; \
.bin/cabal update &amp;&amp; \
.bin/cabal install hsb2hs &amp;&amp; \
.bin/cabal install --disable-documentation pandoc -fembed_data_files

# 編譯完，壓縮 Pandoc
cp .cabal-sandbox/bin/pandoc .
gzip pandoc
&lt;/code&gt;&lt;/pre&gt;
完成後將編譯好的檔案後下載即可：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;docker cp [container-name]:/var/task/pandoc.gz /path/to/local/pandoc.gz&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;使用 Pandoc&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
AWS Lambda 允許你在 /tmp 中下載以及產生檔案，所以我們將欲執行的程式與 Pandoc 壓縮檔上傳至 AWS Lambda 後，執行程式時將 Pandoc 解壓縮至該處後就可以開始使用它了。簡單的 Python 範例如下：
&lt;pre&gt;&lt;code class=&quot;python round5px&quot;&gt;import subprocess

def init_cmd(cmd):
    return subprocess.Popen(
        cmd,
        shell=True,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE
    )

def execute_cmd():
    cmd = (
        &quot;cp pandoc.gz /tmp/pandoc.gz &amp;&amp; &quot;
        &quot;gzip -d /tmp/pandoc.gz &amp;&amp; &quot;
        &quot;chmod 755 /tmp/pandoc &amp;&amp; &quot;
        &quot;/tmp/pandoc -S -s /tmp/input-file -o /tmp/output-file&quot;
    )
    process = init_cmd(cmd)
    out, err = process.communicate()

    # Do anything you want

&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
Environment :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;Amazon Linux&lt;br /&gt;
Reference :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;&lt;a href=&quot;http://pandoc.org&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;Pandoc&lt;/span&gt;&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/4420584894870543431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/4420584894870543431'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/08/aws-pandoc-aws-lambda-aws-build-pandoc.html' title='AWS - 編譯 Pandoc 並於 AWS Lambda 上執行 ( AWS - Build Pandoc and run it on AWS Lambda )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-9194274881171213876</id><published>2017-08-01T02:21:00.000+08:00</published><updated>2017-10-12T00:03:20.849+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Django"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Django 實作教學 - 使用 WhiteNoise 處理靜態文件 ( Django - Using WhiteNoise with Django )</title><content type='html'>這篇文章要介紹如何使用 &lt;span style=&quot;color: #6fa8dc;&quot;&gt;WhiteNoise&lt;/span&gt; 來處理 Django 的靜態文件，為什麼需要特別方式來處理呢？因為，在開發模式下 (Debug 模式開啟)，Django 會有一套預設的機制來替你處理靜態文件。然而，在正式環境下 Django 則強烈建議使用其他的方式來 Serve 靜態的資源，如：使用 Nginx、Apache 或者是 AWS S3 等其他方式。如果你的 Web Application 規模較小，WhiteNoise 會是一個相當簡單的方式來 Serve 靜態文件。( 其他 Django 相關教學可以參考&lt;a href=&quot;https://hatemegalaxy.blogspot.com/2017/10/django-useful-tutorials-for-django-web.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;本篇整理&lt;/span&gt;&lt;/a&gt;。If you want to read this article in English, you can visit &lt;a href=&quot;https://devforgalaxy.github.io/en/2017/08/03/using-whitenoise-with-django-en.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;here&lt;/span&gt;&lt;/a&gt; )&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br/&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;前置作業&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
在開始設定之前，若你還沒將環境建立起來的話，先安裝 Django 並建立專案：
&lt;pre&gt;&lt;code class=&quot;round5px bash&quot;&gt;# 安裝 Django
python -m pip install Django

# 查看 Django 版本
python -m django --version

# 建立 Django 專案
django-admin startproject &amp;lt;project-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
專案預設結構如下：
&lt;pre&gt;&lt;code class=&quot;round5px python&quot;&gt;project-name/
├── project-name
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;安裝 WhiteNoise&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
我們可以透過 &lt;span style=&quot;color: #cc668c;&quot;&gt;pip&lt;/span&gt; 安裝 WhiteNoise，方式如下：
&lt;pre&gt;&lt;code class=&quot;python round5px&quot;&gt;python -m pip install whitenoise&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;設定 WhiteNoise&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
基本上，WhiteNoise 與 Django 的整合度很好，所以在 settings.py 中就可以完全大部分的設定步驟。跟著以下範例將設定加入 settings.py：
&lt;pre&gt;&lt;code class=&quot;python round5px&quot;&gt;# 將 WhiteNoise 加入 Middleware
MIDDLEWARE = [
    ...
    &#39;whitenoise.middleware.WhiteNoiseMiddleware&#39;,
]

# 設定靜態文件所在位置
STATIC_ROOT = os.path.join(BASE_DIR, &#39;staticfiles&#39;)
&lt;/code&gt;&lt;/pre&gt;
&lt;br/&gt;
&lt;hr/&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;複製靜態文件&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
剛剛我們已經設定靜態文件所在位置，接下來需要把各 Application 的靜態資源集中至該位置。而 Django 已經提供了一個簡單的方式：
&lt;pre&gt;&lt;code class=&quot;python round5px&quot;&gt;python manage.py collectstatic --noinput&lt;/code&gt;&lt;/pre&gt;
當以上步驟都完成後，將 Django 啟動後 WhiteNoise 就會自動開始 Serve 靜態資源。
&lt;br/&gt;
&lt;br/&gt;
&lt;hr/&gt;
Environment :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;Debian&lt;br /&gt;
Reference :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;&lt;a href=&quot;http://whitenoise.evans.io/en/stable/index.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;WhiteNoise&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/9194274881171213876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/9194274881171213876'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/08/django-whitenoise-django-using.html' title='Django 實作教學 - 使用 WhiteNoise 處理靜態文件 ( Django - Using WhiteNoise with Django )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-5626126204094636319</id><published>2017-05-21T17:24:00.000+08:00</published><updated>2017-08-03T00:49:34.970+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Hubot"/><title type='text'>Hubot 教學 (3) - 建立 Scripts ( Create scripts for your Hubot )</title><content type='html'>在&lt;a href=&quot;http://hatemegalaxy.blogspot.com/2017/04/hubot-2-hubot-install-and-set-up-your.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;安裝與設定 Hubot&lt;/span&gt;&lt;/a&gt; 中我們已經將 Hubot 建立好，接著本篇將繼續介紹如何新增、撰寫 Scripts 讓你的 Hubot 與 Slack 結合起來。(If you want to read this article in English, you can visit &lt;a href=&quot;https://devforgalaxy.github.io/en/2017/06/15/create-scripts-for-your-hubot-en.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;here&lt;/span&gt;&lt;/a&gt;)&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br/&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;前置作業&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
開始之前，再確認一下你有成功安裝 Node.js 與 npm，指令如下：
&lt;pre&gt;&lt;code class=&quot;round5px bash&quot;&gt;# 查看 Node.js 版本
nodejs -v

# 查看 npm 版本
npm -v
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;新增自訂 Scripts&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
在之前的教學中，我們透過 &lt;span style=&quot;color: #6fa8dc;&quot;&gt;Yo&lt;/span&gt; 建立 Hubot 後，你可以在整個 Hubot 專案裡看到有一個 scripts 資料夾，Hubot 啟動後會自動讀取這個資料夾裡面的 Scripts，所以這也就是我們接下來新增 Script 所要放置的地方。現在，讓我們新增一個簡單的 Script，你可以使用 JavaScript 或者是 CoffeeScript：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;module.exports = (robot) -&gt;

  # Show some information
  # 用法: show_info
  robot.respond /show_info/i, (msg) -&gt;

    # 傳回多行文字訊息
    msg.reply &quot;&quot;&quot;Put your information here
    and here ....
    and here ....
    &quot;&quot;&quot;
&lt;/code&gt;&lt;/pre&gt;
由上面簡單的範例你可以看到，Hubot 透過 robot.respond 來針對你所輸入指令做出反應，然後再利用 reply 回傳資料或是文字訊息。除了 respond 以外你也可以使用 hear。而 respond 與 hear 的差別在於，respond 只針對你所輸入的文字完全符合的狀況下才會做出反應，而 hear 則是會檢查文字中是否有符合的字串。下面則是比較進階的用法：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;  # Call a HTTP API
  # 用法: call-http [param1] [param2]
  robot.respond /call-http (.*) (.*)/i, (msg) -&gt;

    # 取得指令給予的 2 個參數
    data = JSON.stringify({
      param1: msg.match[1]
      param2: msg.match[2]
    })

    # 送出 POST Request，並傳回訊息
    msg.http(&#39;/url/to/your/service&#39;)
      .header(&#39;Content-Type&#39;, &#39;application/json&#39;)
      .post(data) (err, res, body) -&gt;
        if res
          if res.statusCode isnt 200
            msg.reply &quot;Something goes wrong ...&quot;
            return
          msg.reply &quot;Return your data or messages&quot;
        else
          msg.reply &quot;Something goes wrong ...&quot;

&lt;/code&gt;&lt;/pre&gt;
最後記得你自己建立的檔案 ( .js 或者是 .coffee ) 要放在 Scripts 資料夾底下。
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;整合 Hubot 與 Slack &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
我們剛剛建立的 Script 還沒有辦法正常的運作，因為 Slack 還不知道你 Hubot 的存在，所以我們需要去 Slack 上面註冊一個 Hubot。進入 Slack 後，點選 Apps &amp; Integrations 然後選擇 Bot，在 Bot 列表中選擇新增一個 Hubot。新增完成後，你可以看到有一個 API_token，這個 Token 就是唯一能讓你的 Hubot 與 Slack 正常運作的關鍵。
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;啟動 Hubot&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
使用 API_token 方式有兩種，一種是啟動時加入參數，方法如下：
&lt;pre&gt;&lt;code class=&quot;round5px bash&quot;&gt;HUBOT_SLACK_TOKEN=your-api-token ./bin/hubot --adapter slack
&lt;/code&gt;&lt;/pre&gt;
或者把 API_token 加到你的環境變數中即可，如此一來我們就完成所有設定的步驟。接下來，你就可以開始在 Slack 中對 Hubot 下達指令。
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Environment :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;Debian&lt;br /&gt;
Reference :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;&lt;a href=&quot;https://hubot.github.com/&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;Hubot&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/5626126204094636319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/5626126204094636319'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/05/hubot-3-scripts-create-scripts-for-your.html' title='Hubot 教學 (3) - 建立 Scripts ( Create scripts for your Hubot )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-654226156800277529</id><published>2017-05-09T00:36:00.003+08:00</published><updated>2017-10-12T00:03:37.495+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Django"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Django 實作教學 - 自訂 Error 404 頁面 ( Django - Customized error 404 view for your applications )</title><content type='html'>上一篇講解了 Logging 的基本概念與用法後，本篇將介紹如何在 Django 中自訂 Error 處理方式與頁面。( 其他 Django 相關教學可以參考&lt;a href=&quot;https://hatemegalaxy.blogspot.com/2017/10/django-useful-tutorials-for-django-web.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;本篇整理&lt;/span&gt;&lt;/a&gt;。If you want to read this article in English, you can visit &lt;a href=&quot;https://devforgalaxy.github.io/en/2017/05/06/django-customized-error-view-en.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;here&lt;/span&gt;&lt;/a&gt; )&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br/&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;前置作業&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
在開始設定之前，若你還沒將環境建立起來的話，先安裝 Django 並建立專案：
&lt;pre&gt;&lt;code class=&quot;round5px bash&quot;&gt;# 安裝 Django
python -m pip install Django

# 查看 Django 版本
python -m django --version

# 建立 Django 專案
django-admin startproject &amp;lt;project-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
專案預設結構如下：
&lt;pre&gt;&lt;code class=&quot;round5px python&quot;&gt;project-name/
├── project-name
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;建立 View&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
使用 Django 的好處就是它提供了許多預設機制，我們只需要去改寫部分細節、或者是定義自己想要的處理方式即可。以處理 Error 404 來說，Django 其實已經有一個預設的處理機制與頁面，因此我們不需要從零開始。當 Error 404 出現時，Django 會針對這個狀況指定一個 View (也就是我們程式邏輯所在部分)，所以我們可以在 view.py 中加入以下程式碼：
&lt;pre&gt;&lt;code class=&quot;python round5px&quot;&gt;# Error 404 
class Error404View(View):
    def get(self, request):
        # Do something if you want
        return render(request, &#39;path-to-your/error404.html&#39;)

# Error 500
class Error500View(View):
    def get(self, request):
        # Do something if you want
        return render(request, &#39;path-to-your/error500.html&#39;)
&lt;/code&gt;&lt;/pre&gt;
從上面的程式中，你可以看到我們使用兩個 HTML 檔案，這就是我們到時候要呈現的頁面。而通常我們的 HTML 檔案都會放在 templates 資料夾中，使用的方式跟一般的頁面是一樣的，頁面的內容我就不在這邊討論。
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;修改 URL 設定檔&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
前面的步驟還沒有辦法讓 Django 知道我們新的 View 要怎麼用以及何時用，因此我們現在要透過 URL 設定檔將它們連結起來，開啟 urls.py 並將以下內容加入：
&lt;pre&gt;&lt;code class=&quot;python round5px&quot;&gt;from django.conf.urls import handler404, handler500
# 將我們剛剛設定的 View 引入
from your-app.views import Error404View, Error500View

urlpatterns = [
    ...
]

# 讓系統知道對應的 View
handler404 = Error404View.as_view()
handler500 = Error500View.as_view()
&lt;/code&gt;&lt;/pre&gt;
如果你的 Django 專案底下有多個 App，你需要把這段內容加入你專案主要的 urls.py 裡面。
&lt;br/&gt;
&lt;br/&gt;
&lt;hr/&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;測試&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
請記得若你開啟 Debug 模式，剛剛設定的頁面是沒有辦法正常呈現的。你必須要到 settings.py 中把 Debug 模式關閉才能看到結果。
&lt;pre&gt;&lt;code class=&quot;round5px python&quot;&gt;DEBUG = False&lt;/code&gt;&lt;/pre&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;hr/&gt;
Environment :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;Debian&lt;br /&gt;
Reference :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;&lt;a href=&quot;https://docs.djangoproject.com/en/1.11/topics/http/views/&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;Django - Writing views&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/654226156800277529'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/654226156800277529'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/05/django-error-404-django-customized.html' title='Django 實作教學 - 自訂 Error 404 頁面 ( Django - Customized error 404 view for your applications )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-2826512771920544847</id><published>2017-05-02T16:09:00.001+08:00</published><updated>2017-10-12T00:03:55.315+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Django"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Django 實作教學 - 設定 Logging ( Django - Configure logging settings for your application )</title><content type='html'>我最常使用的 Python Web 框架為 Tornado，但因其他專案需要而重回 Django 的懷抱。因此接下來將會慢慢地將遇到的問題與心得做個紀錄。本篇將介紹如何設定 Django 的 Logging。( 其他 Django 相關教學可以參考&lt;a href=&quot;https://hatemegalaxy.blogspot.com/2017/10/django-useful-tutorials-for-django-web.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;本篇整理&lt;/span&gt;&lt;/a&gt;。If you want to read this article in English, you can visit &lt;a href=&quot;https://devforgalaxy.github.io/en/2017/04/29/django-configure-logging-settings-en.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;here&lt;/span&gt;&lt;/a&gt; )&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br/&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;前置作業&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
在開始設定之前，若你還沒將環境建立起來的話，先安裝 Django 並建立專案：
&lt;pre&gt;&lt;code class=&quot;round5px bash&quot;&gt;# 安裝 Django
python -m pip install Django

# 查看 Django 版本
python -m django --version

# 建立 Django 專案
django-admin startproject &amp;lt;project-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
專案預設結構如下：
&lt;pre&gt;&lt;code class=&quot;round5px python&quot;&gt;project-name/
├── project-name
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;了解 Logging 設定&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
Django 所提供的 Logging 設定很靈活，但也因為這樣反而一開始會有點不知所措。所以，先來了解大項目然後接著深入了解細部設定。Logging 設定基本上是存放於 &lt;span style=&quot;color: #93c47d;&quot;&gt;settings.py&lt;/span&gt; 檔案中，預設的設定檔不會有 Logging 相關參數，所以你需要自行加入，內容如下：
&lt;pre&gt;&lt;code class=&quot;python round5px&quot;&gt;LOGGING = {
    &#39;version&#39;: 1,
    &#39;disable_existing_loggers&#39;: False,
    &#39;formatters&#39;: {
        # TODO
    },
    &#39;handlers&#39;: {
        # TODO
    },
    &#39;loggers&#39;: {
        # TODO
    },
    &#39;filters&#39;: {
        # TODO
    },
}
&lt;/code&gt;&lt;/pre&gt;
目前你主要需要了解的部分為 formatters、handlers、loggers：
&lt;ul style=&quot;line-height: 190%;&quot;&gt;
&lt;li&gt;formatters：代表你想要怎麼顯示你的 Log，類似建立模板的概念。&lt;/li&gt;
&lt;li&gt;handlers：代表你想要怎麼處理你的 Log，試想如果我有非例行的任務，我可能只需要它顯示於 Console 或者存放在不同的地方，因此這時候我們就可以使用不同的 Handler 來處理。&lt;/li&gt;
&lt;li&gt;loggers：這部分代表我們將前兩項組合起來形成一個&quot;模組&quot;，這樣方便我們在程式中使用。&lt;/li&gt;
&lt;/ul&gt;
以下以一個簡單的圖來描述它們彼此的關係：
&lt;br/&gt;&lt;br/&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggLi0tkdmBwaGcbo_FGgZ85bRZPMZVPQCrI_mIzHIh0WSwH8HvinUYNekyGlf9iAem7eGcYk81UlLL2XvUA0zNwtwgkuMXfOAxNYaD1-mImJwQmEG8P_W0BA0rkdDKtQmyx-5sF7sQRv6I/s1600/logging.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggLi0tkdmBwaGcbo_FGgZ85bRZPMZVPQCrI_mIzHIh0WSwH8HvinUYNekyGlf9iAem7eGcYk81UlLL2XvUA0zNwtwgkuMXfOAxNYaD1-mImJwQmEG8P_W0BA0rkdDKtQmyx-5sF7sQRv6I/s1600/logging.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;Formatters 設定&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
了解大致上的內容，讓我們來了解細部設定，首先針對 formatters，以下是範例：
&lt;pre&gt;&lt;code class=&quot;python round5px&quot;&gt;    &#39;formatters&#39;: {
        &#39;your-formatter&#39;: {
            &#39;()&#39;: &#39;django.utils.log.ServerFormatter&#39;,
            &#39;format&#39;: &#39;[%(asctime)s] %(message)s&#39;,
        }
    },
&lt;/code&gt;&lt;/pre&gt;
你需要注意的部分是 format 參數：
&lt;ul style=&quot;line-height: 190%;&quot;&gt;
&lt;li&gt;%(asctime)s：代表我想使用我們比較習慣的時間格式，如：2003-07-08 16:49:45,896。&lt;/li&gt;
&lt;li&gt;%(message)s：代表欲輸出的訊息。&lt;/li&gt;
&lt;/ul&gt;
所以到時候 Log 產生時會顯示：
&lt;pre&gt;&lt;code class=&quot;python round5px&quot;&gt;[2017-04-26 11:07:33,380] Your message is here&lt;/code&gt;&lt;/pre&gt;
當然我們有更多的選項（如不同的時間格式、其他資訊）可以使用，請參考&lt;a href=&quot;https://docs.python.org/3/library/logging.html#logrecord-attributes&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;這裡&lt;/span&gt;&lt;/a&gt;。
&lt;br/&gt;
&lt;br/&gt;
&lt;hr/&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;Handlers 設定&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
繼續設定 handlers 部分：
&lt;pre&gt;&lt;code class=&quot;python round5px&quot;&gt;    &#39;handlers&#39;: {
        &#39;web&#39;: {
            &#39;level&#39;: &#39;DEBUG&#39;,
            &#39;class&#39;: &#39;logging.FileHandler&#39;,
            &#39;filename&#39;: &#39;/path/to/your-web.log&#39;,
            &#39;formatter&#39;: &#39;your-formatter&#39;
        },
        &#39;other_service&#39;: {
            &#39;level&#39;: &#39;DEBUG&#39;,
            &#39;class&#39;: &#39;logging.FileHandler&#39;,
            &#39;filename&#39;: &#39;/path/to/your-other-service.log&#39;,
            &#39;formatter&#39;: &#39;your-formatter&#39;
        },
    },
&lt;/code&gt;&lt;/pre&gt;
這個部分你需要注意的設定如下：
&lt;ul style=&quot;line-height: 190%;&quot;&gt;
&lt;li&gt;level：Log 層級&lt;/li&gt;
&lt;li&gt;class：代表我們要怎麼處理 Log 訊息，例如寫入文字檔，或者輸出至 Console。此範例中，我們設定兩個 Handler 都要寫入文字檔，所以使用 logging.FileHandler。&lt;/li&gt;
&lt;li&gt;filename：若你要寫入文字檔，你需要指定檔案要存放在哪裡。&lt;/li&gt;
&lt;li&gt;formatter：代表我們要使用哪個模板（也就是我們剛剛前面設定的）。&lt;/li&gt;
&lt;/ul&gt;
若要取得更多設定的細節，請參考&lt;a href=&quot;https://docs.python.org/3/library/logging.config.html#logging-config-dictschema&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;這裡&lt;/span&gt;&lt;/a&gt;。
&lt;br/&gt;&lt;br/&gt;
&lt;hr/&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;Loggers 設定&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;

&lt;pre&gt;&lt;code class=&quot;python round5px&quot;&gt;    &#39;loggers&#39;: {
        &#39;your-logger&#39;: {
            &#39;handlers&#39;: [&#39;web&#39;],
            &#39;level&#39;: &#39;DEBUG&#39;,
            &#39;propagate&#39;: True,
        },
    },
&lt;/code&gt;&lt;/pre&gt;
這部分需要注意的設定：
&lt;ul style=&quot;line-height: 190%;&quot;&gt;
&lt;li&gt;handlers：指定哪個 Handler 來處理，注意這邊可以指定多個。&lt;/li&gt;
&lt;li&gt;level：Log 層級。&lt;/li&gt;
&lt;/ul&gt;
至於 propagate 則需要另一個篇幅來解釋比較恰當，或者你可以參考&lt;a href=&quot;https://docs.djangoproject.com/en/1.11/topics/logging/&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;文件&lt;/span&gt;&lt;/a&gt;。
&lt;br/&gt;
&lt;br/&gt;
&lt;hr/&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;使用 Logging&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
在你的程式中加入：
&lt;pre&gt;&lt;code class=&quot;python round5px&quot;&gt;# Use logging library
import logging

# Get an instance of a logger
logger = logging.getLogger(&#39;your-logger&#39;)

# Log a message
logger.info(&#39;Your message is here.&#39;)
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Environment :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;Debian&lt;br /&gt;
Reference :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;&lt;a href=&quot;https://docs.djangoproject.com/en/1.11/topics/logging/&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;Django - Logging&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/2826512771920544847'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/2826512771920544847'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/05/django-logging-django-configure-logging.html' title='Django 實作教學 - 設定 Logging ( Django - Configure logging settings for your application )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggLi0tkdmBwaGcbo_FGgZ85bRZPMZVPQCrI_mIzHIh0WSwH8HvinUYNekyGlf9iAem7eGcYk81UlLL2XvUA0zNwtwgkuMXfOAxNYaD1-mImJwQmEG8P_W0BA0rkdDKtQmyx-5sF7sQRv6I/s72-c/logging.png" height="72" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-9103145001048201881</id><published>2017-04-15T01:34:00.000+08:00</published><updated>2017-08-03T00:57:13.941+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Hubot"/><title type='text'>Hubot 教學 (2) - 安裝與設定 Hubot ( Install and set up your first Hubot )</title><content type='html'>在&lt;a href=&quot;http://hatemegalaxy.blogspot.com/2017/04/hubot-1-nodejs-npm-install-nodejs-and.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;上一篇&lt;/span&gt;&lt;/a&gt;教學中，我們已經將 Node.js 與 npm 安裝好，本篇將繼續介紹如何安裝與設定你的第一個 Hubot。(If you want to read this article in English, you can visit &lt;a href=&quot;https://devforgalaxy.github.io/en/2017/04/14/install-and-set-first-hubot-en.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;here&lt;/span&gt;&lt;/a&gt;)&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br/&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;前置作業&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
開始之前，再確認一下你有成功安裝 Node.js 與 npm，指令如下：
&lt;pre&gt;&lt;code class=&quot;round5px bash&quot;&gt;# 查看 Node.js 版本
nodejs -v

# 查看 npm 版本
npm -v
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;安裝 Yo 與 Hubot Generator&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #6fa8dc;&quot;&gt;Yo&lt;/span&gt; 是一個讓我們快速建立專案架構的工具，我們可以透過定義一個 &lt;span style=&quot;color: #6fa8dc;&quot;&gt;Generator&lt;/span&gt; 描述專案的結構。幸運的是 Github 團隊已經提供一個 Generator 讓我們可以利用 Yo 來輕鬆的建立我們的第一個 Hubot。透過 npm 安裝 Yo 與 Hubot Generator，指令如下：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;# 安裝 yo 與 Hubot Generator
npm install -g yo generator-hubot
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;建立 Hubot&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
剛剛介紹我們會用 Yo 建立 Hubot，但是如果你是以 root 身份執行的話，會遇到很多的問題。所以建議使用不同的身份來執行 Yo，你也可以為了 Hubot 新增一個系統使用者，新增指令如下：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;# 新增使用者 hubot-user
useradd -d /hubot-user -m -s /bin/bash -U hubot-user
&lt;/code&gt;&lt;/pre&gt;
切換好使用者後，接著建立一個資料夾專屬於 Hubot，然後在該資料夾下透過 Yo 建立一個 Hubot，指令如下：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;# 建立資料夾
mkdir hellohubot

# 切換至該資料夾
cd hellohubot

# 建立 Hubot，這邊假設我們要結合 Hubot 與 Slack，所以加上 --adapter=slack
yo --no-insight hubot \
   --owner=&quot;your-name&quot; \
   --name=&quot;bot-name&quot; \
   --description=&quot;Put some content here&quot; \
   --adapter=slack
&lt;/code&gt;&lt;/pre&gt;
初始化完成後，你可以開始測試 Hubot 是否可以正常運作，Hubot 啟動指令：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;bin/hubot --adapter slack&lt;/code&gt;&lt;/pre&gt;
目前 Hubot 還不能為我們提供任何自訂的服務，接著&lt;a href=&quot;http://hatemegalaxy.blogspot.com/2017/05/hubot-3-scripts-create-scripts-for-your.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;下一篇&lt;/span&gt;&lt;/a&gt;我們要替 Hubot 增加 Scripts 讓它活起來。
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Environment :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;Debian&lt;br /&gt;
Reference :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;&lt;a href=&quot;https://hubot.github.com/&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;Hubot&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/9103145001048201881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/9103145001048201881'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/04/hubot-2-hubot-install-and-set-up-your.html' title='Hubot 教學 (2) - 安裝與設定 Hubot ( Install and set up your first Hubot )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-4982761034606963936</id><published>2017-04-15T01:30:00.001+08:00</published><updated>2017-08-03T00:58:01.118+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Hubot"/><title type='text'>Hubot 教學 (1) - 安裝 Node.js 與 npm ( Install Node.js and npm for Hubot )</title><content type='html'>Hubot 是一個很優秀自動化工具，你可以很輕鬆的將它結合其他服務如 Google Map、Skype、Slack 等等，所以接下來的文章將介紹如何從無到有透過 Hubot 建立自己的自動化工具，本篇文章將如何準備所需環境步驟記錄下來。(If you want to read this article in English, you can visit &lt;a href=&quot;https://devforgalaxy.github.io/en/2017/04/04/install-nodejs-and-npm-for-hubot-en.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;here&lt;/span&gt;&lt;/a&gt;)&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br/&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;前置作業&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
接下來將在 Debian 上示範所有的步驟，所以在開始安裝 Node.js 與 npm 之前，我們先更新套件管理工具與下載所需軟體：
&lt;pre&gt;&lt;code class=&quot;round5px bash&quot;&gt;# 更新
apt-get -y update

# 安裝 curl
apt-get -y install curl
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;安裝 Node.js 與 npm&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
基本上我們可以透過 &lt;span style=&quot;color: #c27ba0;&quot;&gt;apt-get&lt;/span&gt; 來安裝 Node.js，但是版本會是比較舊的。所以我們可以利用以下方法來安裝較新的版本：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;# 安裝 Node.js 版本 6.X
curl -sL https://deb.nodesource.com/setup_6.x | bash -
apt-get -y install nodejs

# 安裝 Node.js 版本 7.X
curl -sL https://deb.nodesource.com/setup_6.x | bash -
apt-get -y install nodejs
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;確認安裝版本&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
安裝好後，確認一下我們安裝的版本，指令如下：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;# 查看 Node.js 版本
nodejs -v

# 查看 npm 版本
npm -v
&lt;/code&gt;&lt;/pre&gt;
如此一來我們就完成環境的設定，接著繼續&lt;a href=&quot;http://hatemegalaxy.blogspot.com/2017/04/hubot-2-hubot-install-and-set-up-your.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;下一篇：Hubot 教學 (2) - 安裝與設定 Hubot&lt;/span&gt;&lt;/a&gt;。
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Environment :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;Debian&lt;br /&gt;
Reference :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;&lt;a href=&quot;https://nodejs.org/en/&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;Node.js&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/4982761034606963936'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/4982761034606963936'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/04/hubot-1-nodejs-npm-install-nodejs-and.html' title='Hubot 教學 (1) - 安裝 Node.js 與 npm ( Install Node.js and npm for Hubot )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-3490626191880516204</id><published>2017-03-14T17:38:00.000+08:00</published><updated>2017-08-03T00:59:10.368+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>PyPy - 安裝與使用 pip ( Install pip and use it with PyPy )</title><content type='html'>隨著 PyPy 日趨成熟，未來將會有更多機會使用它，因此本篇將如何替 PyPy 安裝 &lt;span style=&quot;color: #6fa8dc;&quot;&gt;pip (package manager)&lt;/span&gt; 與其使用方式做個簡單的紀錄。(If you want to read this article in English, you can visit &lt;a href=&quot;https://devforgalaxy.github.io/en/2017/03/13/install-and-use-pip-for-pypy-en.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;here&lt;/span&gt;&lt;/a&gt;)&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br/&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;前置作業&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
在安裝 pip 之前，當然需要先將 PyPy 安裝好。此篇教學將在 Debian 上示範，安裝 PyPy 的指令為：
&lt;pre&gt;&lt;code class=&quot;round5px bash&quot;&gt;# 更新
apt-get -y update

# 安裝 PyPy 與 curl
apt-get -y install curl pypy
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;安裝 pip&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
安裝 pip 相當簡單，指令如下：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;# 安裝 pip
curl https://bootstrap.pypa.io/get-pip.py | pypy

# 更新 pip
pypy -m pip install --upgrade pip
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;使用 pip&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
使用方式如下：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;# 安裝 module
# 範例：pypy -m pip install [module-name]
pypy -m pip install requests

# 移除 module
# 範例：pypy -m pip uninstall [module-name]
pypy -m pip uninstall requests
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
Environment :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;Debian&lt;br /&gt;
Reference :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;&lt;a href=&quot;https://pypy.org/&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;PyPy&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/3490626191880516204'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/3490626191880516204'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/03/pypy-pip-install-pip-and-use-it-with.html' title='PyPy - 安裝與使用 pip ( Install pip and use it with PyPy )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-3353788455951402202</id><published>2017-03-08T19:09:00.000+08:00</published><updated>2017-08-03T00:59:48.234+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Cassandra"/><title type='text'>Cassandra - 透過安裝與啟用 JNA 提升效能 ( Install and enable JNA for improving Cassandra performance )</title><content type='html'>Cassandra 有許多參數可以調整效能，其中安裝與啟用 &lt;span style=&quot;color: #6fa8dc;&quot;&gt;JNA (Java Native Access)&lt;/span&gt; 可以改善 Cassandra 記憶體方面效能。本篇將介紹如何替 Cassandra 安裝與啟用 JNA。( If you want to read this article in English, you can visit &lt;a href=&quot;https://devforgalaxy.github.io/en/2017/03/06/install-jna-for-improving-cassandra-performance-en.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;here&lt;/span&gt;&lt;/a&gt;&amp;nbsp;)&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br/&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;前置作業&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
此篇教學主要是利用 Docker 來建立 Cassandra 運作環境，所以你需要確認你的機器上已經安裝 Docker ( 參考&lt;a href=&quot;http://hatemegalaxy.blogspot.com/2016/02/docker-1-docker-mac-os-x-install-docker.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;如何安裝 Docker&lt;/span&gt;&lt;/a&gt; )。
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;啟動 Cassandra&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
透過 Docker 來啟用 Cassandra 相當方便 (使用 Spotify 的 Cassandra Docker Image 為範例)，執行：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;# 啟用 Cassandra 並開啟 9160 與 9042 Port
docker run -d \
           -p 9160:9160 \
           -p 9042:9042 \
           --ulimit memlock=-1:-1
           --name cassandra spotify/cassandra
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;安裝 JNA (Java Native Access)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
接著透過 &lt;span style=&quot;color: #a64d79;&quot;&gt;apt-get&lt;/span&gt; 安裝 JNA：
&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;python round5px&quot;&gt;# 安裝 JNA
apt-get install -y libjna-java

# 建立鏈結
ln -s /usr/share/java/jna.jar /usr/share/cassandra/lib/
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;確認安裝是否成功&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
重新啟動 Cassandra：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;docker restart cassandra&lt;/code&gt;&lt;/pre&gt;
若安裝與設定都沒有問題的話，你會在 Log 中看到 JNA mlockall successful 訊息。監看 Log 指令：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;docker logs -f cassandra&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
Environment :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;macOS&lt;br /&gt;
Reference :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;&lt;a href=&quot;https://github.com/spotify/docker-cassandra&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;Spotify Cassandra Docker Image&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/3353788455951402202'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/3353788455951402202'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/03/cassandra-jna-install-and-enable-jna.html' title='Cassandra - 透過安裝與啟用 JNA 提升效能 ( Install and enable JNA for improving Cassandra performance )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-8234469307359212140.post-6134429760777240776</id><published>2017-02-28T15:18:00.000+08:00</published><updated>2017-08-03T01:00:37.462+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="AWS"/><title type='text'>AWS - 在 Amazon Linux 上安裝 Docker ( Install Docker on Amazon Linux )</title><content type='html'>Amazon 已經推出 EC2 Container Service 一陣子了，但本篇還是將如何自行在 Amazon Linux 上安裝 Docker 的步驟記錄下來。( 其他 AWS 相關教學可以參考&lt;a href=&quot;http://hatemegalaxy.blogspot.com/2015/12/aws-useful-tutorial-for-aws.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;本篇整理&lt;/span&gt;&lt;/a&gt;。If you want to read this article in English, you can visit &lt;a href=&quot;https://devforgalaxy.github.io/en/2017/02/26/install-docker-on-amazon-linux-en.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #6fa8dc;&quot;&gt;here&lt;/span&gt;&lt;/a&gt;&amp;nbsp;)&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;script async src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot;
     style=&quot;display:block; text-align:center;&quot;
     data-ad-format=&quot;fluid&quot;
     data-ad-layout=&quot;in-article&quot;
     data-ad-client=&quot;ca-pub-9161307949139214&quot;
     data-ad-slot=&quot;1131030106&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;br /&gt;&lt;br/&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;前置作業&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
我們將在 EC2 實體上安裝 Docker，所以請確認你已經建立實體 (Amazon Linux AMI)。接著透過金鑰 SSH 至 EC2：
&lt;pre&gt;
&lt;code class=&quot;bash round5px&quot;&gt;# 首先將金鑰設定為唯讀
chmod 400 /path/to/your/ec2.pem

# SSH 至 EC2，預設帳號為 ec2-user
ssh -i &quot;ec2.pem&quot; ec2-user@ip
&lt;/code&gt;
&lt;/pre&gt;
&lt;br/&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;安裝 Docker&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
接下來便開始安裝 Docker，指令：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;# 更新
sudo yum update -y

# 安裝 Docker
sudo yum install -y docker

# 安裝完，可以查看版本
sudo docker -v

# 查看 Docker 相關資訊
sudo docker info
&lt;/code&gt;&lt;/pre&gt;
若你不想每次都透過 sudo 執行 Docker 指令，我們可以將 ec2-user 加入 Docker 群組：
&lt;pre&gt;&lt;code class=&quot;bash round5px&quot;&gt;# 加入 Docker group，記得要重新登入才會生效
sudo usermod -a -G docker ec2-user
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;啟用、停止 Docker&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
Docker 就如同一般的服務，我們可以手動啟用與停止，指令：
&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;python round5px&quot;&gt;# 啟動
sudo service docker start

# 停止
sudo service docker stop
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;hr /&gt;
Environment :&lt;br /&gt;
&lt;b&gt;&amp;nbsp; ・&amp;nbsp;&lt;/b&gt;Amazon Linux&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/6134429760777240776'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8234469307359212140/posts/default/6134429760777240776'/><link rel='alternate' type='text/html' href='http://hatemegalaxy.blogspot.com/2017/02/amazon-linux-docker-install-docker-on.html' title='AWS - 在 Amazon Linux 上安裝 Docker ( Install Docker on Amazon Linux )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry></feed>