Home > memo Archive

memo Archive

AMP向け個別記事テンプレートを作ってみる

  • Posted by: maRk
  • memo | tmpl

AMP(Accelerated Mobile Pages) は、モバイル環境で高速表示を実現するプロジェクトです。これに対応する Movable Type用のテンプレートを作ってみることにしました。

AMPに関する詳細は以下にあります。

Movable Type で対応させたといった記事です。

基本としては、個別アーカイブにテンプレート組んで、AMPの決まりごとに沿うように出力の調整をかけるというものです。

その際に、アーカイブマッピングでAMP用のパーマリンク設定となるよう、設定を行い、記事アーカイブのメインと同時にAMP用アーカイブテンプレートが作成されるという形です。

個人的には、出力については、ダイナミックパブリッシングにしておくことで、再構築などに負担がかからないのではないかと思ってます(キャッシュが効いてるという前提ならば)。

以上踏まえて、サンプルというか、実際ブログで使ってるものベースのテンプレートを以下においてあります。

(Google Analytics や アドセンスなど付随するモジュール群は入ってません)

あと、定期的に変更したり元が変更したら反映するようにしますのであくまでもサンプルとしてです。mt:Ignoreのコメントは説明のためのもので、実際のテンプレートには入れていません。

以下、作った時点の方針のようなものです。

  • 編集画面で管理するものとして、なるべく手間のいらないように、include テンプレートしない作りにした
  • 禁止属性等は正規表現にて、置換・削除し、マッチパターン、リプレイスメントは変数代入にした
  • ダイナミック動作想定で極力DBアクセスが少ないよう最低限なテンプレートタグで組んだ
  • CSS や JSON は出力時に、改行・空白を詰めるようにした(編集画面で見やすく、サイズ縮小出力できる、よくある手法です)。

Movable Type カスタムフィールド編集ページの項目と値をリストアップするブックマークレット

  • Posted by: maRk
  • memo

Movable Typeのカスタムフィールド編集の画面上で現在入力されている値をリストアップするブックマークレットです。

カスタムフィールドの現在の内容を管理ページで一覧するようなプラグインは探すとあるようなのですが、リストのメモをとったりり、リストをブログ記事に掲載したりするのに利用できるようなプラグインがみつからなかったので作成してみました。

実行した例です。定義リストとして生成し、画面下部に以下のように表示します。

(現在表示されているフィールドの value を取得するようにしていますので、各フィールドを書き換えた後は、保存されている値ではなく、その値が表示されます)

システムオブジェクト
    記事
名前
    コード埋め込み
説明
    記事内に任意のソースコードを埋め込む
種類
    テキスト(複数行)
オプション
    なし
必須
    必須でない
規定値
    既定値
ベースネーム
    embedcode
テンプレートタグ
    embedcode

コードの中身は以下となります。

document.body に 追加なので、体裁はよくないですが、一応使えるレベルということで。

// for Movable Type 6.x
// Movable Type license as MIT
// Checked ver. 6.0.6
// use /path/to/mt.cgi?__mode=view&_type=field

(function($){
  
// get custom field value
  
  
  $('body#edit_field').each(function () {
    var f_objType = {
      'システムオブジェクト': $('#obj_type').parent('div').text().replace(/[\s\r\n]+/g, '')
    };
    var f_name = {
      '名前': $('#name').val()
    };
    var f_desc = {
      '説明': $('#description').val()
    };
    var f_type = {
      '種類': $('#type-label').parent().next().text().replace(/[\s\r\n]+/g, '')
    };
    var f_option = {
      'オプション': $('#options').val() || 'なし'
    };
    var f_require = {
      '必須': $('#required').attr('checked') === 'checked' ? '必須' : '必須でない'
    };
    var f_default = {
      '規定値': $('#default-field').text().replace(/[\s\r\n]+/g, '')
    };
    var f_basename = {
      'ベースネーム': $('span.basename-text').text()
    };
    var f_tmplTag = {
      'テンプレートタグ': $('#tag').val()
    };
    var result = [];
    result.push(f_objType);
    result.push(f_name);
    result.push(f_desc);
    result.push(f_type);
    result.push(f_option);
    result.push(f_require);
    result.push(f_default);
    result.push(f_basename);
    result.push(f_tmplTag);

// out
    
    $('body').append('<div class="rslt"/>');

    $.each(result, function () {
      for (var key in this) {
        for (var i = 0; i < result.length; i++) {
          var dlist = $('<dl>');
          $(dlist).append('<dt>' + key + '</dt>\n<dd>' + this[key] + '</dd>\n');
        }
      }
      $('div.rslt').append(dlist);
    });
    console.log(result);
  });
})(jQuery);

リポジトリとして、Hatena::let にあります。

メモ:Movable Type:このプラグインは、 Mvable Type 6向けにアップグレードされていません。の直しかた

  • Posted by: maRk
  • memo

Movable Type で古いプラグインを使用していると、表題のような警告がプラグインリストに出ていることがあります

そのままでも動作するのがあったりしますが、今後のことも考えると、似た機能の別のプラグインを探すか、修正するとかいう選択を迫られることとおもいます。

今回は、この警告の対処について、メモとして書いてみますが、あくまでも個人的な使用前提での話ということですので、本番環境で複数ユーザ運営システムの環境は考慮していません。

名指しで申し訳ないのですが、伏せた状態で説明しても分かりにくいので、古めのプラグインの例として TBPingLinkLookup を選ばせてもらいました。

参照:

warnings-mt-plugin-01.jpg

メッセージに書かれているとおりなのですが、変更の実際をやってみます。

このプラグインは、.pl に書かれているタイプのものですので、tb-link-lookup.pl ファイルを編集することにします。(Movable Type の推奨するYAML形のプラグインに直す手もあるのですが雛形とか用意できてないと、手間だったりするので、今回は直接修正する形をとります)

MT->register_junk_filterはコメントにします。

# MT->register_junk_filter({
#    name   => $PluginName,
#    plugin => $plugin,
#    code   => sub { $plugin->handler(.@_) },
#});

my $plugin = という箇所に、registry(junk_filters)になおします。

registry => {
    junk_filters => {
        $PluginName => {
            label => $PluginName,
            code  => \&handler,
        },
    },
},

以上が追加するコードになるかと(インデントは適当なので、元のコードにあわせるほうが視覚的はいいです)。 プラグイン名は元のMT::register_junkfilter のほうが、プラグイン名($PluginNameにて登録ずみ)を使用しているので、そのまま利用します。

label には、このプラグイン名、 code にハンドラを指定。このプラグインだと、 handlerというサブルーチンがそれに該当。

このコードの追加場所ですが、プラグインを登録する、my $plugin の最後(});の前)に追加します。

以上で、ファイルを反映させ、プラグインリストを表示させると、警告が消えて、ジャンクフィルタとしてフィルタ名が表示されるはずです。

warnings-mt-plugin-02.jpg

for MT:AccessRankingGA で生成された json ファイルを php でパースするテンプレート

  • Posted by: maRk
  • memo

以前作成していたものをテンプレート向けに直してメモとして置いておきます。

AccessRankingGAは coolniikou 氏 提供のMovable Type 用プラグインであります。

※ 以下のテンプレートは AccessRankingGA の利用下で使用するものとします。

<?php
  $json = @file_get_contents("PATH/TO/Access_Ranking.json" , true);
  if($json === false){ echo '取得できませんでした orz';
  } else {
  $base = 'http://example.com';
  $obj = json_decode($json,true);
  $data='';
  $data .= '<ol class="access_ranking">';
  foreach($obj[rows] as $val){
  $data .= '<li><a rel="nofollow" href="' . $base. $val[0]. '">' . $val[1] . '</a></li>';
  }
  $data .= '</ol>';
  echo $data;
}
?>

実際には、 Cache_Lite を使用したり、サイト名を除去するなど、もう少し手間のかかることをやってます。

なお、Google Analytics の提供する JSON ファイルの構造に変更があったときなどメンテナンスが必要となります(これはjQueryでパースしてる場合も同じことです)。

カスタムアーカイブマッピングでグローバルモディファイアを用いた場合の動作は

  • Posted by: maRk
  • memo

アーカイブマッピングのところで、MTタグにモディファイアを入れたときの出力を検証した記事です。 実際の運用とかは全く考慮していません。

*将来的に仕様変更というか、制限がかかるようになったら、同じ動作にはならないとおもわれます。

検証をおこなった日

2013 年 5 月 10 日

動作環境

  • MTOS 5.2.2 + MAMP バージョン 2.1.1
  • 今回はウェブページにてマッピングを作成
  • テーマは、Rainier 1.01 を使用

グローバルモディファイアには、MD5 変換するものを自前で用意して使いました。

以下のように、アーカイブマッピングの設定で新規にアーカイブマッピングを追加します。

PageBaseName ファンクションタグに対して、md5 というモディファイアを与えた出力を試みました。

archivemapping-config.jpg

md5/about フォルダ以下に設定したファイルが生成されています。

archivemapping-use-modifier.jpg

はてなブックマークマイページなどでhttp記法を追加表示させるGMスクリプト

  • Posted by: maRk
  • memo

はてなブログでは、ブックマーク連携がありますが、ブックマークしたばかりの記事なら貼付けしやすいけど、過去エントリーについてはやりにくいことが分かったので作ることにしました。

  • add-httpnotation.jpg

http記法は、以下のドキュメントを参考にしました。

ブックマーク数表示をするオプションをつけた形で、title= とあわせる(:title:bookmark とすると、記事タイトルがわかりにくいため)形式で出力するようにしてみました。

// ==UserScript==
// .@name        Add Hatebu HTTP notation
// .@namespace   https://labs.markdiary.com/
// .@description Add to hatena HTTP notation
// .@include     http://b.hatena.ne.jp/*
// .@version     1.0
// ==/UserScript==

window.onload= function(){

function add_notation(){
    var d=document, id=d.getElementById("bookmarked_user")||d.getElementById("page-content"), nd=[],i, el, cl, link;
    if(id){
      el = id.getElementsByTagName("a");
      for(i=0; i<el.length; i++){
         cl = el[i].className;        
          if( cl == "entry-link" ){
             link = el[i].getAttribute("href");
             nd[i] = document.createElement("input");
             nd[i].type = "text";
             nd[i].value = "[" + link + ":title=" + el[i].firstChild.nodeValue +":bookmark]";
             nd[i].setAttribute("readonly", "true");
             nd[i].setAttribute("onclick", "this.select();");
             el[i].parentNode.appendChild(nd[i]);
           }
      }
    }
  }

  setTimeout ( add_notation, 2500 );
};

ブックマークレット 置き場

いちおう、新旧のブックマークページで表示を確認していますが、検索ページでの表示には対応してません(旧ブックマークのhttp://b.hatena.ne.jp/my/search?q= のリクエストのページでは表示できたので、個人的にはこれで目的は達成出来たので)。

mi テキストエディタの config.yaml モードを作りました

  • Posted by: maRk
  • memo

mi で Movable Type などの config.yaml ファイル向けのモードを作成してみました

mi-mode-configyaml.jpg

モードの編集の設定で、インデント時にタブでなく、スペースを使うようになっていればよかったので、ツールとかあまり細かなところまでサポートしてません。

以下にファイルを置きました。

右カラムの(download)のリンクで最新のファイルです。

モード追加のところで、モードファイルからインポートより、Config yaml のモードファイルアイコンを指定します。

追記(2013/05/27)mi テキストエディタ v3 向けのものも用意してみました(注意:現時点で miテキストエディタのv3系はベータ版です)

新規モード追加のところで、"Config yaml"フォルダを指定します。なお、カラースキームファイルを同梱してあります。Color Scheme フォルダのcsvファイルをmi のスキームフォルダ内に移動して適用します。

テーマの再適用とバックアップされたテンプレートの変更履歴について

  • Posted by: maRk
  • memo

Movable Type のテーマの再適用ボタンとバックアップされたテンプレートにおける変更履歴の件です

こんなことをするのは自分だけかと思いますが、あるテーマの config.yaml に手を加えたとき、追加したテンプレートが反映されてないというので、テーマ設定のところの現在のテーマの「再適用」というボタンを押しました。

このときの動作ですが、同じテーマの適用しなおしです。 リセットといったほうがわかりがいいのかもしれません。(とはいっても、Movable Type のテンプレートの初期化動作は種類を選べますから、一概にリセットで括られない部分はあります)

これをわからずにやってしまうと、以前にテンプレートに追加したカスタマイズが初期状態に戻されます。(その原因のひとつに、「再適用」を押したら、「テンプレートの初期化」を押したときと違って、確認画面もでずにすぐに実行されてしまうこともあるとおもいます。ローカル環境用意していながら、確かめずに行なう自分も悪いですが)

こうなってしまった場合に対処としてできることは、バックアップされたテンプレートから直前のバックアップ時刻のものを表示させコピーして持ってくる、ということです。

ちなみに、バックアップされたテンプレート側にテンプレートの変更履歴が保存されています(再適用されたほうは変更履歴はありません)。何度かカスタマイズで変更をやっている場合に前の状態に戻したいとき便利です。但し、これが行なえるのは、設定で変更履歴を保存するようになっている場合です。

以上、MTOS v5.2 におけるテーマ再適用動作に関する内容でした。

mt.Vicuna SimpleにMTOS5.2以降のリッチテキストエディタへのスタイルを適用するテスト

  • Posted by: maRk
  • memo

mt.Vicuna Simple プラグインテーマにMovable Type 5.2 から使うことのできる、エディタへの独自CSSを適用してみるテストをやってみました。

Movable Type 5.2からは、リッチテキストエディタを使った編集画面(ウェブページ、ブログ記事共)に、任意のCSSを指定することができます。CSSの指定を行うと、編集時にCSSによる装飾が有効となります。ウェブサイト、ブログごとに、それぞれ異なるCSSを設定することが可能です。

movabletype.jp (http://www.movabletype.jp/documentation/mt5/design/cssoneditor.html)

Tutorial がないと分かりにくいという人もいるかとおもいまして(自分がそうなだけ)、やってみたことを順にメモしていきます。

確認した mt.Vcuna テーマセットのヴァージョンは、1.03 で最新でなかったですが、手を加える箇所は config.yaml だけなのでそれほどヴァージョンによる違いはないとおもいます。 Movable Type は MTOS 5.2 ja により、同梱のTinyMCEプラグイン以外にエディタに関わるプラグインは使用していません。

まず、整理しておきたいことがあるのでまとめておきます。

  • Movable Type 5.2 から使える機能である
  • テーマの.yamlファイルで編集画面に適用するスタイルシートを指定しておく方法と、投稿設定のフィールドに直接入力する方法とがある (今回は前者の方法)
  • mt.Vicuna は、Movable Type.jp の説明にある、theme.yamlを使わずに config.yaml によるテーマ指定を採用している (今の時点のヴァージョンまで)
  • 適用する CSSファイルまでのパスのほか、 {{theme_static}}変数を使うことが出来る。なお、{{theme_static}} 変数にパスに注意(後述)

作業手順
まず適用するCSSファイルを作成します。 前述の解説ページにある、サンプルファイルを参考に以下のとおりにしました。ファイル名は editor.css

body {
    font-family: serif;
}

body.entry {
    background: pink;
}

body.page {
    background: green;
}

(エディタの背景色が変更されます。ちなみにサンプルCSSファイルのほうは、このほかにある画像がつくようになっていますが、「お楽しみに」とありますのでここでも一往伏せておきます)

作成したCSSファイルは、今回はとりあえず path/to/mt-static/support/theme_static/mtVicunaSimple 直下に置きます。
mt.Vicunaの config.yaml ファイルを任意のエディタで開きます。そして、適用するCSSのパスを追記します。
追記する場所の階層は説明によれば、    elements: >default_prefs: > data: のところですが、ここは mt.VIcuna テーマセットでは既に他の設定がありますから、CSSファイルまでのパスをdate: の階層のところに追記するだけでよいのです。

具体的に示すと以下の場所です

        data:
          file_extension: html
          convert_paras: __default__
          convert_paras_comments: __default__
          archive_type_preferred: Individual
          entries_on_index: 10
# エディタへのスタイルの追記 (この行は書かなくてもよい)
          content_css: '{{theme_static}}editor.css'
#  追記ここまで (この行は書かなくてもよい)

以上で上書き保存します(ローカルとかターミナルからでない場合上書アップロードするなど)。

パスについてですが、 {{theme_static}} のとる値が support/theme_static/止まりでなくテーマセットまで含まれるようなので注意します(これで結構嵌りました)。

{{theme_static}} = (path to)/mt/mt-static/support/theme_static/mtVicunaSimple/  = {{support}}theme_static/mtVicunaSimple/

ブログのデザイン > テーマ を開き、 mt.Vicuna Simple テーマを適用するか、あるいは適用済の場合は [再適用] をクリックします(テーマセットで指定しないというときはこの行程はパスして次の手順のところで手動入力します)。

次に、設定 > 投稿 をみてみましょう(設定できていればすぐに記事編集にいっても問題ないのですが)。

WYSIWYGエディタの設定のフォームに config.yaml に記述した、{{theme_static}}editor.css が入っていれば、記事編集のところでリッチテキストのモードにしたときに、CSSが適用されます。なお、先の行程で再適用しないか yamlファイルに記述しなかった場合は初期のサンプルのリンクのままですから、手動で入力してみます。

この場合は「変更を保存」しておきます。これで、記事の編集画面にてリッチテキストを使ったときに、スタイルが反映されています

use-editor-css.jpg

覚書:ダイナミックパブリッシング用関数で、変数渡ししないでプラグインの設定値の取得はどうするか

  • Posted by: maRk
  • memo

Movable Typeプラグインでダイナミック対応のPHPファイルを作るとき、プラグイン設定した値を得る方法がわからないことがあったのでメモしておきます。

通常は、以下のような形でプラグインで設定した値(Config-value 以下、単に「設定値」と表記します)をゲットします。ブログ単位の設定値

function smarty_function_myplugin( $args, &$ctx ) {
    $mt = MT::get_instance();
    $blog_id = 'blog:' . $ctx->stash('blog_id');
    $config = $mt->db()->fetch_plugin_data('MyPlugin', 'configuration:' . $blog_id);
    $cfgval_blog = $config['config_value'];
return  $cfgval_blog;
}

これを、第3引数で$ctx を渡そうとしたら、$ctxを直接受け取れないかんじだったので躓いていました。

なお、動作確認したときの環境はMTOS 5.14 + PHP5.2系およびPHP5.3系にて

設定値は、MT::get_instance();としたあとで、 contextを変数へ代入。

function smarty_function_myplugin( $text, $args ) {
    $mt = MT::get_instance();
    $ctx =& $mt->context();
    $blog_id = 'blog:' . $ctx->stash('blog_id');
    $config = $mt->db()->fetch_plugin_data('MyPlugin', 'configuration:' . $blog_id);
    $cfgval_blog = $config['config_value'];
    return  $cfgval_blog;
}

演習:特定カテゴリ下のサブカテゴリのリストを指定数でグループ化して出力する

  • Posted by: maRk
  • memo | tmpl

Movable Typeのコミュニティサイト、MTQで質問のあったケースの演習をおこないました。

すでに模範解答がでているようですので、詳細はそちらに譲ります。このような場合は剰余演算を使って行なうのが通例のようです。

__counter__、__last__ といった特殊な変数が利用できないケースでは、変数をセットして自前のカウンターを用意する必要があるのでこれがプログラミング的要素がでてきて厄介なのであります。

ここでは、余りを求めないでおこなうというやり方でやってみるという課題にしておきます。

考えたこと

  • ループの4回目の先頭に</ul> がつくというルールにすればいい(わりとこういう考え方がポイント)。
  • カウント数は変数なので使い回していく
  • リストを出力させるごとに、カウンターを 0・1・ 2 ...という具合に振っていく
  • カウンターが 3(つぎのグループの先頭) になったら </ul>をつけて カウンター0 からスタートさせる

作成したテンプレートサンプル

  • ※テスト環境用のモノなので実際の運用のための最適化をしていません。
  • ※先の命題のとおりで、ある親カテゴリ下に属する子カテゴリのみをリスト表示するためだけのテンプレートです。
  • ※ 条件判断のMT:Unlessは好みでそうしているだけなので、MT:Ifでnot equal な判断でも同じです
<h3>サブカテゴリのリスト</h3>
<mt:Setvar name="cont" value="0">
<MTSubCategories category="サブカテゴリの親のカテゴリ">
          <mt:If name="cont" eq="0">
          <ul class="group">
          </mt:If>
          <li><$mt:CategoryLabel$> ($contの値=<$mt:Var name="cont"$>)</li>
          <mt:Unless name="cont" eq="3"><mt:SetVar name="cont" value="1" op="+"></mt:Unless>

          <mt:If name="cont" eq="3">
          <mt:SetVar name="cont" value="0">
          </ul>
          </mt:If>
          <mt:SubCatIsLast></ul></mt:SubCatIsLast>
</MTSubCategories>

処理の流れを文章化してみた

カウンターを 0 にセットしておく

==ここからループ開始 ==

カウンターが 0 であるか ?  Yes  ->  </ul> をつける
 ↓
No  -> カテゴリラベルを表示 
    ↓
カウンターが 3 ではない ?  Yes ->  カウンターに1を足す
    ↓
カウンターは 3 である(== 4番目のリストである ) ?  Yes ->  カウンターを 0 にもどす </ul> をつける
 ↓
No
 ↓
サブカテゴリリストの最後か?  No -> ループのはじめに戻る ==>
↓
 Yes ->  </ul> をつける。ループの終了

一見、子カテゴリがちょうど3の倍数であったときに、リストの閉じタグ(</ul>)が重複するのでないか、という風に見えますけれども、先にいったとおりに、次のグループの先頭に</ul> を入れるというルールにしてあるので、ループが子カテゴリの最後になったときは次のグループが存在しないために</ul>は振られません。その代わりとしてmt:SubCatIsLastの条件において</ul>を振るということにしてあります。

但し。。

この方法だと、セットした変数にリセットをかけていますから、カウントの変数の値を使ってユニークなIDを振るといった処理には適用できません。

そのような時は、普通にカウントをインクリメントにして剰余を求めたほうがいいです。

MTタグの結果をJavaScriptのArrayオブジェクトに渡すためのテンプレート

  • Posted by: maRk
  • memo | tmpl

あれこれとやっていて頓挫してしまったので、テンプレートの一部分だけを公開してみます。

以下は、エントリーにつけられたタグ名をもとにしてArrayオブジェクトに使用できるようにする出力を得るためのテンプレートです。

<MTEntryIfTagged>
<MTSetVarBlock name="TagName">
<MTEntryTags glue=','>
<$MTTagName normalize="1" encode_js="1" regex_replace='/(.*)/','"$1"'$>
</MTEntryTags>
</MTSetVarBlock>
</MTEntryIfTagged>

MTMLでglueモディファイアのように任意文字で結合するというのはありますが、任意の文字でラッピングするといったものはグローバルモディファイアを組んだりしないといけないので、regex_replaceで対応することにします。

後は、以下の通りにnew ArrayにgetVarすれば、そのままJavaScriptの配列として扱えるようになりました。

var words = new Array(<$MTGetVar name="TagName"$>);

MTのアカウント認証ロックアウト機能をためす

  • Posted by: maRk
  • memo

MovableTypeの5.13からのセキュリティ強化の一機能、アカウント認証のロックアウトについてです。

セキュリティを強化するため、Movable Type 5.13から、アカウントの認証ロックアウト機能が追加されています。

今回は、テストとして新たにユーザーを作成して、そのユーザーの管理ページログイン時にロックされるかを動作確認しました。環境はMacにインストールしたローカルによるものです。

user-lock-test-01.png

デフォルトでは、1800秒の間に6回の認証失敗でロックされる条件となっています。これは機械的なログオンをおこなわなくとも達成される時間であります。

このユーザーはロックがかかったので、システム管理者にてログインしてユーザー一覧をみます。

user-lock-test-02.png

テストで作成したユーザーの状態をみてみます。

user-lock-test-03.png

「ロックを解除する」をクリックして解除できます。

user-lock-test-04.png

MTで記事に指定したタグをもとにDeliciousのタグフィード情報を得る

  • Posted by: maRk
  • memo

Movable Typeで記事に指定しているタグに基づいて、自分のDeliciousアカウントから同一のタグのフィードの情報をGoogle AJAX Feed APIを使って取得してみます。

基本的なところとして、DeliciousのフィードのAPIをおさえておきます。

自分のアカウント(ここで提示するコード上では、{your Delicious account})の特定タグのフィードを得るAPIは以下のようになっています。

http://feeds.delicious.com/v2/rss/{your Delicious account}/{TagName}

タグが設定された記事を想定するので、表示のコード一式をMTEntryIfTaggedで囲みます。

<mt:EntryIfTagged>

<mt:SetVarBlock name="entryTagArray">
<mt:EntryTags glue=",">
  <mt:TagName>
</mt:EntryTags>
</mt:SetVarBlock>


<script type="text/javascript" src="http://www.google.com/jsapi?key={your api key}"></script>
<script type="text/javascript">
var feedBase='http://feeds.delicious.com/v2/rss/{your Delicious account}/';
google.load("feeds", "1");
       function OnLoad() {
// create a feed control
       var feedControl = new google.feeds.FeedControl();
       feedControl.setNumEntries(10);

var tagsArray = "<$MTGetVar name="entryTagArray" strip_linefeeds="1" regex_replace="/[  ]+/g",""$>".toLowerCase().split(",");
   for (var i=0; i<tagsArray.length; i++){
            feedControl.addFeed(feedBase + encodeURIComponent(tagsArray[i]), tagsArray[i])
   }

feedControl.draw(
  document.getElementById("feedContent"),
  {
    drawMode : google.feeds.FeedControl.DRAW_MODE_TABBED,
  });
}

google.setOnLoadCallback(OnLoad);
</script>
<mt:EntryIfTagged>

Google APIの呼び出しをおこないます(key=のあとには自分のAPI keyをいれます。keyをつかわないときは、クエリなしの/jsapiどまりのURIで動作します)。

tagのArrayを作ります。サンプルではコードの視認性の理由で一旦変数に渡しています。

.split(",")をつけることで、配列としてあつかうようになります。これを配列の数だけまわして、feedControl.addFeed()を繰り返すことで複数のタグのフィードを登録するということをおこなっています。

toLowerCase()を使っているのはDeliciousでは大文字/小文字が区別はないようですので統一のためです。

feedControl.setNumEntries(Number)では、取得件数を指定しています。

上記のコードは、個別エントリテンプレートのhead要素内にいれておきます。

Feedの流し込み先に以下の部分を用意して再構築して完了です。サンプルではfeedContentというIDにFeedを入れるようになっています。

<div id="feedContent">loading...</div>

テストページは、以下にあります。

http://www.markdiary.com/sample/tag_to_deliciousfeed-test.html

特定class名にイベントトラッキング(私用版

  • Posted by: maRk
  • memo

あるclass名がついたリンクにGoogle Analyticsのイベントトラッキングをいれるというもの。

自分でだましだまし使っている状態なので、動作は保証できませんが。

外部スクリプトファイルで読み込ませてその中身。

(function (){
var a = document.getElementsByTagName('a');
for (var i=0; i<a.length; i++) {
  if (a[i].className=='event_link') {
        a[i].addEventListener ? a[i].addEventListener( 'click' , tkevent_link , false ):a[i].attachEvent('onclick',tkevent_link);
     }
  if (a[i].className=='event_file') {
        a[i].addEventListener ? a[i].addEventListener( 'click' , tkevent_file , false ):a[i].attachEvent('onclick',tkevent_file);
     }
}

function tkevent_link(){
try {
 var that=this;
_gaq.push(['_trackEvent','link','external', this.href ]);
	setTimeout(function(){window.location.href=that.href}, 300)
}catch(err){};
return false;
}

function tkevent_file(){
try {
 var that=this;
_gaq.push(['_trackEvent','download','file', this.href ]);
    setTimeout(function(){window.location.href=that.href}, 300)
}catch(err){};
return false;
}
})()

外部リンクなときに、event_linkとclassを振った場合にイベントにあわせたトラッキングを実行という形。href属性がある場合にタイミングでトラッキングがおこなえないことがあるので、setTimeoutでページ移動を遅らせてみたり。タイマーの値が大きすぎると、ファイルなど2重ダウンロードになるので注意

追記

割り込み時間が短すぎてもだめなときがあるようなので様子見で。冗長な感じはするけどダウンロードファイルは特にページ遷移をおこさないようにしてみたり。外部ページのほうは一旦hrefを削除してそもそものリンクが先に移動しないような感じに。href属性値が無しというか'#'とか'javascript:'のようなhttpでないようなのでないと正確に計測できないような気がします。

(function (){
var a = document.getElementsByTagName('a');
for (var i=0; i<a.length; i++) {
  if (a[i].className=='event_link') {
      a[i].addEventListener ? a[i].addEventListener( 'click' , recordOutboundLink, false ):a[i].attachEvent('onclick',recordOutboundLink);
     }

  if (a[i].className=='event_file') {
      a[i].addEventListener ? a[i].addEventListener( 'click' , tkevent_file , false ):a[i].attachEvent('onclick',tkevent_file);
     }
}

function tkevent_file(){
try {
    if(window.event.srcElement){
    var that = event.srcElement.href;
    } else { var htat=this.href; };
  _gaq.push(['_trackEvent','download','file',that]);
 setTimeout(function(){return;},300);
}catch(err){};
}

function recordOutboundLink() {
  try {
var msie = navigator.appVersion.toLowerCase();
msie=(msie.indexOf('msie')>-1)?parseInt(msie.replace(/.*msie[ ]/,'').match(/^[0-9]+/)):0;
// Browser checker  
 if(msie<9 && msie!=0){
    var that = event.srcElement.href;
      } else { var that=this.href; };
    _gaq.push(['_trackEvent','link','external',that]);
    this.removeAttribute('href');
    setTimeout(function(){ location.href=that; }, 800);
  }catch(err){}
}
})()
// 111007 www.markdiary.com
// Browser Checher by http://www.losttechnology.jp/WebDesign/2011/ieversion.html

IE 8以下でthatの値がとれないようなので event.srcElementを使ってみることに。Safari Opera Chromeが対応しているようで、window.event.srcElement?で振り分けてもいいのかな、という気がしないでもないけどいちおう。

Delicious BookmarkのエクスポートをEvernoteへ

  • Posted by: maRk
  • memo

Delicious BookmarkでエクスポートしたファイルをEvernoteにとりこむことにしました。

本当のところはJSON形式のファイルに加工しなおして再利用してみようかとおもったんですが、Evernoteでもいいかとおもってそのようにすることとしました。

取り込むときにDeliciousのエクスポートファイルはHTML形式ですが、Netscape Bookmark File Formatにより、そのままHTMLとして出力したものだとちょっと物足りないものがあります。

そこで、一旦落としてきたエクスポートファイルを以下のように加工したものをEvernoteに保存しています。

Perlで加工する

Web::Scraperを使ってタグと登録時刻の情報を追加して以下のようなかんじに。

時間の情報を取り込もうとしていたら、add_dateという属性の値がエポック秒というものらしくて、これを変換するのにDateTimeを使う事にしました。

#!/usr/bin/perl -w

use strict;
use Web::Scraper;
use URI;
use CGI;
use utf8;
use Encode;
use DateTime;

print CGI->header(-charset=>'utf-8', -type=>'text/html');


my $url = "http://localhost/cgi-bin/bookmark.html";

my $scraper = scraper {

    process "dt>a",

      'results[]' => { 'link' => '@href' ,
                       'title' => 'TEXT' ,
                       'tags' => '@tags' ,
                       'time' =>'@add_date' ,
      };

};

my $res =  $scraper->scrape( URI->new($url));

my $header = <<"HERE";
<!DOCTYPE html>
<meta charset="utf-8">
<title>Bookmarks</title>
HERE

open (OUT, ">bookmarklist.html");
      print OUT $header;
print OUT '<ul>';

for my $bookmark (@{$res->{results}}) {
	  print OUT '<li><a href="' . $bookmark->{link}. '">'; 
	  print OUT encode('utf-8', $bookmark->{title}) .'</a>';
      print OUT ' : ' . $bookmark->{tags} . ' : ';
	  print OUT DateTime->from_epoch(epoch => $bookmark->{time} , time_zone => 'local' );
	  print OUT '</li>' . "\n";
}

print OUT '</ul>';

print $header;
print '<P><A HREF="bookmarklist.html">TEST</A></P>';

mtVicunaSimpleでSitemapテンプレートのタグに関するエラーの件

  • Posted by: maRk
  • memo

つかわせてもらってるmtVicuna SimpleでSiteMap 0.9のところで、テンプレートタグのエラーがでていたのでちょっと回避技をやってみました。

エラーのメッセージは、<MTGoogleSitemapsPing>は存在しません(3行目)といったものです。

これはそのタグを提供する、MTGoogleSitemapsPingというプラグイン自体がないもので、MTIfタグでタグの値の有無の判断がプラグインがないためできないみたいです。

以下のMTQでやりとりがありまして、プラグインをいれるというのが解決策のようです。

それでは、プラグインは使わないけどメッセージが鬱陶しいので出さないようにするようなときの改造です。

理屈からいうと、知らないタグだといわれたタグをダミーで登録してしまうというものです。バッドノウハウなのですけども、ローカル環境での作業ならこれでも十分な感じです。(実際にプラグインをいれてテンプレート更新すると無駄にPing送信されてしまうので)

config.yamlの修正

mtVicuna Simpleはテーマセットですが、プラグインによって提供されています。その設定はconfig.yamlにほとんどが集約されています。

tags:
function:のところに、以下を追加してダミーのファンクションタグとして登録しておきます。修正には空白のインデント位置に注意します。

    GoogleSitemapsPing: $mtVicunaSimple::mtVicunaSimple::Plugin::_google_site_map_ping

これだけでタグが登録されていちおうはテンプレート編集でエラーメッセージはでなくなります。

きちんとやろうとすれば、_google_site_map_pingのサブルーチンをvicunaのPlugin.pmにでもおけばいいのですが、ここにGoogleにPing送信するコードがあればそのような動作も可能でしょう。しかしながらテンプレートセットがそこまでサポートするほどでもないのかなとは思っています(別のプラグインが必要だったとしてバンドルするのにライセンスとかも考えないといけないだろうし)。あるプラグインがはいっているかどうかの判断が容易であればいいような気もしますね

Index of all entries

Home > memo Archive

Search

Feeds

Return to page top