トップ  >  趣味の部屋  >  XOOPSサイト構築  >  picoタイトルのxpWikiへの外部Autoリンクに挑戦
xoops pico xpwiki レンダラー リンク

タイトルでリンク可能な特殊文字 anchor.png

タイトルに使っても大丈夫な文字 : $?\*+-/#@%~^ ()=|!{}[][[]]:;
その他、Σなどのマルチバイト文字も可能。

リンクされない文字 (xpWikiのAutoリンクの制約か) : &"'<>


以前より、とあるサイトでXwordsでxpWikiへの外部Autoリンクを便利に使っていました。
  (参考:xpwikiからxwordsへのリンクはできないでしょうか?-XOOPSマニア)

今回、積層スピーカーの会で、スピーカーDBをcosmoDBからpico(1.71系extra-fields)に乗り換えて、外部Autoリンクに挑戦してみました。

準備 anchor.png

Wrapモード=ON anchor.png

(080930変更)Autoリンクの際のアクセスを、

「(xoops_URL)/modules/(pico)/index.php?subject=ABC」

に変更しました。 以下、WrapモードONは必須ではなくなりました。

 Wrapモードにて、仮想パスでアクセス可能にします。
 具体的には、記事タイトルが

「ABC」

であれば、

「/ABC.htm」

という仮想パスを設定することにより、

「(xoops_URL/modules/(pico)/index.php/ABC.htm)」

でアクセス可能になります。

仮想パスの入力欄を常に表示 anchor.png

 defaultの状態では、仮想パス入力欄が出て来ません。

main_content_form.html の編集 anchor.png

「(trust_path)/modules/pico/templates/main_content_form.html」の、33行目と46行目を以下のようにコメントアウトします。
(080930追記)仮想パスでなくてもAutoリンク可能になったので、この変更は必須ではありません。

Everything is expanded.Everything is shortened.
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
        <!-- vpath -->
        <{* if $mod_config.user_wraps_mode || strstr($content.filters,"wraps") *}>
        <tr valign="top" align="left">
            <th class="head"><label for="vpath"><{$smarty.const._MD_PICO_TH_VIRTUALPATH}></label></th>
            <td class="even">
                <input type="text" name="vpath" id="vpath" size="70" maxlength="255" value="<{$content.vpath}>" class="pico_ascii_only" />
                <{if $xoops_isadmin}>
                    <br />
                    <select name="wraps_target" onchange="xoopsGetElementById('vpath').value=this.value;">
                        <{html_options options=$content.wraps_files selected=$content.vpath}>
                    </select>
                <{/if}>
            </td>
        </tr>
        <{* /if *}>

picoにソースを追加 anchor.png

X2の場合 anchor.png

picoで記事を作成・編集するたびに、ページ名一覧を正規表現でファイルに書き込む必要があります。 まずは、一覧を作成するソース。

entries_write.php anchor.png

「trust/modules/pico/include/entries_write.php」というファイルを以下の内容で作成します。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<?php
// xpwikiから picoへの自動リンクを貼るための、アドオン
// 元ネタ:xpwikiから xwordsへの自動リンクを貼るための、アドオン
// see http://xoops.hypweb.net/modules/forum/index.php?topic_id=2140 
// 小文字・大文字を区別しない? (0 or 1)
define('PAGE_CASE_INSENSITIVE', 0);
 
global $xoopsDB;
 
$temp_txt = XOOPS_ROOT_PATH."/uploads/".$this->mydirname."/entries_temp.php";
$entries_dat = XOOPS_ROOT_PATH."/uploads/".$this->mydirname."/entries.php";
$ent_table = $xoopsDB -> prefix ("{$this->mydirname}_contents") ;
 
if ($fp1 = fopen($temp_txt, 'wb')) {
    $result_entries = $xoopsDB -> query( "SELECT subject FROM $ent_table" );
    while ( list( $entry_term ) = $xoopsDB -> fetchrow( $result_entries ) ) {
        if(mb_strlen($entry_term)>2) {fwrite($fp1, $entry_term."\n");
        }
    }
    fclose($fp1);
}
 
$dats = file($temp_txt);
$dat = get_matcher_regex_safe($dats);
if ($fp2 = fopen($entries_dat, 'wb')) {
    fwrite($fp2, $dat);
    fclose($fp2);
}
 
function get_matcher_regex_safe ($pages, $spliter = "\t", $array_fix = true, $nest = 0) {
    if ($array_fix) {
        $pages = array_map('trim', $pages);
        if (PAGE_CASE_INSENSITIVE) $pages = array_map('strtolower', $pages);
        $pages = array_unique($pages);
        foreach(array_keys($pages, '') as $key) {
            unset($pages[$key]);
        }
        sort($pages, SORT_STRING);
    }
    
    ++$nest;
    $reg = get_matcher_regex_safe_sub($pages);
    $regs = preg_split("/(\d+)\x08/", $reg, -1, PREG_SPLIT_DELIM_CAPTURE);
    $pats = array();
    $index = 0;
    reset($regs);
    while (list($key, $pat) = each($regs)) {
        list($key, $val) = each($regs);
        if (!$val) $val = count($pages);
        if (@ preg_match('/' . $pat. '/', '') === false) {
            if ($nest <= 10) {
                $count = $val - $index;
                $split = floor(($val - $index) / 2);
                $pages1 = array_slice($pages, $index, $split);
                $pages2 = array_slice($pages, $split, $count - $split);
                $pats[] = get_matcher_regex_safe($pages1, $spliter, false, $nest);
                $pats[] = get_matcher_regex_safe($pages2, $spliter, false, $nest);
                $index = $val;
            }
        } else {
            $pats[] = $pat;
        }
    }
    return join($spliter, $pats);
}
 
function get_matcher_regex_safe_sub (& $array, $offset = 0, $sentry = NULL, $pos = 0, $nest = 0)
{
    static $g_count = 0;
    
    ++$nest;
    $limit = 1024 * 32 - 10;
    
    if (empty($array)) return '(?!)'; // Zero
    if ($sentry === NULL) $sentry = count($array);
    
    // Too short. Skip this
    $skip = ($pos >= mb_strlen($array[$offset]));
    if ($skip) ++$offset;
 
    // Generate regex for each value
    $regex = '';
    $index = $offset;
    $multi = FALSE;
    $reglen = 0;
    while ($index < $sentry) {
        if ($index != $offset) {
            $multi = TRUE;
            if ($nest === 1 && strlen($regex) - $reglen > $limit) {
                $reglen = strlen($regex);
                $regex .= ')'.($index)."\x08(?:";
                $g_count = 1;
            } else {
                $regex .= '|'; // OR
            }
        }
 
        // Get one character from left side of the value
        $char = mb_substr($array[$index], $pos, 1);
 
        // How many continuous keys have the same letter
        // at the same position?
        for ($i = $index; $i < $sentry; $i++)
            if (mb_substr($array[$i], $pos, 1) != $char) break;
        
        if ($index < ($i - 1)) {
            // Some more keys found
            // Recurse
            $regex .= str_replace(' ', '\\ ', preg_quote($char, '/')) .
            get_matcher_regex_safe_sub($array, $index, $i, $pos + 1, $nest);
        } else {
            // Not found
            $regex .= str_replace(' ', '\\ ',
            preg_quote(mb_substr($array[$index], $pos), '/'));
        }
        $index = $i;
    }
    
    if ($skip || $multi){
        $g_count++;
        $regex = '(?:' . $regex . ')';
    }
    if ($skip) $regex .= '?'; // Match for $pages[$offset - 1]
    return $regex;
}
 
?>

pico本体ソースの変更 anchor.png

続いて、このソースをインクルードする部分の編集です。 なお、記事は自動承認される場合のみ、有効にしています。 承認が必要な場合は、別に承認処理のソースに手を入れる必要があります。
X2の場合はこのフックは必須です。

PicoControllerInsertContent.class.php の編集 anchor.png

「(trust)/modules/pico/class/PicoControllerInsertContent.class.php」に下記の76行目の追記。

75
76
77
78
79
80
81
82
83
84
85
    if( $cat_data['post_auto_approved'] ) {
               include_once( dirname(dirname(__FILE__)).'/include/entries_write.php' );    //naao
        // Notify for new content 'global'
        pico_main_trigger_event( $this->mydirname , 'global' , 0 , 'newcontent' , $extra_tags , $users2notify , 0 ) ;
        // Notify for new content 'category' of all parental categories
        foreach( array_keys( $cat_data['paths_raw'] ) as $cat_id ) {
            pico_main_trigger_event( $this->mydirname , 'category' , $cat_id , 'newcontent' , $extra_tags , $users2notify , 0 ) ;
        }
        // message "registered"
        redirect_header( $ret_uri4html , 2 , _MD_PICO_MSG_CONTENTMADE ) ;
    } else {
PicoControllerUpdateContent.class.php の編集 anchor.png

「(trust)/modules/pico/class/PicoControllerUpdateContent.class.php」に下記の75行目の追記。

74
75
76
77
78
79
    if( $cat_data['post_auto_approved'] ) {
               include_once( dirname(dirname(__FILE__)).'/include/entries_write.php' );    //naao
               
        // message "modified"
        redirect_header( $ret_uri4html , 2 , _MD_PICO_MSG_CONTENTUPDATED ) ;
    } else {
PicoUriMapper.class.php の編集 (080930追記) anchor.png

pico-ver1.73以降では、ハック不要。 pico一般設定の「URIマッピング処理クラス名」にサンプルで同梱されている「PicoUriMapperBySubject」を設定すればOKです。)

「(trust)/modules/pico/class/PicoUriMapper.class.php」の79行目あたり。下記79~91行目を追記。

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
    } else if( @$_GET['cat_id'] !== '0' && ( $this->config['show_menuinmoduletop'] || @$_GET['page'] == 'menu' ) ) {
        $this->request['controller'] = 'menu' ;
        $this->request['view'] = 'menu' ;
    } else if( @$_GET['subject'] ) {
        $xoopsDB =& Database::getInstance() ;
        $content_table = $xoopsDB->prefix($this->mydirname."_contents");
        $sql = "SELECT content_id FROM ".$content_table." WHERE subject='".addslashes(@$_GET['subject'])."'"  ;
        $db_ret = $xoopsDB->query($sql);
            if( $xoopsDB->getRowsNum( $db_ret ) ) {
            list( $content_id ) = $xoopsDB->fetchRow($db_ret);
            $this->request['view'] = 'detail' ;
        } else {
            $this->request['controller'] = 'category' ;
            $this->request['view'] = 'list' ;
        }
    } else {
        $this->request['controller'] = 'category' ;
        $this->request['view'] = 'list' ;
    }

以上、変更したソースをサーバーに上書きします。

XCLの場合 anchor.png

XCLではモジュールアップデートで上書きされる危険性を避けるために、PreloadとDeligateを使うことができますので、これでやってみます。
 (thx GIJOEさん http://www.xugj.org/modules/QandA/index.php?post_id=6217

PicoSubjectRegexHook.class.php anchor.png

「(html)/preload」内に、「PicoSubjectRegxHook.class.php」として以下のソースを保存してアップするだけでOK!

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
<?php
 
if( ! defined( 'XOOPS_ROOT_PATH' ) ) exit ;
 
class PicoSubjectRegexHook extends XCube_ActionFilter
{
    function preBlockFilter()
    {
        $this->mRoot->mDelegateManager->add( 'ModuleClass.Pico.Contentman.InsertSuccess' , array( &$this , 'hook' ) ) ;
        $this->mRoot->mDelegateManager->add( 'ModuleClass.Pico.Contentman.UpdateSuccess' , array( &$this , 'hook' ) ) ;
    }
 
    function hook( $mydirname , $content_id , $cat_data , $ret_uri4html )
    {
    // xpwikiから picoへの自動リンクを貼るための、アドオン
    // 元ネタ:xpwikiから xwordsへの自動リンクを貼るための、アドオン
    // see http://xoops.hypweb.net/modules/forum/index.php?topic_id=2140 
    // 小文字・大文字を区別しない? (0 or 1)
    define('PAGE_CASE_INSENSITIVE', 0);
 
    global $xoopsDB;
 
    $temp_txt = XOOPS_ROOT_PATH."/uploads/".$mydirname."/entries_temp.php";
    $entries_dat = XOOPS_ROOT_PATH."/uploads/".$mydirname."/entries.php";
    $ent_table = $xoopsDB -> prefix ("{$mydirname}_contents") ;
 
    if ($fp1 = fopen($temp_txt, 'wb')) {
        $result_entries = $xoopsDB -> query( "SELECT subject FROM $ent_table" );
        while ( list( $entry_term ) = $xoopsDB -> fetchrow( $result_entries ) ) {
            if(mb_strlen($entry_term)>2) {fwrite($fp1, $entry_term."\n");
            }
        }
        fclose($fp1);
    }
 
    $dats = file($temp_txt);
    $dat = $this->get_matcher_regex_safe($dats);
    if ($fp2 = fopen($entries_dat, 'wb')) {
        fwrite($fp2, $dat);
        fclose($fp2);
    }
 
    }    //end of function
 
    function get_matcher_regex_safe ($pages, $spliter = "\t", $array_fix = true, $nest = 0) {
        if ($array_fix) {
            $pages = array_map('trim', $pages);
            if (PAGE_CASE_INSENSITIVE) $pages = array_map('strtolower', $pages);
            $pages = array_unique($pages);
            foreach(array_keys($pages, '') as $key) {
                unset($pages[$key]);
            }
            sort($pages, SORT_STRING);
        }
    
        ++$nest;
        $reg = $this->get_matcher_regex_safe_sub($pages);
        $regs = preg_split("/(\d+)\x08/", $reg, -1, PREG_SPLIT_DELIM_CAPTURE);
        $pats = array();
        $index = 0;
        reset($regs);
        while (list($key, $pat) = each($regs)) {
            list($key, $val) = each($regs);
            if (!$val) $val = count($pages);
            if (@ preg_match('/' . $pat. '/', '') === false) {
                if ($nest <= 10) {
                    $count = $val - $index;
                    $split = floor(($val - $index) / 2);
                    $pages1 = array_slice($pages, $index, $split);
                    $pages2 = array_slice($pages, $split, $count - $split);
                    $pats[] = $this->get_matcher_regex_safe($pages1, $spliter, false, $nest);
                    $pats[] = $this->get_matcher_regex_safe($pages2, $spliter, false, $nest);
                    $index = $val;
                }
            } else {
                $pats[] = $pat;
            }
        }
        return join($spliter, $pats);
    }    //end of function
 
    function get_matcher_regex_safe_sub (& $array, $offset = 0, $sentry = NULL, $pos = 0, $nest = 0)
    {
        static $g_count = 0;
        ++$nest;
        $limit = 1024 * 32 - 10;
        
        if (empty($array)) return '(?!)'; // Zero
        if ($sentry === NULL) $sentry = count($array);
        
        // Too short. Skip this
        $skip = ($pos >= mb_strlen($array[$offset]));
        if ($skip) ++$offset;
     
        // Generate regex for each value
        $regex = '';
        $index = $offset;
        $multi = FALSE;
        $reglen = 0;
        while ($index < $sentry) {
            if ($index != $offset) {
                $multi = TRUE;
                if ($nest === 1 && strlen($regex) - $reglen > $limit) {
                    $reglen = strlen($regex);
                    $regex .= ')'.($index)."\x08(?:";
                    $g_count = 1;
                } else {
                    $regex .= '|'; // OR
                }
            }
 
            // Get one character from left side of the value
            $char = mb_substr($array[$index], $pos, 1);
 
            // How many continuous keys have the same letter
            // at the same position?
        for ($i = $index; $i < $sentry; $i++)
                if (mb_substr($array[$i], $pos, 1) != $char) break;
 
            if ($index < ($i - 1)) {
                // Some more keys found
                // Recurse
                $regex .= str_replace(' ', '\\ ', preg_quote($char, '/')) .
                $this->get_matcher_regex_safe_sub($array, $index, $i, $pos + 1, $nest);
            } else {
                // Not found
                $regex .= str_replace(' ', '\\ ',
                preg_quote(mb_substr($array[$index], $pos), '/'));
            }
            $index = $i;
        }
    
        if ($skip || $multi){
            $g_count++;
            $regex = '(?:' . $regex . ')';
        }
        if ($skip) $regex .= '?'; // Match for $pages[$offset - 1]
            return $regex;
    }    //end of function
 
}    //end of class
 
?>
pico-1.72までの場合 anchor.png

この上のPicoUriMapper.class.php の編集修正も必要です。 1.73以上にアップすれば、pico一般設定の「URIマッピング処理クラス名」にサンプルで同梱されている「PicoUriMapperBySubject」を設定すればOKです。

ページ一覧ファイルの準備 anchor.png

X2,XCL共通

「(html)/uploads/(pico)/」ディレクトリを作成し、パーミッションを「707」「777」など書き込み権限を与えます。

そして、実際にコンテンツページ記事を作成して、「entry.php」の中身にページ名が正規表現で作成されているかを確認できればOKです。 これで準備は完了。 次はxpWiki側の設定です。

xpWikiで外部オートリンクを設定 anchor.png

「(html/modules/(xpwiki)/private/ini/pukiwiki.ini.php」に(無ければ作成)、以下を編集。(080930変更)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
require ( $root->mytrustdirpath."/ini/".basename(__FILE__) );
 
// : 中略
 
//// picoへのオートリンク
$root->ext_autolinks[] = array(
    'target'  => '' ,         // Target pages split with '&' (prefix search)
    'priority'=> 40 ,        // Priority (Intenal AutoLink = 50)
    'url'   => XOOPS_URL.'/uploads/pico/entries.php' ,  // 空白('')で自己xpWiki, 'ディレクトリ名' は自サイト内の別のxpWiki.
    'urldat'=> 1 ,              // urlはオートリンクデータそのもの(0:No, 1:Yes)
    'case_i'  => 1 ,        // Case insensitive
    'base'  => '' ,        // ベースページ名 (''[空白] ですべてのページ)
    'len'   => 6 ,                // オートリンクを有効にする文字数
    'enc'   => 'EUC-JP' ,        // 相手先の文字エンコーディング
    'cache' => 10 ,                //キャッシュする分数 (最小値: 10分)
    'title' => 'pico:[KEY]' ,    // <a>タグのtitle属性 ([KEY] は対象語句に置換されます)
    'pat'   => '/modules/pico/index.php?subject=[URL_ENCODE]' ,      // リンクパターン. ([URL_ENCODE], [WIKI_ENCODE], [EWORDS_ENCODE]が使用可能)
); 
 
// : 中略
 
?>

という具合です。
これで、xpWikiの記事を作成したとき、「(html)/cache/」ディレクトリ内に「_____.extautolink」というファイルができて、その中身がきちんと正規表現で入っていれば、OKです。

補足 anchor.png

 xpWiki内で外部オートリンクが成功すれば、そのxpWikiがインストールされたサイト内モジュールでxpWikiレンダラーモードを有効にすれば、サイトワイドでこの自動リンクが有効になります。 ちと重くなりますが、使い場所によっては大変便利な機能ですので、お試しください。

検索機能 anchor.png

 pico-extra_fieldsを使えば、テンプレートを駆使してデータベースの検索機能のようなものが作れます。
 参考:(XUGJマニュアル)ModuleManuals/pico/extra_fields

 実際に検索機能を付加したテンプレートを、参考までに下記に公開しておきます。
 なお、実装サイトはこちらになります。

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
<{php}>
    $brands = array('Alcone','Alpine','AltecLansing','Aura','Aurum','BontonAcoustic','Celestion','Coral','Daito','Dayton','Davis','Dinaudio','ElectroVoice','Eton',15=>'Focal',16=>'Fostex','Hi-Vi','Infinity','Infinity','JBL','KEF','Kenwood','Leed','MacAudio','Morel','Onkyo','ParcAudio','Peerless','Phillips','Pioneer','Scan-Speak','Seas','TangBand','Tannoy','Technics','Thiel','VIFA','Yamaha') ;
    $type = array('Corn','Flat','Horn','Dome','Ribbon','RingRadiator','HornDriver','その他');
    $size = array('その他','01','02','02.5','02.8','03','04','05','06','07','08','10','12','13','14','15','16','17','18','20','22','25','28','30','35','40','50','60','70','80');
    $imp = array('2','4','6','8','16','その他');
    $magnet = array('フェライト(外磁)','アルニコ(内磁)','リパルジョン(防磁)','ネオジウム','その他','不明');
    $this->assign( 'brands',$brands );
    $this->assign( 'type',$type );
    $this->assign( 'size',$size );
    $this->assign( 'imp',$imp );
    $this->assign( 'magnet',$magnet );
<{/php}>
 
<div class="pico_container" id="<{$mydirname}>_container">
 
<{include file="db:`$mydirname`_inc_breadcrumbs.html"}>
 
<!-- controllers -->
<div class="pico_controllers">
 
    <!-- link to menu -->
    <a href="<{$mod_url}>/index.php?page=menu">[<{$smarty.const._MD_PICO_MENU}>]</a>
    
    <{if $category.isadminormod}>
    <a href="<{$mod_url}>/index.php?page=categorymanager&amp;cat_id=<{$category.id}>">[<{$smarty.const._MD_PICO_LINK_EDITCATEGORY}>]</a>
    <{/if}>
    
    <{if $xoops_isadmin}>
        <a href="<{$mod_url}>/admin/index.php?page=category_access&amp;cat_id=<{$category.id}>">[<{$smarty.const._MD_PICO_LINK_CATEGORYPERMISSIONS}>]</a>
    <{/if}>
    
    <{if $xoops_isadmin}>
        <a href="<{$mod_url}>/admin/index.php?page=contents&amp;cat_id=<{$category.id}>">[<{$smarty.const._MD_PICO_LINK_BATCHCONTENTS}>]</a>
    <{/if}>
    
    <{if $category.can_makesubcategory}>
    <a href="<{$mod_url}>/index.php?page=makecategory&amp;pid=<{$category.id}>">[<{$smarty.const._MD_PICO_LINK_MAKESUBCATEGORY}>]</a>
    <{/if}>
    
    <{if $category.can_post}>
    <a href="<{$mod_url}>/index.php?page=makecontent&amp;cat_id=<{$category.id}>&amp;ret=mc<{$category.id}>">[<{$smarty.const._MD_PICO_LINK_MAKECONTENT}>]</a>
    <{/if}>
 
    <!-- link to RSS -->
    <a href="<{$mod_url}>/index.php?page=rss&amp;cat_id=<{$category.id}>">[RSS]</a>
    
</div>
 
<{if $category.id == 0}><p><{$mod_config.top_message}></p><{/if}>
 
<h1><{$category.title}></h1>
<{if $category.isadminormod}>
    <p>
    <{$smarty.const._MD_PICO_CONTENTS_TOTAL}>:<{$category.redundants.contents_total}>
    <{$smarty.const._MD_PICO_SUBCATEGORIES_TOTAL}>:<{$category.redundants.subcategories_total}>
    </p>
<{/if}>
 
<p><{$category.desc}></p>
 
<!-- list subcategories -->
<{if $subcategories}>
<h2><{$smarty.const._MD_PICO_SUBCATEGORIES}></h2>
<{foreach from=$subcategories item="subcategory"}>
    <dl class="pico_subcategory">
        <dt>
            <a href="<{$mod_url}>/<{$subcategory.link}>"><{$subcategory.title}></a>
            <{if $category.isadminormod}>
                <{$smarty.const._MD_PICO_CONTENTS_TOTAL}>:<{$subcategory.redundants.contents_total}>
                <{$smarty.const._MD_PICO_SUBCATEGORIES_TOTAL}>:<{$subcategory.redundants.subcategories_total}>
            <{/if}>
        </dt>
        <dd>
            <{$subcategory.desc}>
        </dd>
    </dl>
<{/foreach}>
<{/if}>
 
<!-- list contents -->
<{if $contents}>
<h2><{$smarty.const._MD_PICO_CONTENTS}></h2>
 
<{if $category.depth_in_tree==1}>
    <{foreach from=$contents item="content"}>
        <a href="<{$mod_url}>/<{$content.link}>">
        <{if $content.public}>
            <{$content.subject}>
        <{elseif $category.isadminormod}>
        <em class="pico_notice"><{$content.subject}></em>
            <{if ! $content.approval}>
            (<{$content.poster_uname}> <{$content.created_time_formatted}> )
            <{/if}>
        <{/if}>
        </a>
        <{if $category.can_edit}>
            <a href="<{$mod_url}>/index.php?page=contentmanager&amp;content_id=<{$content.id}>&amp;ret=mc<{$category.id}>"><img src="<{$mod_imageurl}>/icon_edit.gif" alt="<{$smarty.const._MD_PICO_LINK_EDITCONTENT}>" /></a>
        <{/if}>
    <{/foreach}>
<{else}>
 
<table>
<tr><th>ブランド</th><th>型式</th><th>公称口径(cm)</th><th>インピーダンス(Ω)</th><th>fo(Hz)</th><th>再生周波数帯域</th><th>音圧レベル(dB/W)</th><th>入力定格/music(W)</th><th>標準価格(税抜)</th>
    <{foreach from=$contents item="content"}>
    <{* unserialize *}>
    <{assign var="ef" value=$content.extra_fields|unserialize}>
    <{assign var="content_display" value=false}>
    <{if  $smarty.get.and_query==1}>
        <{if (! $smarty.get.brand && ! $smarty.get.size && ! $smarty.get.type && ! $smarty.get.imp && ! $smarty.get.magnet) || (!$smarty.get.brand || ($smarty.get.brand && $smarty.get.brand==$ef.brand|escape)) && (!$smarty.get.type || ($smarty.get.type && $smarty.get.type==$ef.type|escape)) && (!$smarty.get.size || ($smarty.get.size && $smarty.get.size==$ef.size|escape)) && (!$smarty.get.imp || ($smarty.get.imp && $smarty.get.imp==$ef.imp|escape)) && (!$smarty.get.magnet || ($smarty.get.magnet && $smarty.get.magnet==$ef.magnet|escape))}>        
            <{assign var="content_display" value=true}>
        <{/if}>
    <{else}>
        <{if (! $smarty.get.brand && ! $smarty.get.size && ! $smarty.get.type && ! $smarty.get.imp && ! $smarty.get.magnet) || ($smarty.get.brand && $smarty.get.brand==$ef.brand|escape) || ($smarty.get.type && $smarty.get.type==$ef.type|escape) || ($smarty.get.size && $smarty.get.size==$ef.size|escape) || ($smarty.get.imp && $smarty.get.imp==$ef.imp|escape) || ($smarty.get.magnet && $smarty.get.magnet==$ef.magnet|escape)}>        
            <{assign var="content_display" value=true}>
        <{/if}>        
    <{/if}>
 
    <{if ($content_display=="true")}>
        <tr><td><a href="<{$mod_url}>/<{$content.link}>">
        <{if $content.public}>
            <{$content.subject}>
        <{elseif $category.isadminormod}>
        <em class="pico_notice"><{$content.subject}></em>
            <{if ! $content.approval}>
            (<{$content.poster_uname}> <{$content.created_time_formatted}> )
            <{/if}>
        <{/if}>
        </a>
        <{if $category.can_edit}>
            <a href="<{$mod_url}>/index.php?page=contentmanager&amp;content_id=<{$content.id}>&amp;ret=mc<{$category.id}>"><img src="<{$mod_imageurl}>/icon_edit.gif" alt="<{$smarty.const._MD_PICO_LINK_EDITCONTENT}>" /></a>
        <{/if}>
    </td>
    <td> <a href="<{$mod_url}>/index.php?cat_id=<{$category.id}>&amp;brand=<{$ef.brand|escape}>"><{$ef.brand|escape}></a></td>
    <td><a href="<{$mod_url}>/index.php?cat_id=<{$category.id}>&amp;size=<{$ef.size|escape}>"><{$ef.size|escape}></a></td>
    <td><a href="<{$mod_url}>/index.php?cat_id=<{$category.id}>&amp;imp=<{$ef.imp|escape}>"><{$ef.imp|escape}></a></td>
    <td><{$ef.f0|escape}></td>
    <td><{$ef.range|escape}></td>
    <td><{$ef.spl|escape}></td>
    <td><{$ef.pwr|escape}></td>
    <td><{$ef.price|escape}></td>
    </tr>
    <{/if}>
    <{/foreach}>
</table>
<{/if}>
<{/if}>
<!-- end contents -->
 
<{if $category.id == 0}>
<h2>検索</h2>
<form name="or_query" action="./index.php" method="get" >
<ul>
    <li><{$smarty.const._MD_PICO_SUBCATEGORIES}>
        <select name="cat_id" id="cat_id">
        <{foreach from=$subcategories item="subcategory"}>
            <option value=<{$subcategory.id}>><{$subcategory.title}></option>
        <{/foreach}>
        </select>
        ※<font color="red">選択必須</font>
    </li>
    <p>絞込み方法 「and」検索を選択しなければ、「or」検索になります。<br />
    <input type="checkbox" name="and_query" id="and_query" value="1" checked="checked" /> <label for="and_query">「and」検索</label>
    </p>
 
    <p>以下、検索項目</p>
 
    <!-- brand-->
    <li>ブランド:<select id="brand" name="brand"><option value="" selected="selected">未選択</option>
            <{foreach from=$brands item=brand}>
                <option value="<{$brand}>"><{$brand}></option>
            <{/foreach}>
        </select>
    </li>
 
    <!-- type-->
    <li>タイプ:<select id="type" name="type"><option value="" selected="selected">未選択</option>
            <{foreach from=$type item=type}>
                <option value="<{$type}>"><{$type}></option>
            <{/foreach}>
        </select>
    </li>
 
    <!-- size-->
    <li>口径(cm):<select id="size" name="size"><option value="" selected="selected">未選択</option>
            <{foreach from=$size item=size}>
                <option value="<{$size}>"><{$size}></option>
            <{/foreach}>
    </select>
    </li>
 
    <!-- impedance-->
    <li>インピーダンス(Ω):<select id="imp" name="imp"><option value="" selected="selected">未選択</option>
            <{foreach from=$imp item=imp}>
                <option value="<{$imp}>"><{$imp}></option>
            <{/foreach}>
        </select>
    </li>
 
    <!-- magnet-->
    <li>磁気回路:<select id="magnet" name="magnet"><option value="" selected="selected">未選択</option>
            <{foreach from=$magnet item=magnet}>
                <option value="<{$magnet}>"><{$magnet}></option>
            <{/foreach}>
        </select>
    </li>
 
    <input type="submit" value="送信" />
</ul>
</form>
<{/if}>
<hr class="notification" />
<{include file='db:system_notification_select.html'}>
 
</div>
<!-- end module contents -->

実体ファイル:inc/pico_autolink

プリンタ用画面
投票数:42 平均点:7.38
前
AU携帯からX2サイトでプロフィール編集できない件のハック
カテゴリートップ
XOOPSサイト構築
次
inquirySPフォームに元記事ページ情報埋込み

コメント一覧

投稿ツリー


なーお  投稿日時 2009/2/14 11:01 | 最終変更

このサイトにも、導入してみました。  :-D

ただ、各記事のタイトルが長すぎて、あまり実用的ではないかも。
それに、仮想パスの画像やページリンクが切れちゃいますね。
ということで、以下のコードでのオーバーライドクラスで仮想パスへのリダイレクトのテスト。
「(trust)/modules/pico/class/PicoUriMapperBySubject2.class.php」

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php
 
// You can access pico contents via URI like ...
// XOOPS_URL/modules/pico/index.php?subject=(subject of the content)
 
class PicoUriMapperBySubject2 extends PicoUriMapper {
 
function judgeController( &$cat_id , &$content_id )
{
    parent::judgeController( $cat_id , $content_id ) ;
 
    if( ! empty( $_GET['subject'] ) ) {
        // get content_id from $_GET['subject']
        $db =& Database::getInstance() ;
        $sql = "SELECT content_id, vpath FROM ".$db->prefix($this->mydirname."_contents")." WHERE subject='".addslashes($_GET['subject'])."' LIMIT 1"  ;
        $content_row = $db->fetchArray( $db->query( $sql ) ) ;
        if( ! empty( $content_row ) ) {
            $this->request['controller'] = 'content' ;
            $this->request['view'] = 'detail' ;
            $content_id = $content_row['content_id'] ;
            $vpath = $content_row['vpath'] ;
            if( ! empty( $vpath ) ) {
                        redirect_header(XOOPS_URL.'/modules/'.$this->mydirname.'/index.php'.$vpath, 1, 'ページを表示しました');
            }
        }
    }
}
 
}
 
?>

以下、テスト。


更新履歴(旧版)
観光:プラハ

なーおの多趣味のはなし
趣味のはなし : マラソン
趣味のはなし : オーディオスピーカー自作
「スーパースワン」改 の頭部設計図の一部
3D-スパイラルスピーカー自作
MSDBS-1(Middle-Speed DB Spiral-1)
Twister
3D-subako
3D-elbow-r2
3D-ELBOWのF特測定
3D-Elbow測定グラフ in TakenakaさんRoom

趣味のはなし : ソフトテニス

自作PC、家庭内ネットワーク(現行:2008/12)
自作PC、家庭内ネットワーク(旧3:2006/12)
自作PC、家庭内ネットワーク(旧2:2004/01)
自作PC、家庭内ネットワーク(旧1:2000/12)

XUGJ_blockでMyブックマーク作成
習作:MT形式のd3blogインポート
習作:WordpressME(xoops版)のMT形式エクスポート
XC2.0のサイトで携帯対応(携帯対応レンダー)
AU携帯からX2サイトでプロフィール編集できない件のハック
picoタイトルのxpWikiへの外部Autoリンクに挑戦
inquirySPフォームに元記事ページ情報埋込み

minidiary d3コメント選択対応とd3commentクラス
Xwords d3コメント選択対応とd3commentクラス
piCal d3コメント選択対応とd3commentクラス
myalbum-P d3コメント選択対応とd3commentクラス

piCal for easy comment integration
myalbum-P for easy comment integration

なーお のクルマ遍歴
クルマのオフ会報告
ROOM GDI FUN -レグナムGDIの情報
(三菱)GDIエンジンの省燃費サイクル
(三菱)GDIエンジンの空燃比変化(予想)
└三菱への質問状の内容
└三菱からの回答
(三菱)GDIエンジンの省燃費性能を最大限に引き出すには?
└(三菱)GDIエンジンの空燃比変化予想(旧版)
(三菱)・4G93(GDI)レグナムの実際の燃費
GDIエンジン新旧特性比較
(三菱)レグナムST-GDI
Legnum時代のカーオーディオの話題
GDIレグナムのインプレッション
GDIレグナムのトラブル情報
└GDI高圧燃料ポンプリコールの全文

負圧計の見方
1:低負荷域:一定速度 =  超リーン 空燃比40?30
2:負荷域:緩加速 =  通常燃焼リーン 空燃比16?24
3:高負荷域:強加速 =  通常燃焼ストイキ 空燃比13?14.7

Libertyの部屋
Liberty-Inpression
Liberty-Driving
Liberty-Hyper-CVT
Liberty-CVT省燃費走法
Liberty-Ecology(燃費)
Liberty-CarAudio
Liberty-DIY-TUNE
Libertyにアンサーバックユニット取付け
Libertyオフ会報告

Liberty's Gallery Top
なーお家の肖像

トンネルの山姥

管理サイト
ブックマーク
なーお'n研究室
なーお'n研究室 Topページ左
なーお'n研究室 Topページ右
なーお'n研究室 Topページ左
なーお'n研究室 Topページ右

nonn50  投稿日時 2009/5/11 20:12

なにやら、興味津々な改造ですね。

サンプルとしているこちらのページと、このページの相違がいまいち理解できていないのですが、picoモジュールの利用方法として面白いです。
picoモジュールを利用してみたい誘惑があります。

小生、酒のデーターベース化をもくろんでいるのですが、利用できそうですね。

また、色々と教えてください。

なーお  投稿日時 2009/5/11 23:57 | 最終変更

nonn50さん

スピーカーサイトのデータベースは、xoops2なのでpico本体ハックをしていますが、こちらはデリゲートを使っていますので、モジュールアップデートの際にも安心です。 どちらも、ページタイトルにxpwikiオートリンクがかかるようにしている点では同じ機能です。

なお、このページの記述はpico1.7.3まで有効で、1.7.4以降はextra_fields周りの指定が変更になっていますので、このページのままでは出来ませんので要注意です。 (そんなわけで、私もなかなかpicoを1.8以上にアップデートする勇気が出ません) :-?

お酒のデータベースですか、それは楽しみですね。 そういう使い方にpicoのextra_fieldsはフレキシブルで良いと思います。 但し、テンプレートを自分で書き倒すことになりますんで、なかなか骨が折れます。(普通は携帯用テンプレートも別に作りますが、二度手間で大変なので、PCでも携帯でも破綻しない表示を意識して検索ページを作ります)。  また、検索機能もテンプレートでやることのなるので、簡単な検索機能はできますが、再絞込みや複雑な検索は苦手です。 :-D
実装の際には、多少フォローしますよ。



新しくコメントをつける

題名
ゲスト名
投稿本文
より詳細なコメント入力フォームへ