之前曾用過Extjs一段時間, 但總覺得Extjs的運作方式傾向於使用整個頁面作為一個Application的介面, 這另我很難簡單地在其他網頁上內嵌一些Extjs的Component, 而又不影響網頁本來的樣子, 最終放棄了這個使用方式.
最近突然想把Extjs的GridPanel放在一個用Bootstrap用theme的網頁上, 因為GridPanel實在做得很好, 不用有點可惜, 於是研究了一下
首先要在Html裡導入Extjs的js及css檔, 我用的是Extjs的gray theme, Extjs版本是4.2, css檔是/resources/ext-theme-gray/ext-theme-gray-all.css這個file. 導入後一看, 整個頁面的字型, 大小, 排版等都有些走樣了, 其原因主要是ext-theme-gray-all.css裡的一些CSS被應用到Extjs以外的DOM裡, 需要作以下修改:
.x-body { margin:0 }
Extjs會強制為body加上x-body這個class, 這有可能會對網頁做成影響, 而x-body只有這個margin:0的Style, 所以可以把x-body改成其他不會用的字串.
.x-border-box, .x-border * { box-sizing:borderbox;-moz-box-sizing:border-box;-ms-box-sizing:border-box;-webkit-box-sizing:border-box}
這個規則會同樣被應用到很多DOM上, 我把.x-border *改成.x-border .x-panel *, 這樣只有x-panel內的DOM會被加上border-box, 我只需要用GridPanel, 這已經夠了, 如果以後發現其他有些Extjs的Component不正常可以再修改
另外Bootstrap的CSS會設定lineheight, 這會導致Extjs的MessageBox有些走樣, 以後需要用到再看看怎樣解決
2013年4月18日 星期四
2012年12月3日 星期一
Composer簡介
什麼是Composer?
Composer是一個PHP的"dependency management"工具, 它能讓你指定你的Project裡需要用到的"dependent libraries", 並安娤這些libraries到你的project裡.Dependency management
Composer不是"package manager", 雖然它是處理packages, 但它是在project的層面上管理, 通常是在project的根目錄下建立一個叫vendor的directory, 然後把packages安裝到這個directory裡. 一般情況下它不會安裝global的packages.Composer解決的問題
- 你有一個project需要數個libraries.
- 在那些libraries當中, 有些需要依頼其他libraries.
- 你能自己定義你的project所依賴的libraries
- Composer找出所需安裝的packages及versions, 並安裝(事實上是下載)到project的vendor目錄
安裝
要安裝Composer, 在你的project的根目錄下執行
$ curl -s https://getcomposer.org/installer | php
以上指令會先檢查PHP的設定然後下載composer.phar到你的目錄下.
要執行composer, 執行
php composer.phar
如果你想直接以composer執行, 可以把composer.phar 複制到/usr/local/bin中
$ sudo mv composer.phar /usr/local/bin/composer
定義dependencies
例如你需要在你的project裡用monolog, 先建立composer.json, 內容為
{ "require": { "monolog/monolog": "1.2.*" } }
require傳入的物件格式為{ "vendor name/package name" : "version" }
version可以是:
- Exact version: 如1.0.2
- Range: 如>=1.0,<2.0
- Wildcard: 1.0.*
- Next Significant Release: 如 ~1.2(相當於>=1.2,<2.0)
使用
執行以下指定, Composer會自動安裝你所定義的dependencies
$ php composer.phar install
composer.lock及composer.json
Composer執行install後會把安裝過的packages寫入composer.lock中, 而Composer每次執行install時會先確認composer.lock是否存在, 如果存在則安裝composer.lock中的packages, 不會理會composer.json, 如不存在則以composer.json裡的packages內容建立composer.lock. 所以執行install不會自動升級packages, 要升級需執行
$php composer.phar update
2012年10月25日 星期四
Symfony2 console commands
# Generate Bundle. php app/console generate:bundle --namespace="My/Bundle" --format=ymlDoctrine
# Create database. php app/console doctrine:database:create
# Generate Entity. php app/console doctrine:generate:entity --entity="MyBundle:MyEntity"
# Generate Entities getters and setters. php app/console doctrine:generate:entities MyBundle
# Update schema. php app/console doctrine:schema:update --force
# Generate CRUD. php app/console doctrine:generate:crud --entity="MyBundle:MyEntity"Asset
# Install assets into web folder with symlink. php app/console assets:install web --symlink
2012年10月24日 星期三
Doctrine以Composite及Foreign Keys作主鍵(Primary Key)
Doctrine2 可以用composite keys作為primary key(例如用戶的姓加名字作為主鍵), 而Doctrine2.1更支援關聯的foreign key.
方法很簡單:
- Entity內不能有@GeneratedValue, 除非設定為"ASSIGNED".
- 在需要作為primary key的property加上@Id這個annotation.
- 需要__construct() 方法在建立物件時傳入作為primary key的property, 因為primary key不是自動生成, 沒有primary key呼叫EntityManager#persist()會有問題.
<?php use Doctrine\Common\Collections\ArrayCollection; /** @Entity */ class Order { /** @Id @Column(type="integer") @GeneratedValue */ private $id; /** @ManyToOne(targetEntity="Customer") */ private $customer; /** @OneToMany(targetEntity="OrderItem", mappedBy="order") */ private $items; /** @Column(type="boolean") */ private $payed = false; /** @Column(type="boolean") */ private $shipped = false; /** @Column(type="datetime") */ private $created; public function __construct(Customer $customer) { $this->customer = $customer; $this->items = new ArrayCollection(); $this->created = new \DateTime("now"); } } /** @Entity */ class Product { /** @Id @Column(type="integer") @GeneratedValue */ private $id; /** @Column(type="string") */ private $name; /** @Column(type="decimal") */ private $currentPrice; public function getCurrentPrice() { return $this->currentPrice; } } /** @Entity */ class OrderItem { /** @Id @ManyToOne(targetEntity="Order") */ private $order; /** @Id @ManyToOne(targetEntity="Product") */ private $product; /** @Column(type="integer") */ private $amount = 1; /** @Column(type="decimal") */ private $offeredPrice; public function __construct(Order $order, Product $product, $amount = 1) { $this->order = $order; $this->product = $product; $this->offeredPrice = $product->getCurrentPrice(); } }參考資料: http://docs.doctrine-project.org/projects/doctrine-orm/en/2.1/tutorials/composite-primary-keys.html
2008年6月18日 星期三
MySQL的一些操作技巧
如果要backup MySQL database, 可以用mysqldump save成text file, 可以保存整個database或個別table, 要restore時可以在mysql 裡用source filename即可.
MySQL statement裡可以用變數來增加變化, 如想在select的result裡最左邊加一個column來表示行數, 而這個行數本身沒有記錄在table裡, 是select statement執行的時間動態產生.方法是:
1. set @v1=0;
(這裡是宣告一個叫@v1的變數, 值為0)
2. select @v1:=@v1+1, name from table;
(這裡是把最左邊的column定為@v1, 而@v1每次都會+1, 所以可以代表行數, 也可以混合其他function, 如 concat('no. ',@v1:=@v1+1) 這樣行數會變成"no. 1", "no. 2", ...)
p.s. 要注意是用":="而不是平常statement用的"="
MySQL statement裡可以用變數來增加變化, 如想在select的result裡最左邊加一個column來表示行數, 而這個行數本身沒有記錄在table裡, 是select statement執行的時間動態產生.方法是:
1. set @v1=0;
(這裡是宣告一個叫@v1的變數, 值為0)
2. select @v1:=@v1+1, name from table;
(這裡是把最左邊的column定為@v1, 而@v1每次都會+1, 所以可以代表行數, 也可以混合其他function, 如 concat('no. ',@v1:=@v1+1) 這樣行數會變成"no. 1", "no. 2", ...)
p.s. 要注意是用":="而不是平常statement用的"="
2008年5月14日 星期三
Drupal
安裝好Drupal, cleanURL無法啟動, drupal.org中提到需要在/etc/httpd/conf/http.conf中uncomment
LoadModule rewrite_module modules/mod_rewrite.so 這行才可以.
但照做了也一樣無法啟動, 後來看下去才知道要加
<Directory "/var/www/html/drupal-6.2">
AllowOverride All
</Directory>
加了以後就能啟動
2008年4月7日 星期一
find 指令 time 選項及 xargs 一起使用
今天看了一下catchall的mailbox, 有9萬多封郵件, 我的postfix是以directory方式儲存郵件,每個郵件都是一個檔案, 開次一打開這個資料夾都很慢, 所以想按日期分類, 減少單一資料夾的檔案數.
我的catchall是以IMAP連接dovecot的式, 需要先create 一些按日期的資料夾, 以2008-01, 2008-02, ...的分類成式, 由於每個用也有兩萬封, 還是太多, 所以再在每個月裡create 01-10, 11-20, 11-31資料夾, 按日分類, 兩這些資料夾的實際path是在catchall Maildir/.INBOX.2008-01.01-10, Maildir/.INBOX.2008-01.11-20, ...把郵件按日期move到這些folder裡的new或cur即可(dovecot會在IMAP登入時把郵件從new移到cur).
但catchall inbox的郵件太多, 執行ls等指令很慢, 單用mv 及 rm等指令一次也不能處理太多檔案. 其中一個辦法是以find找到想移動的檔案再用xargs送到mv處理, find 能處理的檔案很多, 但好像也有限(至少9萬個處理不了, 會直接停止執行), 所以find的使用要有點技巧.
find的功能很多, 這次要以郵件檔的modification time來判斷它到達server的時間, 所以要用mtime選項(因為ctime在移動後會改為移動的時間, 所以執行第二次已經不能判斷).
find . -mtime n 當中 . 為目前路徑搜尋, n 為數字, 代表多少個24小時. mtime default是以當前時間的n*24小時計算, 如果想要以當日的24:00作基準(實際是向未來的時間方向移動,即明日的00:00的n*24小時計算),需要加上-daystart參數.
n 的數值為 0 時代表現在到24小時前之間, 加上daystart代表現在到今天00:00之間
n 的數值為 1 時代表24小時前到48小時前之間, 加上daystart代表今天00:00到昨天00:00之間(即整個昨天)
n 還可以加+或-, 分別代表1(24小時前到48小時前的時段)的兩邊, 但不包括1, 即-1代表現在(理論上是無限的未來)到24小時前的時段, +1代表48小時及之前(理論上是無限的過去)的時段. -0應該沒有任何結果, 除非有未來建做的檔案存在, 有這樣的檔案應該是電腦的時間調校錯了.
之外mtime可以組會使用, 如:
find . -mtime +1 -mtime -3 這裡指48小時前及未到72小時之間, 相當於 -mtime 2.
了解mtime的用法後回到剛才的一個問題上, find遇到超出數量時也不能運作, 所以在我那個有9萬個files的folder上使用時需要些技巧, 經我測試發覺組合的mtime是由左至右執行,例如我想找48小時前至72小時前之間的files, 需要用 -mtime +1 及 -mtime -3, 如果是:
find . -mtime +1 -mtime -3 這樣會先執行 +1 , 即所有48小時前的檔案, 以我的情況是至少有8萬多個, 一段時間後自動跳出執行, 沒有結果. 相反:
find . -mtime -3 -mtime +1 這樣會先執行 -3, 現在至72小時前之間, 有幾千, 沒有超出限量, 跟著再以 +1把現在至48小時前之間的除去, 得到我想要的結果.
以find 找到檔案後要送給xargs再執行mv:
find . -mtime -3 -time +1 | xargs -i mv {} destination.
當中 -i 代表用{}代表前面送來的結果(這裡即find的結果), {}代表find的結果, 並作為mv的source, destination代表目標路徑.
除了-i外可以用 -I, 差別是-I可以指定代表結果的字完, 如:
xargs -i mv {} /tmp
相當於:
xargs -I [] mv [] /tmp
最後成功把emails按日期分類.
我的catchall是以IMAP連接dovecot的式, 需要先create 一些按日期的資料夾, 以2008-01, 2008-02, ...的分類成式, 由於每個用也有兩萬封, 還是太多, 所以再在每個月裡create 01-10, 11-20, 11-31資料夾, 按日分類, 兩這些資料夾的實際path是在catchall Maildir/.INBOX.2008-01.01-10, Maildir/.INBOX.2008-01.11-20, ...把郵件按日期move到這些folder裡的new或cur即可(dovecot會在IMAP登入時把郵件從new移到cur).
但catchall inbox的郵件太多, 執行ls等指令很慢, 單用mv 及 rm等指令一次也不能處理太多檔案. 其中一個辦法是以find找到想移動的檔案再用xargs送到mv處理, find 能處理的檔案很多, 但好像也有限(至少9萬個處理不了, 會直接停止執行), 所以find的使用要有點技巧.
find的功能很多, 這次要以郵件檔的modification time來判斷它到達server的時間, 所以要用mtime選項(因為ctime在移動後會改為移動的時間, 所以執行第二次已經不能判斷).
find . -mtime n 當中 . 為目前路徑搜尋, n 為數字, 代表多少個24小時. mtime default是以當前時間的n*24小時計算, 如果想要以當日的24:00作基準(實際是向未來的時間方向移動,即明日的00:00的n*24小時計算),需要加上-daystart參數.
n 的數值為 0 時代表現在到24小時前之間, 加上daystart代表現在到今天00:00之間
n 的數值為 1 時代表24小時前到48小時前之間, 加上daystart代表今天00:00到昨天00:00之間(即整個昨天)
n 還可以加+或-, 分別代表1(24小時前到48小時前的時段)的兩邊, 但不包括1, 即-1代表現在(理論上是無限的未來)到24小時前的時段, +1代表48小時及之前(理論上是無限的過去)的時段. -0應該沒有任何結果, 除非有未來建做的檔案存在, 有這樣的檔案應該是電腦的時間調校錯了.
之外mtime可以組會使用, 如:
find . -mtime +1 -mtime -3 這裡指48小時前及未到72小時之間, 相當於 -mtime 2.
了解mtime的用法後回到剛才的一個問題上, find遇到超出數量時也不能運作, 所以在我那個有9萬個files的folder上使用時需要些技巧, 經我測試發覺組合的mtime是由左至右執行,例如我想找48小時前至72小時前之間的files, 需要用 -mtime +1 及 -mtime -3, 如果是:
find . -mtime +1 -mtime -3 這樣會先執行 +1 , 即所有48小時前的檔案, 以我的情況是至少有8萬多個, 一段時間後自動跳出執行, 沒有結果. 相反:
find . -mtime -3 -mtime +1 這樣會先執行 -3, 現在至72小時前之間, 有幾千, 沒有超出限量, 跟著再以 +1把現在至48小時前之間的除去, 得到我想要的結果.
以find 找到檔案後要送給xargs再執行mv:
find . -mtime -3 -time +1 | xargs -i mv {} destination.
當中 -i 代表用{}代表前面送來的結果(這裡即find的結果), {}代表find的結果, 並作為mv的source, destination代表目標路徑.
除了-i外可以用 -I, 差別是-I可以指定代表結果的字完, 如:
xargs -i mv {} /tmp
相當於:
xargs -I [] mv [] /tmp
最後成功把emails按日期分類.
訂閱:
文章
(
Atom
)