ドコモのCSSをインラインに埋め込んでくれるPHPライブラリ「toInlineCSSDoCoMo」(続き)
    このエントリをはてなブックマークに登録

昨日から、ドコモで外部CSSやスタイルタグが利用できるようになるPHPライブラリ、「toInlineCSSDoCoMo」に夢中です。

読み手がかたよってしまうことを承知の上で、続編の記事を書かせていただきます。

私の作成したサイトはSmartyを使ったものが多いため、フィルタを作成しようかなと考えていたら、既に同じようなコードを書いていた方がいました。
当ブログにいつもコメントを戴いているmaru_ccさんのブログです。

→ PHPライブラリ「toInlineCSSDoCoMo」をEthnaに組み込んでみた [hatena.ne.jp]

 

ここでは、Ethnaに「toInlineCSSDoCoMo」を組み込む方法が紹介されています。
Ethna使いの方は要チェックですね。

ひとまず私はSmartyフィルタだけ拝借し、一部を修正して利用させていただくことにしました。

 

しかし実際に動かしてみたところ、幾つか問題が出てきました。
どれも「toInlineCSSDoCoMo」の問題というよりは、PEARの「HTML_CSS」の問題のようです。

 

1. Warningエラーが出る

サイト内のHTMLの書き方が汚く、HTMLをパースする際にエラーになってしまうようです。
こちらは少しずつ書き直していくしかないですね。

ただ、「<a id=”anchor” name=”anchor”></a>」のような書き方でも何故かエラーになってしまうため、困っていたりします。

通常のCSSと同じようにエラーを出したくない方は、「@」でエラー抑止をすると良いと思います。
またCSSファイルが読み取れなかった場合でも、Exceptionに飛んでいってしまうため、注意が必要です。

 

2. 文字化けしてしまう

HTMLヘッダ内の文字コード指定のmetaタグより前にtitleタグがあった場合には、文字化けしてしまうようです。
調べてみると、metaタグを先に書くのが正しいようですね。
今まで特に問題がなかったので気づきませんでした。

 

3. non-objectエラーで止まってしまうことがある

styleタグで内部CSSを指定した場合に、152行目の「$parent->removeChild($node);」でエラーとなってしまうことがあります。
同じstyleタグの書き方でもエラーが出る場合と、出ない場合があるので詳細は調査中です。(styleタグ自体を削除すると直ります)
ひとまず152行目に、「if ($parent) {」を追加し回避しています。

 

4. Smarty->fetchでコンテンツを取得してる場合、outputfilterでは対応できないかも

私のサイトでは、よく使う表示ブロックは、Smartyのテンプレート関数を作成し、独自タグを設定しています。

例えば、最新ニュースを表示したいときには、タグ「{displayNews num=”5″}」で表示するようにしています。
(こうすると、あちこちでニュースを表示できて便利なためです)

内部ではsmarty->fetchメソッドでニュースを取得しているのですが、fetchに対してもoutpufilterが効いてしまいます。
fetchされるテンプレートは当然ヘッダ情報などを持っていませんので、outputfilterとtoInlineCSSDoCoMoとの相性は、あまり良くありません。

ということで、「ob_start([コールバック関数])」を利用し、出力直前の情報に対して、処理を行うことにしました。

コールバック関数のサンプルは次の通りです。

<?php
// obフィルタの設定
ob_start('ob_filter_cssdocomo');

function ob_filter_cssdocomo($out)
{
  require_once 'toInlineCSSDoCoMo.php';
  $basedir = dirname($_SERVER['SCRIPT_FILENAME']) . '/';
  try {
    $buf = toInlineCSSDoCoMo::getInstance()->setBaseDir($basedir)->apply($out);
  } catch (Exception $e) {
    // エラー処理へ
  }
  return $buf;
}
?>

今のところ、これで一通りうまくいっています。
もう少し試行錯誤が必要ですが、快適なHTML製作に向けて、1歩前進です。

 

関連:


 

最近の記事







4 Responses to “ドコモのCSSをインラインに埋め込んでくれるPHPライブラリ「toInlineCSSDoCoMo」(続き)”

  1. ゆどうふ Says:

    いきなりハードに使っていただいてありがとうございますw
    きちんと書いたHTMLを想定してるので、エラー処理が荒っぽいのがばればれですねw
    できればサイトサンプルを見ながらデバッグしたい気持ちでいっぱいですwww

    2.の文字化けは、たぶんDOMDocumentが化かしてる気がします。
    XHTMLがそこそこ正しいとよしなにやってくれるのですが。。。

    encoding指定は、デフォルトを決めるのが悩ましかったので実装しませんでしたが、
    new DOMDocument() → new DOMDocument(‘1.0’, $encoding);
    みたいにすると化けなくなると思います。

    が。。。この辺はXHTMLを正しく直してもらう方がいいと思ってる僕がいます(^^;

    3.のnon-objectエラーは、HTMLが荒れていてちゃんとノードがパースできていない可能性があるので、
    $dom new DOMDocument();
    の次の行に
    $dom->recover = true;
    をつけてみてください。
    直るかはわかりませんが。。。可能性的にはありかも。

    idとnameがかぶるとwarningになる件は、結構困りものです。
    たぶんXMLの定義に違反してるのかな。。。という気もするのですが、自分も悩みの種で、今は回避策を模索中。。。という感じです。

  2. >ゆどうふさん

    この度は素晴らしいものをありがとうございますw
    また色々と回答ありがとうございます。試してみますね。

    ただ基本的にはHTML側を修正していく方向で対応しようと思っています。
    サイトを運用していくと、どうしても様々な人が触ることになり、どんどんHTMLがおかしくなっていきます。
    なのでむしろWarningが出るのは便利かもしれませんw

    追加でもう一点(バグ?|仕様?)報告を
    toInlineCSSDoCoMoを通すと、xml宣言とDOCTYPE宣言の位置が入れ替わってしまいます。
    (なのでブラウザによってはXMLパースエラーとなってしまいます)
    こちらもHTML_CSSの問題なのかなと思っていますがどうでしょう。

    引き続き色々といじってみますね。
    私の方でも解決策の一つでも見つけられるようがんばります。

  3. ゆどうふ Says:

    ゆどうふです。

    > toInlineCSSDoCoMoを通すと、xml宣言とDOCTYPE宣言の位置が入れ替わってしまいます。

    `;:゙;`;・(゚ε゚ )ブッ!!
    このあたりは、ほとんどがDOM関数が悪さをしてるのですが。。。これは予想外ですねw
    単に
    loadHTML($document);

    としただけでひっくり返りました。。。orz
    うーん、何とか考えてみますw

  4. ゆどうふさん

    レスありがとうございます。
    DOM関数に通しただけでアウトですか。
    いよいよ手が出しづらいところですねー(^^;

    最悪ひっくり返したものを再度ひっくり返すくらいしか手がないかもしれませんね。

コメントを書く