We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 32580
    • 25 Posts
    いつもお世話になっています。
    今回はメニュー表示についての質問です。

    以下のような構造です。
    親カテゴリー
     └子カテゴリー1
      └ドキュメントA
      └ドキュメントB
      └ ・・・
      └ ・・・
      └ドキュメントZ
     └子カテゴリー2
      └ドキュメントA
      └ドキュメントB
      └ ・・・
      └ ・・・
      └ドキュメントZ

    この状態で、親カテゴリーのページに、全ての子カテゴリーから各最新5ドキュメントをリストアップさせたいのです。
    実際は子カテゴリーは4,5あったり、その中で子カテゴリーによっては最新のものが2008年であったり、2006年であったり、
    またドキュメントの数もことなるので、wayfinderでlimitを使ってもだめでした。
    親カテゴリーのページにいくつものwayfinderを張れば解決するのでしょうが、
    wayfinderあるいはdittoを1度だけ使ってこのようなことは可能でしょうか?
    よろしくお願いします。
      • 36592
      • 970 Posts
      美しいのはDittoのextenderを自作することだと思いますが、
      ここに各子カテゴリーから1つだけのドキュメントを取ってくる例がありますので、
      これを5つに変更すればできそうな...?

      Dittoのテンプレート中にDittoを書くという技のようです。
      5つにするとソートが利かなくなるかもしれませんね~
        • 32580
        • 25 Posts
        リンク先のようにやっていましたが、以下のようなエラーとなり、表示されませんでした。
        Fatal error: Maximum execution time of 30 seconds exceeded in /manager/includes/document.parser.class.inc.php on line 59

        これはやはりファイル数が多いためにループしているということでしょうか。
        ちなみにdittoを置いているファイル以下には121ドキュメントあります。
        つまり121回、dittoコールされている。。。

        extendersの自作は、今の自分にはかなりハードルが高そうです。。

        また、現在は、その場しのぎで、wayfinderの&showSubDocCount=`true`を使って子カテゴリーの数だけを表示させています。
          • 36592
          • 970 Posts
          Quote from: wmo at Aug 05, 2008, 09:16 PM

          ちなみにdittoを置いているファイル以下には121ドキュメントあります。
          子カテゴリーが121個もあるんですか...
          その環境ではこのやり方はちょっと実用的じゃないですね。

          やってみたわけではありませんが...

          1. 子カテゴリーのページにTVを作り、@selectでその子カテゴリー配下のドキュメントから最新の5個のidをセットする。
            例えば「2,5,8,10,25」みたいな5つの数値がコンマ区切りでTVにセットされる。

          2. 親カテゴリーのページにDittoを使うが、&parentsではなく&documentsを使う。
            この&documentsの値に、全ての子カテゴリーのTVの値をコンマでくっつけて代入する。

          でできそうな気はしますが ?
            • 32580
            • 25 Posts
            すいません。
            解決したようです。
            先のリンク先のコードでドキュメントが指定してあったのを&depth=`2`としていたのがいけなかったようです。
            [[Ditto? &depth=`1` &tpl=`dittoSubCall` &display=`all`]]

            親カテゴリーにこうすることで、5-6件ある子カテゴリーの数だけdittoコールということになりました。

            121というのは複数の子カテゴリーがもつドキュメントの総数でした。

            とりあえずこれでやってみます。
            そんなにページのロード時間もそんなにおそくないです。
            dittoの下にまたdittoという発想はまたなにかで使えそうです。。

            ありがとうございました。

            PS:TVを作り、@selectで、というのはまったくどうしていいかわかりませんでした。。。
              • 36592
              • 970 Posts
              GetChildIdsというスニペットがありましたので、これを参考に自作してみました。
              PHPのコーダーではないので見よう見まねです。
              とりあえず動きそうなので、他の方がBrushUpして頂けることを期待して公開しますね。
              (あくまでも他人頼み... tongue)

              まず以下のSnippetを作ります。ここでは仮に名称を「ListLatest」とします。
              <?php
              
              $docid = (isset($docid))? $docid: $modx->documentIdentifier; 
              $sortBy = (isset($sortBy)) ? $sortBy : 'menuindex';
              $sortDir = (isset($sortDir)) ? $sortDir : 'ASC';
              $itemNumber = (isset($itemNumber)) ? $itemNumber : 3;
              
              if( !function_exists(getNumberLimitedChildIds) ) {
                function getNumberLimitedChildIds( $docid, $sortBy, $sortDir, $number ) {
                  global $modx;
                  $children = $modx->getActiveChildren($docid, $sortBy, $sortDir,'id');  
                  if( !$children === false ) {
                    $idArray = array();
                    $count = 0;
                    foreach( $children as $c ) {
                      $idArray[] = $c['id'];
                      if( ++$count == $number ) break;
                    }
                    $output = implode(',',$idArray);
                  } else {
                    $output = $docid;
                  }
                  return $output;
                }
              }
              
              $children = $modx->getActiveChildren( $docid, $sortBy, $sortDir, 'id' );
              if( !$children === false ) {
                $outputArray = array();
                foreach( $children as $c ) {
                  $tmpIds = getNumberLimitedChildIds( $c['id'], $sortBy, $sortDir, $itemNumber );
                  if( $tmpIds == $c['id'] ) continue;
                  else $outputArray[] = $tmpIds;
                }
                $output = implode(',',$outputArray); 
              } else {
                $output= $docid; 
              }
              
              return $output;
              
              ?>
              

              このSnippetの引数は4つあります。

              &docidは、wmoさんの最初の投稿で言う「親カテゴリー」に相当するドキュメントのIDです。
              &itemNumberは、子カテゴリー配下のドキュメントの中からいくつのドキュメントを抽出するかを指定します。
              &sortByと&sortDirは、子カテゴリー配下のドキュメントの中から上記で指定された数のドキュメントを抽出する際に、どういう並び順で抽出するかを指定します。

              例えば...「親カテゴリーのIDが20で、それぞれの子カテゴリーの中から更新時間の新しいものから5つ抽出」という条件だとすれば、
              [!ListLatest? &docid=`20` &sortBy=`editedon` &sortDir=`DESC` &itemNumber=`5`!]
              

              と言う風に使います。

              このスニペットで抽出されるのは、Dittoでの表示に必要なドキュメントのIDをカンマ区切りで繋いだもので、例えば「2,52,44,15,33」のような出力が得られます。

              で、最終的に親カテゴリーに相当するドキュメントにDittoを置きます。
              例えば以下のような感じで...
              [!Ditto? &documents=`[[ListLatest? &docid=`20` &sortBy=`editedon` &sortDir=`DESC` &itemNumber=`5`]]` &tpl=`ditto_blog` &sortBy=`editedon` &display=`all`!]
              

              こんな感じで私の環境では表示できた...ように思います...(自信なし! :’()
                • 32580
                • 25 Posts
                おお、すばらしい。
                試してみました。うまくいきました。
                そしてListLatestのほうが速く、負担にならないようです。
                ListLatest:
                MySQL: 0.0033 s, 6 request(s), PHP: 0.8535 s, total: 0.8567 s
                Ditto / Ditto:
                MySQL: 0.0905 s, 29 request(s), PHP: 1.6702 s, total: 1.7607 s

                しかし。。欲を言えば、レイアウト的には、
                ditto の入れ子方式の方が
                子カテゴリー名を表示できたりするので、便利かと。。。

                現在は、親カテゴリーに
                [[Ditto? &depth=`1` &sortBy=`pud_date` &tpl=`dittoSubCall` &display=`all`]]

                として、
                dittoSubCallには
                <H2>[+pagetitle+]/[+longtitle+]:</h2>
                [[Ditto? &parents=`[+id+]` &tpl=`rubrique` &display=`3`]]
                <a href="[~[+id+]~]">[+longtitle+]一覧</a>
                

                こうなっているので。

                ListLatestのほうとはうまく使い分ければと思います。
                (というか、すべてdittoでできるのが理想でしょうが。。。)