PerlでHTMLの繰り返し部分をインクリメントしてみた
HTMLの構築とかしてると、やたら繰り返す部分が多い。
で、画像ファイルだけ差し替えてみたいな。
私は、好み的に画像ファイル名を【『ファイル名』+連番】にしているので、
これは、自動化できるんじゃないかと思った。
はじめは、Emacsとかチューンできるテキストエディタを使おうか
なんてことも考えた。Lispも覚えたら幸せになれそうだし。
しかし、よくよく考えるとPerlはテキストの編集に強みを持っているのが特徴だった。
そんな声がした気がしたので、Perlスクリプトを書いてみた。
美しくもなんともないスクリプトだが、不毛なコピペから解放された。
#!/usr/bin/perl # # 特定の位置にインクリメント数字を入れていってHTML構築を短縮化するスクリプト # 3つずつの<div class="unit">を<div class="three_unit clearfix">でくくる、というのを繰り返す # 20101230by_perl48 use strict; use warnings; use encoding qw(shiftjis); # 繰り返し回数を指定する my $max = 24; # ファイルハンドルをオープンして、外部テキストファイルへの書き込み準備 open my $writing, '>>', "dekiagari.txt"; for( my $i = 1; $i <= $max; $i ++ ){ # 1番目、4番目、7番目・・・に<div class="three_unit clearfix">を突っ込む if( $i % 3 == 1 ){ print $writing <<END_HEADER; <div class="three_unit clearfix"> END_HEADER } # <div class="unit">内の画像ファイル名末尾をインクリメントして複製していく print $writing <<END_OF_UNIT; <div class="unit"> <a href="/img/sem_pho2010-$i.jpg" rel="lightbox"><img src="/img/sem_pho2010-$i.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> END_OF_UNIT # 3番目、6番目、9番目・・・に</div>を突っ込む if( $i % 3 == 0 ){ print $writing <<END_FOOTER; </div> END_FOOTER } }
で、dekiagari.txt に出力されたのが下
<div class="three_unit clearfix"> <div class="unit"> <a href="/img/sem_pho2010-1.jpg" rel="lightbox"><img src="/img/sem_pho2010-1.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> <div class="unit"> <a href="/img/sem_pho2010-2.jpg" rel="lightbox"><img src="/img/sem_pho2010-2.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> <div class="unit"> <a href="/img/sem_pho2010-3.jpg" rel="lightbox"><img src="/img/sem_pho2010-3.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> </div> <div class="three_unit clearfix"> <div class="unit"> <a href="/img/sem_pho2010-4.jpg" rel="lightbox"><img src="/img/sem_pho2010-4.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> <div class="unit"> <a href="/img/sem_pho2010-5.jpg" rel="lightbox"><img src="/img/sem_pho2010-5.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> <div class="unit"> <a href="/img/sem_pho2010-6.jpg" rel="lightbox"><img src="/img/sem_pho2010-6.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> </div> <div class="three_unit clearfix"> <div class="unit"> <a href="/img/sem_pho2010-7.jpg" rel="lightbox"><img src="/img/sem_pho2010-7.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> <div class="unit"> <a href="/img/sem_pho2010-8.jpg" rel="lightbox"><img src="/img/sem_pho2010-8.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> <div class="unit"> <a href="/img/sem_pho2010-9.jpg" rel="lightbox"><img src="/img/sem_pho2010-9.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> </div> <div class="three_unit clearfix"> <div class="unit"> <a href="/img/sem_pho2010-10.jpg" rel="lightbox"><img src="/img/sem_pho2010-10.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> <div class="unit"> <a href="/img/sem_pho2010-11.jpg" rel="lightbox"><img src="/img/sem_pho2010-11.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> <div class="unit"> <a href="/img/sem_pho2010-12.jpg" rel="lightbox"><img src="/img/sem_pho2010-12.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> </div> <div class="three_unit clearfix"> <div class="unit"> <a href="/img/sem_pho2010-13.jpg" rel="lightbox"><img src="/img/sem_pho2010-13.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> <div class="unit"> <a href="/img/sem_pho2010-14.jpg" rel="lightbox"><img src="/img/sem_pho2010-14.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> <div class="unit"> <a href="/img/sem_pho2010-15.jpg" rel="lightbox"><img src="/img/sem_pho2010-15.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> </div> <div class="three_unit clearfix"> <div class="unit"> <a href="/img/sem_pho2010-16.jpg" rel="lightbox"><img src="/img/sem_pho2010-16.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> <div class="unit"> <a href="/img/sem_pho2010-17.jpg" rel="lightbox"><img src="/img/sem_pho2010-17.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> <div class="unit"> <a href="/img/sem_pho2010-18.jpg" rel="lightbox"><img src="/img/sem_pho2010-18.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> </div> <div class="three_unit clearfix"> <div class="unit"> <a href="/img/sem_pho2010-19.jpg" rel="lightbox"><img src="/img/sem_pho2010-19.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> <div class="unit"> <a href="/img/sem_pho2010-20.jpg" rel="lightbox"><img src="/img/sem_pho2010-20.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> <div class="unit"> <a href="/img/sem_pho2010-21.jpg" rel="lightbox"><img src="/img/sem_pho2010-21.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> </div> <div class="three_unit clearfix"> <div class="unit"> <a href="/img/sem_pho2010-22.jpg" rel="lightbox"><img src="/img/sem_pho2010-22.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> <div class="unit"> <a href="/img/sem_pho2010-23.jpg" rel="lightbox"><img src="/img/sem_pho2010-23.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> <div class="unit"> <a href="/img/sem_pho2010-24.jpg" rel="lightbox"><img src="/img/sem_pho2010-24.jpg" width="200" alt="" rel="lightbox[seminor]" /></a> <p>text</p> </div> </div>
EC-CUBEのディレクトリ構造をPerlで暴く
今月は、割とEC-CUBEを触ってみている。
EC-CUBEはSmartyというPHPのテンプレートエンジンをベースに作られている。
MVCモデル的だ。
ショップ用に作られているため、
カート・メルマガ・売上管理・顧客管理機能が標準で付いている。
まー、過剰な気もするけど。
MVCは、ModelとViewとControllerが分離していて、
作業の分担がキレイにできたり、相乗り部分が少ないため管理がしやすい
というのが売りのようだ。
話を聞く限りでは、確かに便利そうだ。
が、一人で全部修正する場合どうなんだろうとやってみて思った。
管理画面から登録できる商品項目を増やすために、
DBのカラムを増やし、増やした項目がEC-CUBE内の配列として読み込まれるように追記し、
管理画面の入力と確認のテンプレートを修正し、サブクエリー表示できるように追記。
で、やっとSmarty的な
とかいう変数が使えるようになった。
{$arrProduct.hoge|nl2br}
慣れの問題もあるけど、
「めんどくせぇ」
というのが正直な感想だった。
まー、でもこの程度の作業でカスタマイズができると考えれば
便利なんだろうなーと強引に納得。
そんなEC-CUBEたん、ディレクトリ構造の複雑さが半端ねぇんです。
Smarty勉強する前なんて
「templatesディレクトリ」と「templates_cディレクトリ」は、
ユーザを惑わせるための開発者の嫌がらせかと感じたくらいだったから。
まー、そんなこんなでEC-CUBEで見た目を触るときに
修正すべきファイル名はわかってるけどファイルの場所がわからん。
という事態に直面し、「ここはいっちょう、Perlで解決してやろうじゃないか!」
と思ったわけです。
コマンドプロンプトのtreeコマンドでは不満でした。
そのマシンの持つ純粋なポテンシャルを引き出すことこそが最大の喜び。
なーんて、オーバーレブに登場していた「ノーマルの狼」みたいなことを
言ってみましたが、自分の考えはそっち寄りです。
プログラミングにしても、システム構築にしても最も適した道具を選択し、
その道具のポテンシャルを使い切るのが良いなーと思ってます。
まー、実際使い切る所まではいかないわけですがw
そんな思想から、今回のEC-CUBEのディレクトリ構造解明も
はじめは、コマンドプロンプトで済ませようと考えてました。
tree /a /f > eccube_tree.txt
みたいに。
でも、出力結果が
6.php | |||
6.phps | |||
7.php | |||
7.phps | |||
8.php | |||
8.phps | |||
9.php | |||
9.phps | |||
index.html | |||
+---Engine | |||
Interface.php | |||
PearDate.php | |||
UnixTS.php | |||
+---Month | |||
Weekdays.php | |||
Weeks.php | |||
+---Table |
こんな感じになってしまって、
親ディレクトリまで辿るのにマウスホイールどんだけ回さなきゃなんだ!
と思いPerlでの解決に移りました。
File::FindモジュールでEC-CUBEのディレクトリ構造攻略
#! usr/bin/perluse strict;
use warnings;
use File::Find;open my $save, '>', './findName.txt' ;
find(\&fileProc, '.');
sub fileProc {
print $save "$File::Find::name\n";
}close $save;
こんなスクリプトを書いた出力結果が以下の通り
(この上は略)
./data/Smarty/templates/default/mypage/index.tpl
./data/Smarty/templates/default/mypage/login.tpl
./data/Smarty/templates/default/mypage/navi.tpl
./data/Smarty/templates/default/mypage/reading.tpl
./data/Smarty/templates/default/mypage/refusal.tpl
./data/Smarty/templates/default/mypage/refusal_complete.tpl
./data/Smarty/templates/default/mypage/refusal_confirm.tpl
./data/Smarty/templates/default/order
./data/Smarty/templates/default/order/index.tpl
./data/Smarty/templates/default/products
./data/Smarty/templates/default/products/customer_favorite_products.tpl
./data/Smarty/templates/default/products/detail_image.tpl
./data/Smarty/templates/default/products/review.tpl
./data/Smarty/templates/default/products/review_complete.tpl
./data/Smarty/templates/default/products/review_confirm.tpl
./data/Smarty/templates/default/regist
./data/Smarty/templates/default/regist/complete.tpl
./data/Smarty/templates/default/rss
./data/Smarty/templates/default/rss/index.tpl
./data/Smarty/templates/default/rss/product.tpl
./data/Smarty/templates/default/shopping
./data/Smarty/templates/default/shopping/card.tpl
./data/Smarty/templates/default/shopping/complete.tpl
./data/Smarty/templates/default/shopping/confirm.tpl
./data/Smarty/templates/default/shopping/convenience.tpl
./data/Smarty/templates/default/shopping/deliv.tpl
./data/Smarty/templates/default/shopping/index.tpl
./data/Smarty/templates/default/shopping/nonmember_input.tpl
./data/Smarty/templates/default/shopping/payment.tpl
./data/Smarty/templates_c
(この下も略)
これで、ファイル探しが楽になったー。
Perlハッシュのリファレンスを使いこなせるようになりますように。
慣れてくると欲が出てくるのは人間の常のようで、
1行ずつ処理していたものを、複数行まとめて処理したくなってしまった。
どう考えても、リファレンスを使わなきゃできそうにない。
ということで、ハッシュリファレンスと向き合ってみた。
まず、読み込むinput2.txt ファイルを準備。
まー、複数行まとめて処理したいナニガシだ。
秋葉原,1,1,1,1,1,1,1,1,1,1
恵比寿,2,2,2,2,2,2,2,2,2,2
新横浜,3,3,3,3,3,3,3,3,3,3
そして、「Perlって便利だなぁ」と思わせてくれると本に書いてあったハッシュリファレンスのお出まし。
# !/usr/bin/perl
#
# ハッシュのリファレンスが思ったとおりに制御できるか実験use strict;
use warnings;# 入力リストを開く
open my $input,"< ./input2.txt";# 入力データを格納する配列
my @input_datas;# ハッシュ%inputsのキーに入れるやつらを格納した配列
my @attrs = qw(
site_assortment
site_category
site_name
site_url
site_description
site_keywords
site_admin
site_admin_mail
site_admin_account
site_admin_pass );while(<$input>){
chomp;
my %inputs;# input2.txtのデータをカンマで区切って、ハッシュ%inputsのバリューとして格納
@inputs{@attrs} = split/,/;# ハッシュ%inputsのリファレンスを配列@input_datasに格納
push @input_datas, \%inputs;
}# 狙ったとおりに格納されているかハッシュリファレンスをデリファレンス・出力して確認
print $input_datas[0] -> {site_assortment} ;
print $input_datas[1] -> {site_assortment} ;
print $input_datas[2] -> {site_assortment} ;
はい、いい感じ〜。
MovableTypeの役に立たないプラグインを作ってみた
Perlの学習にもってこいだし、仕事に使わなくもないのでMTのプラグイン開発の真似事を少し始めてみた。
プログラミング入門にお決まりの「Hello World!」表示がお題になっていたが、面白くないのでオリジナルメッセージに変更。
プラグイン名も無駄にオリジナルに。
↑自分が作ったプラグインが表示されるとテンション上がる
プラグインのソースは下記の通り。
pluginフォルダにILoveAKB48フォルダを作り、i_love_akb48.plとして保存。
package MT::Plugin::ILoveAKB48;use strict;
use warnings;use base qw( MT::Plugin );
my $plugin = MT::Plugin::ILoveAKB48->new({
id => 'iloveakb48',
key => __PACKAGE__,
name => 'ILoveAKB48',
registry => {
tags => {
function => {
'ILoveAKB48' => \&hdlr_iloveakb48,
},
},
}
});
MT->add_plugin($plugin);sub hdlr_iloveakb48 {
return 'I Love AKB48!!';
}1;
もちっと役に立つプラグインを作れるようにならなくっちゃ。
Perl48 meets eval function
自分の仕事用に作ったPerl"ガラクタ"スクリプトをブラッシュアップしていくのが、ささやかな趣味の一つになってたりします。
『初めてのPerl 第3版(古っ!)』がバックボーンだったりする私ですが、いまだにこの本から新しい発見があります。
ほんっと読みたい所しか目に入ってないんだなぁと痛感。
今日見つけたのは eval関数。
複数URLのフォームに必要事項を入力しサブミットしていくという、自分用Perlスクリプトを同僚に公開したところ、
「エラーになったときに止まるのがイヤ。エラーを後でわかるようにチェックして、処理は次に進む感じがいい。」
という要望をいただいた。
論理的にできるだろうと漠然と思っていたものの、作成段階からトライ&エラーを何十回と繰り返してきた自分にとっては、使い勝手に不満が無かったりする。(どういう風に動いてるか熟知してるし、エラーの対処も慣れてるから)
という怠惰な感じでズルズルと来てたんだけど、なんとなく久しぶりに開いた『初めてのPerl』で出会ってしまいました。
evalちゃんに。
奇しくも、同僚の要望をそのまま実現する関数でした。
というわけで、
eval{
(〜登録処理〜)
};
# eval関数でキャッチしたエラーが存在する場合にエラー内容を表示する
if ($@){
print "On URL:$_ ,An error occurred ($@), continuing...\n";
}
というのを追記して、