tags:

views:

136

answers:

7

Hello! I am teaching my friend how to make websites. I would like to keep the websites static, so that he does not [yet] have to learn PHP, worry about testing on his Windows machine, worry about the server configuration, security etc. The bad thing is that without some tool support he would have to repeat a lot of code, for example the menu block on each page is almost the same. Is there a simple tool that would help him?

I’d like something that runs on Windows without too much work, ie. without Perl, Cygwin, IIS, PHP and such. (A simple GUI tool or a text editor with some special support for this would be nice.) I’d like something that does not require keeping separate “source” and “build” file versions, ie. the source files with some special markup and the build ones with regular HTML. (I hate to re-make the whole thing after each change in code.) I’d like something free and simple.

Is there such a thing?


Update: I was dreaming about something that would work like this:

$ cat page.html
<h1>A page</h1>
<!-- insert menu -->
<!-- menu ends -->
$ cat menu.tmpl
<ul id="#menu">…</ul>
$ update-templates page.html && cat page.html
<h1>A page</h1>
<!-- insert menu -->
<ul id="#menu">…</ul>
<!-- menu ends -->
$ echo "Moo" > menu.tmpl
$ update-templates page.html && cat page.html
<h1>A page</h1>
<!-- insert menu -->
Moo
<!-- menu ends -->

…only in GUI. BTW: Thanks for the JavaScript solutions. These did not occur to me, but the website has to work even with JS turned off.


Update: As I did not find any existing solution, I’ve written the script as a Google Code project. There are some quirks to be handled (like the different line endings on different systems), but the template substitution stuff works. The script requires Perl, but otherwise all you have to do is to double-click on an icon to get the HTML sources updated.

A: 

Is there something wrong with good old copy and paste to get the common elements from one page to another? Or better yet, make a simple text file that has all the common elements already arranged in it and then when he wants to make a new page, just copy that file and rename the copy.

EBGreen
If I could automate it without too much magic, I’d rather leave the boring work to the machine.
zoul
copy and rename is too much work?
EBGreen
Imagine You want to make a simple change in the menu and have to manually change 10 files. This gets old very quickly. It’s not a big deal, but if there was a simple way around it, I would use it.
zoul
Aah...I see the issue that you have. In that case I think you are probably SOL without includes.
EBGreen
+2  A: 

The easiest would probably be (although it requires a little bit of set up) a web server with server-side includes. It's the easiest form of templates that I can think of, and if you don't want to "build" the html files from some kind of source, then you need something which is actively serving requests.

I don't know if it's standardized, but Apaches SSI looks like this:

<!--#include file="menu.html" -->

Hope that helps.

EDIT:
I was convinced that not having separate source and target/build files it'd be impossible to achieve without an active server. However, as you commented about comment-markers a thought struck me, it shouldn't be to difficult to construct a simple perl-script that includes a file, replacing everything between a start-commment marker and an end-comment marker. You also said you don't want to mess with perl, did that include a prepared perl-script that he just needs to execute?

EDIT 2
A simple few-liner perl script using the /e-regexp modifier could be sufficient, since you're using windows I don't know if you can use backticks like cat $file, so I added a readfile sub.

sub readfile($) {
  open(FILE, 'r', shift);
  my $buffer;
  read (FILE, $buffer, 2 ** 20); # one megabyte maximum.
  close(FILE);
  return $buffer;
}
sub writefile($$) {
  open(FILE, 'w', shift);
  print FILE shift;
  close(FILE);
}

for my $file(@ARGV) {
  my $content = readfile($file);
  $content =~ s/\<!--\s+include\s+(\S+\)\s+--\>.*?\<!--\s+end\s+\1\s+--\>/"<!-- include $1 -->".readfile($1)."<!-- end $1 -->"/ge;
  writefile($file, $content);
}

Be wary though, that a crash or a bit greedy replacement (perhaps due to a typo) will kill the entire file, and this without maintaining a source file. I'm also unsure if LHS will match correctly with the backreference, I need to look into that.

roe
Poster says there's no server on the machine.
Diodeus
I hoped I could find a tool that uses a single file both as the source and the build target, maybe with some simple comment markers. SSIs won’t let him check the website on his machine (without installing webserver).
zoul
Yes, that’s probably how I am going to solve it if there is no other solution.
zoul
+1  A: 

It's a bit of a work-around.

You can use JavaScript includes, and include a local file. You'd have to insert the HTML via JavaScript into the right places in the document though. Learning how to do this may bot be a bad idea in itself. Escaping quotes in the include file may be a pain in the butt though.

File:

<p id='moo'></p>
<script type="text/javascript" src="moo.js"></script>

moo.js:

$('moo').innerHTML="hello world"

(I'm using Prototype shortcuts)

Diodeus
A: 

Hitchhiking on the apache suggestion: I think Windows has a "personal" IIS server that you can install. Put in just enough javascript to fetch the repeated block on each page and update the inner html on a pasted placeholder tag.

Probably want to give him a nice CSS file and include line to paste, as well.

A: 

install tomcat :-)

If that's palatable, use no java code, just give your friend the magic recipe to put the include call in the "magic" html files with the funny jsp suffixes???

OK, that's about the same as setting up PHP, isn't it.

If you want something to be generated, you're probably going to need some software to do it. I don't know what your "pain threshold" is.

+1  A: 

I've set up a similar thing in the past. I write just my content as a series of HTML files, without worrying about <html>, <head>, <body>, menus, etc - just the content. A PHP script reads all the files in that directory and performs some really simple templating (string substitution) to create the output files. I know you said that you wanted to avoid having source and build versions, but this method is actually really simple since the script finds all your source files automatically. Plus, you can just run the script from the command line (or as a batch file), so you don't need to muck about with setting up a server or anything: just download php and unpack it into a directory. Here's a really rough idea of what I mean:

Template file: page.tpl

<html>
<head> ... whatever ...</head>
<body>
    <div id="menu">
        Item 1
        Item 2
        (this could even be generated automatically from the files)
    </div>
    <div id="content">
        <!-- CONTENT -->
    </div>
</body>
</html>

Content page src/page1.txt:

<p>This is my page content.</p>

PHP Script pseudocode:

$template = get_contents(page.tpl)
for each of the .txt files in the src directory {
    $c = get_contents($file)
    write(string_replace("<!-- CONTENT -->", $c, $template)) into page1.html
}

Running the script:

$ php script.php

Of course, this would work with any language of your choosing.

nickf
+1  A: 

If you are willing to spend some money then Adobe Dreamweaver has some pretty nice template functionality that works about like you describe.

Zoredache