is so that your cascading stylsheet can format it better. I don't actually have any explicit formats using the
class, but I'm not done yet.
===== inc/pageutils.php =====
I added a value %%conf["formdir"]%% where I store my forms path, and then implemented a function modelled after %%wikiFN()%% in the same file.
function formFN($id,$rev=''){
global $conf;
if(empty($rev)){
$id = cleanID($id);
$id = str_replace(':','/',$id);
$fn = $conf['formdir'].'/'.utf8_encodeFN($id).'.php';
}
return $fn;
}
Changed some code in resolve_pageid which, essentially, checks both the pages and forms directory to determine if a file exists and returns TRUE if either exists. Maintains the "check singular and plurals" logic.
...
// Does the file exist as a page or a form?
// checks for forms are new -- edh
if(!@file_exists($file) && !@file_exists(formFN($page))) {
//check alternative plural/nonplural form
if( $conf['autoplural'] ){
if(substr($page,-1) == 's'){
$try = substr($page,0,-1);
}else{
$try = $page.'s';
}
if(@file_exists(wikiFN($try)) && !@file_exists(formFN($try))){
$page = $try;
$exists = true;
}
}
}else{
$exists = true;
}
...
===== inc/search.php =====
A new function, scan_dir(), gets a lot of the body from the function search():
function scan_dir(&$dirs, &$files, $base, $dir) {
//read in directories and files
$dh = @opendir($base.'/'.$dir);
if(!$dh) return;
while(($file = readdir($dh)) !== false){
if(preg_match('/^[\._]/',$file)) continue; //skip hidden files and upper dirs
if(is_dir($base.'/'.$dir.'/'.$file)){
$dirs[] = $dir.'/'.$file;
continue;
}elseif(substr($file,-5) == '.lock'){
//skip lockfiles
continue;
}
$files[] = $dir.'/'.$file;
}
closedir($dh);
}
And the search function has numerous changes to allow parallel searches:
/**
* recurse direcory
*
* This function recurses into a given base directory
* and calls the supplied function for each file and directory
*
* @author Andreas Gohr
*/
function search(&$data,$base,$func,$opts,$dir='',$lvl=1){
global $conf; // new forms edh
echo "\n";
$page_dirs = array();
$page_files = array();
scan_dir(&$page_dirs, &$page_files, $base, $dir);
sort($page_files);
sort($page_dirs);
// ========================================================== new forms edh
$form_dirs = array();
$form_files = array();
$mask = "%^". $conf['datadir'] ."(.*)$%";
//echo "\n";
if(preg_match($mask, $base)) {
$form_base = preg_replace($mask, $conf['formdir'] .'\1', $base);
//echo "\t\n";
scan_dir(&$form_dirs, &$form_files, $form_base, $dir);
sort($form_files);
sort($form_dirs);
}
// ========================================================== new forms edh
//give directories to userfunction then recurse
foreach($page_dirs as $dir){
if ($func($data,$base,$dir,'d',$lvl,$opts)){
search($data,$base,$func,$opts,$dir,$lvl+1);
}
}
// ========================================================== new forms edh
//give directories to userfunction then recurse
foreach($form_dirs as $dir){
if ($func($data,$base,$dir,'d',$lvl,$opts)){
search($data,$base,$func,$opts,$dir,$lvl+1);
}
}
//now handle the files
foreach($page_files as $file){
$func($data,$base,$file,'f',$lvl,$opts);
}
// ========================================================== new forms edh
foreach($form_files as $file){
$func($data,$base,$file,'f',$lvl,$opts);
}
}
search_index() has several changes; first to make the PHP files in ./forms equivalent to TXT files in ./pages and to avoid duplicates in the result array.
...
if($type == 'd' && !preg_match('#^'.$file.'(/|$)#','/'.$opts['ns'])){
//add but don't recurse
$return = false;
}elseif($type == 'f' && !preg_match('#\.txt$#',$file)
&& !preg_match('#\.php$#',$file)){ // forms edh
//don't add
return false;
}
...
// forms edh
// try to avoid duplicate entries for forms and pages
foreach($data as $item) {
if( ($item['id'] == $id)
&& ($item['type'] == $type)
&& ($item['level'] == $lvl)) {
// This item already has a member in the array
return $return;
}
}
$data[]=array( 'id' => $id,
'type' => $type,
'level' => $lvl,
'open' => $return );
return $return;
}
in search_pagename(), again make .php as valid as .txt:
if(!preg_match('#\.txt$#',$file)
|| preg_match('#\.php$#',$file) ) return true; // forms EDH
In search_list, again make .php as valid as .txt:
function search_list(&$data,$base,$file,$type,$lvl,$opts){
//we do nothing with directories
if($type == 'd') return false;
if(preg_match('#\.txt$#',$file)
|| preg_match('#\.php$#',$file)){ // forms EDH
//check ACL
$id = pathID($file);
if(auth_quickaclcheck($id) < AUTH_READ){
return false;
}
$data[]['id'] = $id;;
}
return false;
}
in pathID(), remove the txt and php extensions from files:
if(!$keeptxt) $id = preg_replace(
array('#\.txt$#', '#\.php$#'), // forms EDH
array('' , '' ), $id); // forms EDH
===== File System =====
Finally, I created a forms directory tree where each directory is a namespace, just as in the other DokuWiki data folders. By placing a file into these folders with the same name + .php, my forms code interprets it and injects the result imediately above the formatted text file result
===== TODO =====
One of the problems I've had is integrating the form pages with Wiki pages in indexing; the sidebar and indexing pages give me a list of files, but not of forms. I've played with a few ideas around the searching function but I get duplicate namespaces because, for example, [[:solving:wordlists:dictionary_search]] is a //page// namespace and a //form// namespace. The same problem is even worse for [[:solving:bases]] since none of the forms tend to have a page ... makes them hard to locate.
My changes to inc/search.php have improved the problem above immensely. I don't like how a page which is also a namespace is listed as a different item in the list... hard to make them out without explicitly looking.
I'd love to find a way to make some pages "invisible" or "default" like index.* pages are; if one is in a folder and you access that folder, you get that page, not an index of the folder. This also resolves my "page is a namespace" gripe, I think. If I could make a defaut page in a namespace (ie. _default.txt), then I could create :my:name:space:_default ... and when I have page parameters like ?id=&idx=my:name:space, I'd see my _default.txt file.
------
~~booknav>~~