We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 36592
    • 970 Posts
    Quote from: dainiti at Mar 09, 2009, 01:20 AM

    modx の rss_fetch.inc の function fetch_rss ($url)内でもやはり 304 も ETagもきっちり入っています。
    MagpieとかSimplePieとかあんまり理解していませんが... この関数はRSSを読み込んでくる方の関数ですね。
    管理画面でmodxの最新情報とかセキュリティ情報を表示するのに使われています。
    多分、Last-Modifiedとかを出力する関数ではないのでは?
      • 6350
      • 421 Posts
      すんません、tkfm さんの意見見逃していました。
      Quote from: tkfm at Mar 09, 2009, 01:20 AM

      これだと、RSSのドキュメント自身が編集されないと、値が変化しないのでは?
      RSS出力対象になっているドキュメントを全部サーチして、
      その中でeditedonが一番新しい(大きい)値を探してこないといけないような気がします。
      そんなことはないですよ。Date の部分はアクセスするたびに、ちゃんと変化しているので。
      問題は $modx->documentObject["editedon"]) では modx 全体の記事の最終更新時刻になってしまうので。RSS のフォルダ以下より最新記事の時刻が取得できれば一番いいのですが。たぶん Ditto でそれも取得できるんじゃないでしょうか。

      Quote from: tkfm at Mar 09, 2009, 01:20 AM

      過去にも語られていますが、結局ページ毎に何の値をもって更新されたと判断するかが難しい...のでは?
      (RSSの場合は上記のような感じでしょうが、それ以外のページではまた違うのかも?)
      http://modxcms.com/forums/index.php?topic=4569.0
      とりあえずはこれでもいいと思うのですが本来は RSS に指定されたフォルダ以下から取るべきでしょうね。
      WordPress でも同じような処理になっていますし。WordPress はほとんどが記事なのでそれでもいいのかも?

      ようするにトップページは記事全体の更新日時 $modx->documentObject["editedon"]) かな?
      createdon とかは普通使わないと思います。作成後に更新した場合にRSSが変化しなくなるので。。。
      公開日時とかを指定したい場合でもその後に編集は有ると考えないとおかしくなるし。

      Quote from: yama at Mar 09, 2009, 01:34 AM

      あ、えーーと・・・CMSの開発者がという意味ではなくて、クライアント側がetagを無視することが多いということです。
      でもこれ、検証がけっこう厄介ですよ。tkfmさんも指摘されてますが、何をもって最新とするかは運用によっても違いますし。
      WordPress と同じように最新記事の時刻を MD5で暗号化した文字列を返すだけでいいと思います。
      最新記事の時刻さえ取れればこの処理自体は難しいことではないですよね。
        • 6350
        • 421 Posts
        Quote from: tkfm at Mar 09, 2009, 01:20 AM

        過去にも語られていますが、結局ページ毎に何の値をもって更新されたと判断するかが難しい...のでは?
        (RSSの場合は上記のような感じでしょうが、それ以外のページではまた違うのかも?)
        http://modxcms.com/forums/index.php?topic=4569.0
        上記の例はすべての記事をキャッシュさせたくない場合の例ですよね。
        manager/index.php を参考に僕が一番最初に試した方法で簡単でいいのですが RSSには向いてないですし参考にはなりませんよ

        とりあえずサイト完成後の更新はほとんどが blog 内の更新になると思うので
        header("Last-Modified: " . gmdate(’r’, $modx->documentObject["editedon"]) . " GMT");
        を使うのでも暫定的には問題はないと思います。

        あれこれ考えて何もできないよりは ・・
        yama さんの言うように検証は一番難しい領域ですね。テスト環境では bot に登録されると困るし。実環境でないとできない。しかも新規のサイトでないと初期のアクセス状況だけがちがうので。。それでも規格に沿った出力をしていてエラーにならなければいいんではないでしょうか。http://web-sniffer.net/ で確認できる程度で・・

        通常の html サイトから modx への置き換えでも違いがわかります。検証方法は baidu から何十時間もアクセスが続くかどうかです (・・? Last-Modified と ETag のどちらが有効でアクセスが変わってくるのかは別にして ETag の出力はそれほど手間のかかる部分ではないので入れるべき(ETagは重要という人がいる限り)

        参考:WordPress classes.php L331~333

        $wp_etag = ’"’ . md5($wp_last_modified) . ’"’;
        @header("Last-Modified: $wp_last_modified");
        @header("ETag: $wp_etag");
          • 33014 ☆ A M B ☆
          • 1,231 Posts
          Quote from: dainiti at Mar 09, 2009, 02:01 AM

          WordPress と同じように最新記事の時刻を MD5で暗号化した文字列を返すだけでいいと思います。
          最新記事の時刻さえ取れればこの処理自体は難しいことではないですよね。
          もともとETagはそういうものなので・・・
          最新時刻の取得自体はDittoでできると思いますが、Dittoで条件付きGETを実装することはできないので、自前でプラグインを作る程度の難しさはあると思います。
            • 6350
            • 421 Posts
            Quote from: tkfm at Mar 09, 2009, 01:41 AM

            MagpieとかSimplePieとかあんまり理解していませんが... この関数はRSSを読み込んでくる方の関数ですね。
            管理画面でmodxの最新情報とかセキュリティ情報を表示するのに使われています。
            多分、Last-Modifiedとかを出力する関数ではないのでは?
            そうなんですか ・・ よく考えれば fetch ですからね。。全面的に WordPress を参考にするのが早いかもですね

            Quote from: yama at Mar 09, 2009, 02:39 AM

            もともとETagはそういうものなので・・・
            最新時刻の取得自体はDittoでできると思いますが、Dittoで条件付きGETを実装することはできないので、自前でプラグインを作る程度の難しさはあると思います。
            yama さんつくりかけのプラグインで実装お願いします。標準添付のプラグインになるようにがんばってください (・・?
            RSS の場合 extender では無理ですか?
            とりあえずベータ版は常に +200でいいかな
              • 33014 ☆ A M B ☆
              • 1,231 Posts
              そうですね、200で問題ないと思います。たぶん検索エンジンから見て、Last-Modifiedが常にアクセスした瞬間の日時で、かつレスポンスコードが200であれば、ここはphpか何かで動的に生成しているコンテンツだと見て判断を切り換える仕組みになってるのだと思います。僕は確認してませんが、MODxではLast-Modifiedを出力してないということなので、そこで判断が揺らいでしまっている可能性はありますね。違う気もするけど・・・

              ちなみにbaiduはかなり気まぐれなロボットなので、あまり気にしないほうがいいと思いますよ。まじめに分析している人もほとんどいないと思います。僕の場合はbaiduが来たらむしろ追い返すことにしてます。
                • 6350
                • 421 Posts
                Quote from: yama at Mar 09, 2009, 03:11 AM

                ちなみにbaiduはかなり気まぐれなロボットなので、あまり気にしないほうがいいと思いますよ。まじめに分析している人もほとんどいないと思います。僕の場合はbaiduが来たらむしろ追い返すことにしてます。
                あまりしつこくて僕も好きじゃないけど 70時間以上一ヶ月も続けてアクセスがあったのは modx にしてからなんで検証用のテスト道具としてはちょうどいいかも、といったところです。

                だけど画像の検索精度は google よりも数段上なんですよね。
                それにしても今日は何でこんなにレスポンスが早いんだ。考えてる暇がない  embarrassed
                  • 6350
                  • 421 Posts
                  Quote from: tkfm at Mar 09, 2009, 01:20 AM

                  これだと、RSSのドキュメント自身が編集されないと、値が変化しないのでは?
                  RSS出力対象になっているドキュメントを全部サーチして、
                  その中でeditedonが一番新しい(大きい)値を探してこないといけないような気がします。
                  読み返してて、今頃になって気が付きました。
                  atom.format.inc.php がこれを使ってたので最新の更新日時を取ってるんだと思ってました
                  gmdate(’r’, $modx->documentObject["editedon"]);

                  diito で最新の記事の更新日付を取ってくるべきですね
                  それともやっぱりループかな
                    • 6350
                    • 421 Posts
                    ・・・ ということでよく考えてみました。

                    よくよく考えてみるると dittoで最新の更新日時を取ってくるとか、どうやってループするのかわからないことに気が付きました。 laugh
                    それでどうすればいいのか考えてみましたが ・・

                    Windows のフォルダのように下にあるファイルが更新されたときに上のフォルダの更新日時を同時に更新しその時刻を利用すればループの無駄もなくなるんじゃないかということです。ドキュメントが増えるほど効果は出てきそうです。

                    ただひとつ、日時を更新するだけでも一度ドキュメント全体を読み込んでこなければいけないことですが、本文は[[Ditto なんたらかんたら ]] が入るくらいなので定型で書き込み内容を持っていれば読み込みの無駄はなくせそうです。

                    通常記事の最新時刻はどうやって取ってくるかですがこれも同じ方式でルートフォルダの更新時刻を書き換えればループはかなり少なくなるはずです。

                    ひとつ余分に更新日時専用のテーブルをつくってアクセスしたほうが無駄はなくせそうですが、そう言う仕掛けでできればフォルダ変数とか、共有変数がほしいな。こういうのってスニペットにする値打ちはあるでしょうか?だれか作ってください。
                      • 6350
                      • 421 Posts
                      「はじめてのプラグイン」を作成しました。
                      システムイベントは OnWebPagePrerender でサンプルサイト限定です。
                      誰にでも応用しやすくするためショートプログラムとしRSSページの値が固定になっています。
                      $site_start = $modx->config['site_start'];
                      switch ($modx->documentObject['id']) {
                      case $site_start:   // スタートページの場合ドキュメント全体からの最新更新時刻を出力する
                            $sql= "SELECT MAX(editedon) AS latest FROM ".$modx->getFullTableName("site_content")."WHERE published=1 AND deleted=0";
                            $result= $modx->dbQuery($sql);
                            $tmpRow= $modx->fetchRow($result);
                            $latest = $tmpRow['latest'];
                            header("Last-Modified: " . gmdate('r', $latest) . " GMT");
                            break;
                      case 11:            // RSS 出力対象のドキュメント最新時刻と ETag を出力する (階層は1レベルのみに限定)
                            $sql= "SELECT MAX(editedon) AS latest FROM ".$modx->getFullTableName("site_content")."WHERE published=1 AND deleted=0 AND parent=2";
                            $result= $modx->dbQuery($sql);
                            $tmpRow= $modx->fetchRow($result);
                            $latest = $tmpRow['latest'];
                            $etag = '"' . md5($latest) . '"';
                            header("Last-Modified: " . gmdate('r', $latest) . " GMT");
                            header("ETag: $etag");
                            header("X-Powered-By: dainiti");    // これがすごい
                            break;
                      }

                      クエリーもはじめて使うのでドキドキ
                      ここで取得した最新時刻を効率よく rss.format.inc.php に渡せる方法を模索中 ・・・
                      つづく  smiley