[concrete5.6] ローカルで作成したDesigner Content Proのブロックを本番へ移行する
2016.03 24

cocrete5の強力なプラグイン、Designer Content Proで作成したブロックをローカルから本番環境へ移行するためのポイントを備忘録としてまとめました。

とても便利なDesigner Content Pro

Designer Content Pro(以下、DCP)は、concrete5でコンテンツを編集・レイアウトするための機能であるブロックを自分で拡張できるプラグインです。

これを利用することで、独自の入力フォームを持ったブロック(カスタムブロック)を作成することができます。

さらにカスタムブロックを作るために必要なプログラミングの量をほぼ無くしてくれるので、HTMLによる表現部分だけに集中することができ、デザイナーの画面作成やなクライアントの運用をサポートすることができます。

使い方・カスタマイズの参考

本番稼動しながらDCPブロックへ入れ替えたい

テスト環境でブロックを作って入れ込んでしまうと、本番環境でまた作成しなおさなくてはなりません。データベースのダンプで入れ替えても良いのですが、並行して稼働したい場合だと難航します。

メンテナンス時間を長くとっての移行はなるべく避けたいところです。

concrete5は下書き保存で変更後のプレビューができるので、本番サーバーは現状を維持しながら編集を進められます。

ローカルではブロックの動作のみ確認し、中身は本番サーバー上で入力して公開すれば、メンテナンス時間をかなり短縮できます。

テーマファイルには、ブロック化する前の内容を静的に埋め込んでおいて、そこに編集エリアを併記します。ブロックの追加と中身の入れ込みも、下書き状態であればログインユーザー以外には見えません。

内容がOKとなった段階で、静的に埋め込んだ部分を削除したテーマファイルを反映し、下書きを公開すれば入れ替えがスムーズです。

ブロックタイプを追加すると自動生成されるファイル群

  • /blocks/[block_hanle]/view.php
  • /packages/designer_content_pro_blocks/blocks/[block_handle]/
    • tools/edit_repeating_item.php
    • add.php
    • controller.php
    • db.xml
    • edit.php
    • view.php

ブロックタイプを追加した時点で、後述のインストールが自動で行われます。その際、データベース上のBlockTypesテーブルにブロックタイプについてのレコードが追加されます。

ブロックのインストール、アンインストール、削除

DCPで作成したブロックは、いつでもインストールとアンインストールができます。

インストール

自動生成されたファイルのうち、重要なのはdb.xmlです。インストール時にブロックハンドルのアンダースコアをキャメルケースにした名前で、ブロック用のテーブルをデータベース上に作成します。

テーブルの名前はブロックハンドルがtest_blockだとすると、btTestBlockとなります。

テーブル定義がdb.xmlで管理されることで、データベース上でテーブル編集など直接操作を行う必要がありません。

アンインストール

ページ内で作成したブロックを使用している場合はそれらも削除されてしまうので注意が必要です。

作成したブロックをアンインストールしても、テーブルや自動生成されたファイルは消えません。

削除

削除すると以下の内容が削除されます。
1. /blocks/[block_hanle]/view.php
2. /packages/designer_content_pro_blocks/blocks/[block_handle]
3. BlockTypesテーブルからブロックタイプのレコード

移行の手順

  1. DCPをインストール済みとして、自動生成されたファイルを本番サーバーへ同じディレクトリ構成でアップロードします。
  2. 管理画面からDCPのページへ移動すると、アップロードしたブロックがインストール待ちの状態で表示されます
  3. インストールをクリックします
  4. ページの編集エリアにブロックを追加しようとすると、DCPで作成したブロックが一覧に表示されています

この記事へのコメント

[5.6]concrete5のパッケージにLaravel5を組み込む
2015.04 20

[5.6]concrete5のパッケージにLaravel5を組み込む 環境 ディレクトリ構成は、CPI ACE01 SSHではphpコマンドを打てないので、ローカルで諸々の環境を作ってからサーバー上で展開 ローカルのPH […]

[5.6]concrete5のパッケージにLaravel5を組み込む

環境

  • ディレクトリ構成は、CPI ACE01
  • SSHではphpコマンドを打てないので、ローカルで諸々の環境を作ってからサーバー上で展開
  • ローカルのPHPはphpenvで環境にあわせてバージョンを指定
└── html
    ├── blocks
    ├── concrete
    ├── config
    ├── controllers
    ├── css
    ├── elements
    ├── files
    ├── helpers
    ├── jobs
    ├── js
    ├── languages
    ├── libraries
    ├── mail
    ├── models
    ├── packages
    ├── packages
    │   └── example
    │       ├── controllers
    │       │   └── dashboard
    │       │       └── example
    │       │           └── sandbox
    │       ├── laravel
    │       └── single_pages
    │           └── dashboard
    │               └── example
    │                   └── sandbox
    ├── page_types
    ├── single_pages
    ├── themes
    ├── tools
    └── updates

Laravel5の導入

composerインストール

  • プロジェクトのルートディレクトリにcomposerをインストール
  • ローカルで運用
> curl -sS https://getcomposer.org/installer | php

Laravel5のインストール

> php composer.phar create-project laravel/laravel html/packages/example/laravel --prefer-dist

composer.jsonにForm・HTMLヘルパーを追加

Upgrade Guide – Laravel – The PHP Framework For Web Artisans

    "require": {
        "laravel/framework": "5.0.*",
        "laravelcollective/html": "~5.0" // 追加
    },

Call to undefined method Illuminate\Foundation\Application::getCachedCompilePath()

先ほど追加したForm・HTMLヘルパーを入れるためにupdateを実行して上記エラーが出た場合の対処

Call to undefined method Illuminate\Foundation\Application::getCachedCompilePath() · Issue #8127 · laravel/framework

> rm vendor/compiled.php
> php composer.phar update

パッケージ内のコントローラーからLaravel5を読み込む

パッケージのパスを取得して、autoload.phpなどをrequireしていく
concrete5 :: Get the Package Path in a Dashboard Single Page Controller

<?php
defined('C5_EXECUTE') or die("Access Denied.");

use \App\User;

class DashboardExampleSandboxController extends DashboardBaseController {

    public $helpers = array('html', 'form');

    public $laravel;

    public function on_start() {
        parent::on_start();
        $packagePath = Package::getByID($this->c->pkgID)->getPackagePath();
        require $packagePath . '/laravel/bootstrap/autoload.php';
        $this->laravel = require_once $packagePath . '/laravel/bootstrap/app.php';
    }

    public function view() {
        // Laravel5標準の認証用ユーザーモデル
        $user = new User();
    }

まとめ

強引な方法だけれども、Laravel5内のリソースにアクセスできた。Eloquentも普通に使えるはずなので検証を継続。

もっとスマートな方法があれば情報求む。

情報提供

パッケージコントローラーのon_start()で読み込むとスッキリだった。あとはPSR-0準拠として、Laravel側のnamespaceを置き換えれば良さそう

この記事へのコメント

[WordPress]寄稿者ユーザーに他者の投稿を表示させない方法
2015.04 09

寄稿者ユーザーに他者の投稿を表示させない方法について備忘録としてまとめました。フィルターフックとアクションフックを併用して、管理画面の投稿一覧に関する表示制御を行っています。

寄稿者の権限で投稿を受け付ける場合、その人以外の投稿を見せないようにするためには、フィルターフックとアクションフックの両方を利用する必要があります。

フィルターフック

プラグイン API/フィルターフック一覧 – WordPress Codex 日本語版

WordPress上で投稿データを表示するときなど、何か表示するタイミングで独自のプログラムを実行させることができます。

アクションフック

プラグイン API/アクションフック一覧 – WordPress Codex 日本語版

WordPress上で投稿ボタンを押したときなど、何か動作が発生したタイミングで独自のプログラムを実行させることができます。

要件

  1. 投稿一覧で「すべて」「公開済み」などの投稿状態フィルタを非表示にする
  2. 寄稿者が自分の投稿数0件の状態でも、投稿一覧で他者の投稿が見えないようにする

上記を満たすために、フィルターフックとアクションフックをテーマ内のfunctions.phpに記述していきます。

実装

投稿一覧で「すべて」「公開済み」などの投稿状態フィルタを非表示にする

投稿状態フィルタ

投稿状態フィルタの変更後

function show_owned_posts_only( $views ) {
    unset($views['all']); // すべて
    unset($views['draft']); // 下書き
    unset($views['publish']); // 公開済み
    unset($views['pending']); // 保留中
    unset($views['trash']); // ゴミ箱

    return $views;
}
// views_edit-[post_type] カスタム投稿タイプの場合は、投稿タイプを指定する
add_filter('views_edit-xxxxx', 'show_owned_posts_only');

投稿状態フィルタそれぞれの内容はコールバック引数で受け取る、$viewsに入っています。unset()で要素を削除することで制御できます。

今回はすべての要素を非表示にすることで、「所有」という自分の投稿数のみ表示されるようになります。

注意点としては、CODEXにある「views_edit-post」は「投稿(投稿タイプ=post)一覧」のフィルターフックだという点です。カスタム投稿タイプを利用する場合は、「views_edit-hoge」のように投稿タイプ名に置き換える必要があります。

寄稿者が自分の投稿数0件の状態でも、投稿一覧で他者の投稿が見えないようにする

function hide_other_posts($wp_query) {
    global $current_screen, $current_user;

    if($current_screen->id != "edit-xxxxx") {
        return;
    }

    if(!$current_user->roles[0] == "contributor") {
        return false;
    }

    $wp_query->query_vars['author'] = $current_user->ID;
}
add_action('pre_get_posts', 'hide_other_posts');

フィルターフックで投稿状態フィルタを非表示したとしても、寄稿者の投稿数が0件の状態で投稿一覧にアクセスすると、他者の投稿が見えてしまいます。

pre_get_postsアクションフックを使い、ある特定の画面(この場合はカスタム投稿タイプの投稿一覧)で、ログインしているユーザー(この場合は寄稿者)の投稿のみ取得しています。

$current_screenと$current_userで現在表示している画面とログインしているユーザーを特定しています。

ユーザーを特定できれば、$wp_queryからauthorパラメータで投稿を絞り込むことができます。

参考

この記事へのコメント

OSX Marvericks にアップデートしたら MAMP PRO が動かなくなった
2013.11 02

OSX Marverics(以下、Marvericks)になって、便利な機能も増えましたが恒例のごとく「今まで動いていたものが動かない!」というケースも発生したりします。今回は、MAMP PROがそれになったので対処法をメモとして残しておきます。

現象

  • MAMP PRO 起動後に MySQL を起動できずハングアップする
  • 上記の状態だと、アプリケーション側からはログを見ることしかできない

原因

Marverics でのセキュリティ強化により、権限の問題で /etc/hosts をサードパーティーアプリケーションが書き換えられなくなっているためのようです。

やるべきこと

  • MAMP PRO を最新(2.2)にアップデート
  • Keychain Access で署名を発行する
  • codesign コマンドで MAMP PRO に署名し、編集許可を与える

電子署名を作成する

  • Keychain Access を起動する
  • Menu(Keychain Access) > Certificate Assistant > Create a Certificate…
  • 必要情報を入力して、署名を作成
  • Name => CalmTech(ここは任意)
  • Identity Type => Self Signed Root
  • Certificate Type => Code Signing

Keychain Access で電子署名を作成後

MAMP PRO に適用する

上記で発行した電子署名を MAMP PRO に適用します。ターミナルを起動して、以下のコマンドを実行します。
codesign -s “Your Name(今回の場合は、CalmTech)” /Applications/MAMP\ Pro/MAMP\ Pro.app

適用されたかどかは、以下のコマンドで確認できます。

codesign -v /Applications/MAMP\ PRO/MAMP\ PRO.app -v

MAMP PRO を再起動します。私の場合は、マシンも再起動してみました。

調査の過程で試したこと

デフォルトでインストールされる Apache を停止

Marvericks にアップグレードすると、Apache がインストールされるため MAMP Pro の Apace を起動できないというケースも散見されています。この場合は、以下のコマンドで Apache を停止することで解決。今後も使わないのであれば、自動起動からも削除してしまうと良いと思います。

sudo apachectl stop
sudo launchctl unload -w /System/Library/LaunchDaemons/org.apache.httpd.plist

参考

この記事へのコメント

Guard + Compass + Foundation で環境構築メモ
2013.07 05

フロントエンド開発でもCUIベースでのビルドツールが充実してきています。RubyベースのGuardで複数のリソースを扱う方法についてメモをまとめました。

    Guardはコマンドラインツールで、ファイル変更を監視してコンパイルや結合などのタスクを実行できます。Middlemanでプロトタイプを構築して、既存システム(PHPベース)に移植という段取りだったのですが、Middlemanのディレクトリ構成をそのまま持ち込むことはできません。

    Guardを採用した理由としては以下があります。CoffeeScript、concat、uglifyはまた今度に。

    • Compass、CoffeeScript、Slimといった様々なライブラリを複合で扱える
    • BundlerでGem管理ができる
    • Rubyベースなので資産を再利用しやすかった

    まず、CompassとFoundationを導入する段取りについて。

    Gemfile

    Guardプラグイン各種を入れておきます。

    # SASS & Compass
    source ‘http://rubygems.org’
    
    # V8 JavaScript Engine (for Uglifier)
    gem “therubyracer”
    gem "sass"
    gem "compass"
    gem "zurb-foundation"
    gem "susy"
    gem "compass-normalize"
    
    # For concatenation/compression
    gem "uglifier"
    
    # Guard and plugins
    gem "guard"
    gem "guard-sass"
    gem "guard-compass"
    gem "guard-coffeescript"
    gem "guard-livereload"
    gem "guard-concat"
    gem "guard-uglify"
    gem "rb-fsevent"
    

    Bundlerでインストールします。

    bundle install --path vendor/bundler

    config.rb

    各種Gemをrequireしておきます。

    require 'zurb-foundation'
    require 'susy'
    require 'compass-normalize'
    

    Sassファイルでは以下のようにインポートしておきます。

    @import "normalize";
    @import "foundation";
    

    Foundationについては、これですべてのスタイルが読み込まれます。

    Guardfile

    CompassでSassファイルをコンパイルするタスクを用意します。
    正規表現で .scss と .sass 両方をコンパイル対象にしています。

    guard :compass do
        watch(%r{sass/(.+\.s[ac]ss)})
    end
    

    Guard実行

    bundle exec guard init
    bundle exec guard
    

    コマンドを実行するとタスクが実行され、さらにファイル変更の監視を始めます。

    [1] guard(main)>

    この記事へのコメント

    RubyでYoutube Data APIの認証、動画検索、取得、更新
    2013.02 28

    RubyからGoogle Data APIを操作するバッチを書いていたので、おさらいです。APIとのやりとりを直接書いてみると、マッシュアップ系のWebサービスを作るときの基礎練習として良いですね。

    APIを使う準備

    まずはデベロッパーキーを取得しておきます。名前と使用するサイトのアドレスを指定すると、キーが発行されます。

    認証

    Youtube Data APIでの認証は主に3種類あります。

    1. AuthSub
    2. OAuth
    3. ClientLogin

    今回は3.のClientLoginを使います。クライアントマシンから実行するバッチスクリプトとしてコードを書いていたので、Youtubeコンテンツの所有アカウントに紐付けるClientLoginが最適です。

    APIにPOSTを送信して、認証トークンを取得します。

    require 'net/http'
    require 'uri'
    uri = URI.parse('https://www.google.com/youtube/accounts/ClientLogin')
    https = Net::HTTP.new(uri.host, uri.port)
    https.use_ssl = true
    header = {'Content-Type'=>'application/x-www-form-urlencoded'}
    body = "Email=#{email}&Passwd=#{password}&service=youtube&source=#{client_name}"
    res = https.post(uri.path, body, header)
    token = res.body.split('YouTubeUser=').first.gsub(/^Auth=/, '')
    

    ClientLoginの場合、レスポンスのボディにAuth=xxxYouTubeUser=user_nameというフォーマットでトークンとユーザ名が入ってきます。上記のコードはuglyですがトークンを最後の所で抽出しています。putsで表示した内容をコピーして使用しても良いですが、認証トークンには期限があるので、最新のトークンを取得して以降に使用する方が良いと思います。

    sourceの所はアクセス元の名前なので、適当で大丈夫なようです。

    動画検索

    APIにGETを送信し、特定のユーザがアップロードした動画から、検索キーワードを指定して検索します。

    require 'net/http'
    require 'uri'
    require 'rss'
    
    search_uri = URI.parse('http://gdata.youtube.com/feeds/api/videos')
    header = {
        'Authorization'=>"GoogleLogin auth=#{token}", 
        'X-GData-Key'=>"key=#{developer_key}"
    }
    search_http = Net::HTTP.new(search_uri.host, search_uri.port)
    res = search_http.get(search_uri.path + "?v=2&author=#{user_name}&start-index=1&max-results=20&lr=ja&q=#{query}")
    rss = RSS::Parser.parse(res.body)
    
    rss.entries.each do |entry|
        puts entry.title.content
    end
    

    まずリクエストのヘッダに認証キーとデベロッパーキーを指定します。スペースなどが入る点に注意が必要です。次にリクエストのボディにパラメータを指定します。

    • author => 動画の投稿ユーザを指定できます
    • start-index => 検索結果の開始位置
    • max-result => 検索結果1ページあたりの件数
    • lr => 言語
    • q => 検索キーワード

    検索が正常に実行されると、レスポンスのボディにAtom形式でXMLが入ってきます。今回は、これをパースして使うようにしています。XMLの内容については、こちらを参考に。

    動画単体の取得

    APIにGETを送信し、動画IDを指定して取得します。

    require 'net/http'
    require 'uri'
    require 'rss'
    
    single_uri = URI.parse("http://gdata.youtube.com/feeds/api/users/#{user_name}/uploads/#{movie_id}")
    header = {
        'Authorization'=>"GoogleLogin auth=#{token}", 
        'X-GData-Key'=>"key=#{developer_key}"
    }
    single_http = Net::HTTP.new(single_uri.host, single_uri.port)
    res = single_http.get(single_uri.path + "?v=2&author=#{user_name}&start-index=1&max-results=1&lr=ja&q=#{query}")
    single = RSS::Parser.parse(res.body)
    
    puts single.title.content
    
    

    URIにユーザ名と動画IDを指定します。注意はXMLをパースしたときに、ルートノードがentryになる点です。

    エントリーの更新

    APIにPUTを送信し、動画に関する説明やカテゴリ、タグなどを更新します。

    require 'net/http'
    require 'uri'
    
    upload_uri = URI.parse("http://gdata.youtube.com/feeds/api/users/#{user_name}/uploads/#{movie_id}")
    upload_http = Net::HTTP.new(upload_uri.host, upload_uri.port)
    upload_header = {
        'Authorization'=>"GoogleLogin auth=#{token}", 
        'X-GData-Key'=>"key=#{developer_key}",
        'Content-Type'=>'application/atom+xml; charset=UTF-8'
    }
    
    xml <<-EOS
    
    
      
        #{title}
        #{description}
        #{category}
        #{keywords}
      
    
    EOS
    
    res = upload_http.put(upload_uri.path, xml, upload_header)
    

    XML内で値を指定する場合に注意することがあります。

    GithubでもRubyベースのGoogle Data API向けのモジュールは多数あるので、そちらを利用しても手軽に利用できると思います。

    この記事へのコメント

    HTTPでXMLを送信したら、The Processing Instruction Target Matching “[xX][mM][lL]” is Not Allowed
    2013.02 27

    Rubyで次々とXML送信するバッチスクリプトを書いていたところ、Net::HTTP#putの利用時にステータス400。ふたを開けてみると、なんということはない内容でした。

    The Processing Instruction Target Matching “[xX][mM][lL]” is Not Allowed

    Youtube Data APIで動画の更新をしようとXMLをPUTで送信しようとしたら上記のエラー。ステータスは400でBad request扱い。色々探したら、原因が分かりました。
    どうやら、XMLの前に余計な文字列が送信されているためのエラーらしい。

    Rubyの便利ヒアドキュメントが裏目に

    Rubyでのヒアドキュメントで便利なのは、以下のようにインデントできるタイプ。

    def xxx
      s = <<-EOS
        
        ...
      EOS
    end
    

    ただ、ここでヒアドキュメントで生成した文字列を確認してみると、XMLの前にきっちりインデント文字が生成されてました。

    \t\t
    

    これのせいですね。というわけで以下のように変更して事なきを得ました。イージーなミスを・・・

    def xxx
      s = <<-EOS
    
    ...
      EOS
    end
    

    コードが「うーん」という状態になりますが、いたしかたありません。

    この記事へのコメント

    Sublime Text 2 + MAMP + Xdebug でPHPデバッグをする方法
    2012.12 18

    Sublime Text 2(以下、ST2)がすっかりメインエディタに定着したのですが、デバッグ環境が未整理でした。そういえば・・・と思って探してみると、やはりプラグインがありました。ST2とMAMPによるPHPデバッグ環境の導入方法を解説します。

    MAMPのphp.iniに設定を追加する

    MAMPを使用している場合、私はPROなのでファイルメニュー -> テンプレートを編集 から編集できますが、PROでない場合はphp.iniを直接開いての編集となります。各phpバージョンごとに設定が必要なので、利用環境に合わせて設定を追加していきます。例えば以下。zend_extensionの部分はコメントアウトされているだけなので、行頭のセミコロンを削除でOKです。

    [xdebug]
    zend_extension=“/Applications/MAMP/bin/php/php5.3.14/lib/php/extensions/no-debug-non-zts–20090626/xdebug.so”
    xdebug.remote_enable=On
    xdebug.remote_host=“localhost”
    xdebug.remote_port=9000
    xdebug.remote_handler=“dbgp”
    xdebug.remote_autostart=Off
    xdebug.profiler_enable = On
    xdebug.profiler_dir = “/Applications/MAMP/tmp/php5.3.14/xdebug/”
    xdebug.collect_vars=on
    xdebug.collect_params=4
    xdebug.dump_globals=on
    xdebug.dump.GET=*
    xdebug.dump.POST=*
    xdebug.show_local_vars=on

    SublimeXdebugを追加する

    SublimeXdebugというXdebugクライアントのプラグインがあります。実行すると、ST2上にXdebugによるPHPデバッグメニューとデバッグ状況を表示する分割ウィンドウを表示します。

    .sublime-projectファイルに設定を追加する

    ST2のプロジェクトとして保存している場合は、以下の様な設定を追加します。例えばWordPressを利用時にwpフォルダを作っている場合は、http://your.web.server/wpと記述します。

    
    {
        "folders":
        [
            {
                "path": "..."
            },
        ],
    
        "settings": {
            "xdebug": { "url": "http://your.web.server" }
        }
    }
    

    ブレークポイントを指定する

    ST2上で止めたい処理の行で Shift + F8 を押し、Add/Remove Breakpoint を実行します。すると行番号の左に●が表示されます。デバッグ実行時に該当する行まで処理がくるとストップして、そこの部分で現在の変数はどうなっているか?といった情報を確認できます。

    デバッグを開始する

    Shift + F8 でクイックメニューが表示されます。Run Debugging
    選択するとデバッグを開始できます。
    メニューからデバッグを開始すると、http://your.web.server?XDEBUG_SESSION_START=sublime.xdebugというURLで規定ブラウザ上にページが表示されます。URLは先ほどの.sublime-projectで指定した値です。

    注意しなければいけないのは、セッションキーとしてURLに XDEBUG_SESSION_START=sublime.xdebug という値が追加されていることです。デバッガにXdebug使ってるよーと通知するための値です。デバッガのメニューから Rub debugging を実行した場合に自動で追加されますが、表示されたページ上でPOSTや別ページへのリンクにジャンプしようとした時は、その値がクリアされるので注意が必要です。
    Chromeエクステンション Xdebug helper の設定でもセッションキーを指定するので、使用する場合には忘れずに。

    ショートカットで効率良くデバッグ

    ごく基本的なステップ実行によるデバッグをショートカットで実行できます。プラグインのページにもありますが、よく使うものとしては以下でしょうか。

    • Ctrl + Shift + F5: 次のブレークポイントまで実行
    • Ctrl + Shift + F6: ステップオーバー(次の行へ)

    Xdebugでリモートデバッグとなると、Eclipse PDTやNetbeansを使っている例が多数ですし、見やすさや使いやすさは一歩譲りますが、軽量なSublime Text 2でもできるようになるのは嬉しいですね。

    この記事へのコメント

    IE9でprototype.js + Shadowbox.jsを使う場合のメモ
    2012.06 05

    IE9なら、モダンブラウザに近づくから面倒なIE対応は減るはず、というのは幻想で余計に手間が増えるケースもあります。今回は限定されたシチュエーションですが、JavaScriptライブラリを使う場合の対応をまとめました。

    事の発端はIE9利用時のフィードバック

    サムネイル表示にShadowbox.jsというライブラリを使用していました。これはいわゆるLightbox系なのですが、導入した当時はjQuery移行が活発で、prototype.jsをベースにしたものがあまり無かった中では貴重な存在でした。

    今回、リリースから4年ほど経過しているシステムの追加機能をリリースしたのですが、IE9の場合にサムネイル表示されない現象が発生しました。再現してみると、クリックすると画像への直リンクとなってしまいます。

    問題はprototype.jsの古さとdoctype

    prototype.jsは1.7 RC3でIE9のフルサポートが完了したようです。また、Shadowbox.jsのフォーラムではdoctypeをhtml5にしたら正常に動いたということで、prototype.js 1.7 stableにアップデートしつつdoctypeをxhtml 1.0からhtml5としたところ、標準モードで問題なく動作するようになりました。IE7とIE8についても問題ありません。(IE6はもういいでしょう・・・)

    イベントモデルの変更が原因?

    IE9ではDOM L3のサポートで独自のattachEvent実装などがなくなっているようです。prototype.jsのソースを少し読んでみると、新しいものではブラウザ判定の処理が異なっており、イベントハンドラにまつわる記述に変更があります。この辺が影響しているようです。

    ブラウザサポートはライブラリやソースのメンテナンス、リファクタリングを伴う契約に

    問題は、こういった検証や修正は請求対象となるか否かでしょう。今回は無償対応としたのですが、こういったケースを想定した保守費用や継続的製作費を説明もしくは計上しておくのも、製作者サイドには大事かと思います。Androidの世界はもっと大変かもしれません。

    ソフトウェアの最大のメリットは、「後から直せる」ことです。しかし、こういった特定のベンダに依存した環境で製作を行なっていくことは、「後出しジャンケンされる」ということでもあります。

    SIerの世界では、そういったケースにそなえた予算取りなどが確立している所も多いですが、正直、がんじがらめにされたユーザが訳もわからず搾取されているケースもあります。AppleがFlashを全面廃止した時と同じように一寸先は闇ですが、3年以上の稼働を想定したシステムなどは、こういったケースでクライアントに理解を得られるよう平時からの情報共有が大事だと改めて思いました。

    この記事へのコメント

    [FuelPHP] taskでRailsライクなseedを作る
    2012.02 22

    FuelPHPを使い始めているのですが、良いと評価できる点にコマンドラインから実行できる便利なタスクがあります。Railsではrake, railsというコマンドで各種タスクを実行でき、それを踏襲しています。今回はその中でも初期データ作成に便利なseedという機能をFuelPHP上に作ってみました。

    FuelPHPを使い始めているのですが、良いと評価できる点にコマンドラインから実行できる便利なタスクがあります。Railsではrake, railsというコマンドで各種タスクを実行でき、それを踏襲しています。今回はその中でも初期データ作成に便利なseedという機能をFuelPHP上に作ってみました。

    taskを拡張するクラスを配置する

    置き場所は fuel/app/tasks/*.php です。そして、seedファイルの置き場所は fuel/app/seeds/*.php としました。今回、実行できるタスクとしては以下の3つという設計にしました。

    • モデル名を指定して同名のseedを実行
    • seeds以下をすべて実行
    • モデル名を指定して同名(複数形のはず)テーブルを初期化

    上記の設計を反映したコードが以下のとおり。more better な実装あれば是非ご意見いただきたく。

    このソースを参考に、というか reset はパクr

    
    

    それぞれのタスクを実行する場合のコマンドは以下のようになります。

    • oil r seed model_name
    • oil r seed:all
    • oil r seed:reset model_name

    そして、実行されるseedファイルの中身はこんな感じに。

     'テスト1',
    		'summary' => '1つめのテストデータ'
    	),
    	array(
    		'name' => 'テスト2',
    		'summary' => '2つめのテストデータ'
    	)
    );
    
    foreach ($seeds as $key => $seed) {
    	$model = Model_Test::forge($seed);
    	$model->save();
    }
    ?>	
    

    この記事へのコメント

    Older Posts »

    作者について

    青森県内でソフトウェア・システム開発を行うフリーランスのプログラマー。元々は集中監視システム開発に従事。現在はウェブサイト製作・オンラインシステムの開発案件を中心に、プログラミングのスキルトレーニングや講演も行う。

    TEL 0172-55-7030  FAX 0172-55-7031
    10:00 - 18:00 土日祝休

    恐れ入りますが、お急ぎの場合を除いて、メールにてお問い合わせください。