File: templatefs.pike

package info (click to toggle)
libroxen-templatefs 1.12-2
  • links: PTS
  • area: main
  • in suites: lenny, sarge
  • size: 40 kB
  • sloc: makefile: 39
file content (314 lines) | stat: -rw-r--r-- 10,723 bytes parent folder | download
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
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
// This is a roxen module. (c) Martin Baehr 1999

// templatefs.pike 
// template adding filesystem
// based on code from per hedbor

//  This code is (c) 1999 Martin Baehr, and can be used, modified and
//  redistributed freely under the terms of the GNU General Public License,
//  version 2.
//  This code comes on a AS-IS basis, with NO WARRANTY OF ANY KIND, either
//  implicit or explicit. Use at your own risk.
//  You can modify this code as you wish, but in this case please
//  - state that you changed the code in the modified version
//  - do not remove my name from it
//  - send me a copy of the modified version or a patch, so that
//    I can include it in the 'official' release.
//  If you find this code useful, please e-mail me. It would definitely
//  boost my ego :)
//  
//  For risks and side-effects please read the code or ask your local 
//  unix or roxen-guru.

#include <module.h>
#include <stdio.h>
inherit "roxenlib";
inherit "modules/filesystems/filesystem";
inherit "templatefs-utils";

constant my_cvs_version="$Id: templatefs.pike,v 1.12mark 2001/07/13 04:29:51 mbaehr Exp $";

constant cvs_version = (my_cvs_version-"Exp $")+"<br>"
             +(((::cvs_version*"<br>") -" Exp $")-"$Id: ");

void create()
{
  unload_program("templatefs-utils");
  unload_program("modules/filesystems/filesystem");

  ::create();

  defvar("dirtmpl", ".template-dir", "directory template",
             TYPE_STRING, 
	     "Template for the directory it resides in. "
	     "If it is missing the directory template from the parent dir "
	     "will be applied."
	     );

// there still some issues to be resolved, essentially in one directory
// it should be possible to set a template for the current directory
// and one for all subdirs 

  defvar("filetmpl", ".template-file", "file template",
             TYPE_STRING, 
	     "Template for each file in the current directory"
	     "If it is missing the file template from the parent dir "
	     "will be applied."
	     );
}

static private string doc()
{
  return "currently two types of templates are supported:<br>\n"
         "<dl>"
         "\n<dt><b>file templates</b>"
         "<dd>the file template is applied to files in the current directory "
         "\n<dt><b>directory templates</b>"
         "<dd>these are applied after the file template has been applied, "
         "first the directory template residing in the same directory with "
         "the file, then successively each directory template up the path "
         "until the base directory of the filesystem is reached."
         "\n<dt>the following types are planned:"
         "\n<dt><b>recursive or default file templates</b>"
         "<dd>if there is no file template in the current directory, "
         "the path is searched upward until a default template is found."
         "\n<dt><b>recursive or default directory templates</b>"
         "<dd>like the default file template, if a directory template is "
         "missing the path will be searched upwards until a default "
         "directory template is found, and since directory templates are "
         "applied for each directory in the path, the same will happen here, "
         "thus eventually the same template may be applied multiple times."
         "</dl>\n"
         "in templates you may use the following tags and containers:"
         "<dl>"
         "\n<dt><b><tt>&lt;tmplinsertall&gt;</tt></b>"
         "<dd>will simply insert the whole contents"
         "\n<dt><b><tt>&lt;tmplinserblock&gt;</tt></b>"
         "<dd>will insert the contents of the container which is "
         "named in the argument <tt>container</tt>:"
         "\n<dt><b><tt>&lt;tmploutput&gt;&lt;/tmploutput&gt;</tt></b>"
         "<dd>will allow to insert all kinds of variables"
         "  <dl>"
         "  \n<dt><b>#file#</b>"
         "  <dd>the name of the directory (or file), the template is being "
         "  applied to"
         "  \n<dt><b>#path#</b>"
         "  <dd>the path to the directory (or file), the template is being "
         "  applied to"
         "  \n<dt><b>#base#</b>"
         "  <dd>the basename (the part of the filename before the first '.'"
         "  of the directory (or file), the template is being applied to"
         "  \n<dt><b>#targetfile#</b>"
         "  <dd>the name of the target file, (the one to which the "
         "  file template is being applied to)"
         "  \n<dt><b>#targetpath#</b>"
         "  <dd>the path to the target file."
         "  \n<dt><b>#targetdir#</b>"
         "  <dd>the name of the directory the targetfile resides in."
         "  \n<dt><b>#target#</b>"
         "  <dd>if the targetfile is an indexfile this is equal to the "
	 "  targetdir, otherwise it is equal to the targetfile."
         "</dl>";
}

array register_module()
{
  return ({
    MODULE_LOCATION|MODULE_PARSER,
    "template filesystem",
    "Indeed. Template adding filesystem with image viewing extras "
    "(per hedbor)<p>\n"+doc(),
  });
}

int notemplate( string fn, object id )
{
  return (!!id->prestate->notmpl ||
          !!id->conf->stat_file( query_location() + 
                                 dirname( fn+"foo" ) + 
                                 "/.notmpl", id ));
}

string apply_template(string newfile, string f, string template, object id)
{
  string file;

  werror("templatefs: loop: %s ...", template);
  if(id->conf->real_file(template, id))
  {
    file = read_file( id->conf->real_file(template, id));
    werror(" found\n");
    file = parse_html(file, ([]), ([ "tmploutput":icontainer_tmploutput ]), id, f);
    
    newfile = parse_html(file, ([ "tmplinsertall":itag_tmplinsertall, "tmplinsertblock":itag_tmplinsertblock]), ([]), id, newfile);
  }
  else
    werror(" not found\n");

  return newfile;
}

string apply_all_templates( string f, string file, object id )
{
  array cd = ("/"+f) / "/";
  
  werror("templatefs: %s, %O\n", f, cd);

  //for(i=0; i<sizeof(cd)-1; i++)
  int i = sizeof(cd)-1;

  // first apply the file template

  string template=query_location()+cd[..i-1]*"/" + "/" + query("filetmpl");
  file = apply_template(file, "/"+f, template, id);

  // and then step down the directory path and i
  // apply the directory template found in each dir.
  while( i-- )
  {
    werror("templatefs: outloop: %s ...", 
           query_location()+cd[..i]*"/" + "/" + query("dirtmpl"));

    template=query_location()+cd[..i]*"/" + "/" + query("dirtmpl");
    file = apply_template(file, query_location()+cd[..i+1]*"/", template, id);
  }  
  return file;
}

string template_for( string f, object id )
{
  string current_dir = query_location()+dirname(f+"foo")+"/";
  werror("templatefs: %s, %s\n", f, current_dir);
  array cd = current_dir / "/";
  int i = sizeof(cd);
  while( i-- )
  {
    werror("templatefs: "+cd[..i]*"/"+"/template ...");
    if( id->conf->stat_file( cd[..i]*"/"+"/template", id ) )
    {
      werror(" found\n");
      return cd[..i]*"/"+"/template";
    }
    else
      werror(" not found\n");
  }
}

mixed find_file( string f, object id )
{
  string template, vtemplate;

  mapping defines = id->misc->defines || ([]);
  id->misc->defines = defines;

  mixed retval = ::find_file( f, id );
  if( intp( retval ) || mappingp( retval ) )
    return retval;

  //if(!(template=id->conf->real_file(vtemplate = fix_relative(template_for(f,id),id),id)))
  //  return retval;
  
  if( id->variables["content-type"] )
    return http_file_answer( retval, id->variables["content-type"] );

  
  if( id->variables->show_img )
  {
    id->variables->image = id->not_query;
    m_delete( id->variables, "show_img" );
    return http_string_answer( parse_rxml( ::find_file( "/showimg", id )->read(), id ) );
  } 
  else 
  {
    if( notemplate( f, id ) )
      return retval;
    // add template to all rxml/html pages...
    string type = id->conf->type_from_filename( id->not_query );
    switch( type )
    {
     case "text/html":
     case "text/rxml":
     {
       string contents;
       string file=retval->read();

       //werror("templatefs: %s", apply_all_templates(f, file, id));
       contents = apply_all_templates(f, file, id);
       //werror("templatefs: %s", contents);
       
       //contents = parse_html(contents, ([ "tmplinsertall":itag_tmplinsertall ]), ([]), id, file);

       //contents = parse_rxml(contents, id);
       //werror("templatefs: %O\n%O\n", id->misc, id->misc->defines);
       return http_rxml_answer(contents, id);

       //ok, here we basicly take over the function of the parser module,
       //not good, better use this:
       //object fd=Stdio.File();
       //object pipe = fd->pipe();
       //fd->write(contents);
       //return http_file_answer( pipe, type );
     }
//       return http_string_answer( parse_rxml("<use file="+template_for(f,id)+">"
//                                             "<tmpl-head title=\""+f+"\">"+
//                                             retval->read()+"<tmpl-foot>", id) );
    }
  }
  return retval;
} 

string icontainer_tmploutput(string container, mapping arguments, string contents, object id, string path)
{
  string file, dirname;
  string target, targetfile, targetpath, targetdirname;
  
  array thepath=path/"/";
  array thetarget=id->not_query/"/";

  file = thepath[-1];
  dirname = simplify_path((thepath[..sizeof(thepath)-2])*"/");

  array indexfiles = id->conf->dir_module->query("indexfiles");

  targetfile = thetarget[-1];
  targetdirname = thetarget[sizeof(thetarget)-2];

  if(search(indexfiles, thetarget[-1])==-1)
    target = targetfile;
  else
    target = targetdirname;
  
  targetpath = simplify_path((thetarget[..sizeof(thetarget)-2])*"/");

  werror("templatefs: tmploutput: %s, %s, %s, %s, %s, %s, %s, %s\n", dirname, file, (file/".")[0], targetfile, targetpath, targetdirname, target, id->not_query );
  return replace(contents, 
        ({ "#file#", "#path#", "#base#", "#targetfile#", "#targetpath#", "#targetdir#", "#target#" }), 
	({ file, dirname, (file/".")[0], targetfile, targetpath, targetdirname, target }));
}

string itag_tmplinsertblock(string tag, mapping arguments, object id, string filecontents)
{
  return parse_html(filecontents, ([]), ([ arguments->container:
       lambda(string tag, mapping arguments, string contents)
       { return contents; }
       ]));
}

string itag_tmplinsertall(string tag, mapping arguments, object id, string filecontents)
{
  return filecontents;
}

string tag_templatefs(string name, 
                     mapping arguments, 
	             object id)
{
  if(arguments->help)
    return("<obox><title>the template filesystem</title>"+doc()+"</obox>");

}

mapping query_tag_callers()
{
  return ([ "templatefs":tag_templatefs ]);
}