Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking us to recommend or find a tool, library or favorite off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it.
Closed 9 years ago.
Improve this question
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.
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.
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.
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)
If you are willing to spend some money then Adobe Dreamweaver has some pretty nice template functionality that works about like you describe.
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.
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.
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.
Related
TL;DR: vim seems to be sourcing both indent/javascript.vim and indent/html.vim on editing html files; is this intentional or a bug? How can I make html files only source html.vim?
Recently I found out that vim seems to be using indent filetype plugins for both javascript and html on editing html files, and I've done some testing based on this behaviour on minimal vim configurations.
Here is my one-line .vimrc:
filetype plugin indent on
Inside my .vim directory:
~ % tree .vim
.vim
└── indent
├── html.vim
└── javascript.vim
1 directory, 2 files
Where:
~ % cat .vim/indent/javascript.vim
setlocal formatprg=js-beautify
let g:testvar_js="js testvar"
let g:testvar="testvar defined in javascript.vim"
and
~ % cat .vim/indent/html.vim
setlocal formatprg=html-beautify
let g:testvar_html="html testvar"
let g:testvar="testvar defined in html.vim"
Then I open up a new, empty vim buffer with vim foo.html, and tested with some commands:
:set filetype?
filetype=html
:set formatprg?
formatprg=js-beautify
:echo g:testvar
testvar defined in javascript.vim
:echo g:testvar_html
html testvar
:echo g:testvar_js
js testvar
As if vim sources both indent filetype plugins, with indent/html.vim first and then indent/javascript.vim.
Therefore, my questions are:
Did I make any silly mistakes?
If no, then is this an intentional design, a bug, or is that vim has nothing to do with this at all?
Is there a way to make vim only source on html.vim when editing html files?
Some additional information that might be helpful:
I'm on vim 8.2, macOS arm64, using Terminal.app
Neovim exhibits the same behaviour; actually that's where I first note it
This behaviour does not occur for ftplugin/, only indent/
javascript files are not affected by indent/html.vim: variables defined in indent/html.vim are all undefined in a javascript buffer
formatprg of html files is always js-beautify on open, regardless of if there are any javascript code pieces or <script> tags inside that html file
An indent/css.vim will not be involved at all when editing html - I've tested
js-beautify and html-beautify are two separate executables (repository is here)
bin % ls -n js-beautify
lrwxr-xr-x 1 501 80 53 Apr 19 17:59 js-beautify -> ../lib/node_modules/js-beautify/js/bin/js-beautify.js
bin % ls -n html-beautify
lrwxr-xr-x 1 501 80 55 Apr 19 17:59 html-beautify -> ../lib/node_modules/js-beautify/js/bin/html-beautify.js
If you want me to do some additional tests or need more information, just shout.
Many thanks
Here is a perfectly valid HTML sample:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Sample</title>
<script>
console.log('Hello, World!');
</script>
<style>
body {
background: orange;
}
</style>
</head>
<body>
<h1>Sample</h1>
</body>
</html>
You will notice it has a tiny bit of embedded JavaScript in it, which is a good enough reason for $VIMRUNTIME/indent/html.vim to source $VIMRUNTIME/indent/javascript.vim. After all, the javascript indent script is supposed to know how to indent JavaScript, so why not use it in a html buffer that can contain embedded JavaScript?
FWIW, here is the snippet responsible for that behaviour:
if !exists('*GetJavascriptIndent')
runtime! indent/javascript.vim
endif
Note that the maintainers of $VIMRUNTIME/indent/html.vim chose the external route for javascript and the internal one for css. Maybe because $VIMRUNTIME/indent/css.vim didn't fit the bill? I don't know and, frankly, I don't think it matters.
Now, let's go through your mistakes…
Filetype-specific scripts (indent, syntax, ftplugins) are sourced in this order:
~/.vim/indent/<filetype>.vim,
$VIMRUNTIME/indent/<filetype>.vim
~/.vim/after/indent/<filetype>.vim
If you are not very careful, stuff you put in an earlier script might be overwritten when a later script is sourced. For that reason, it makes a lot more sense to put your own stuff in scripts under after/.
The following lines have nothing to do in indent scripts:
setlocal formatprg=js-beautify
setlocal formatprg=html-beautify
They are supposed to be in ftplugins:
" after/ftplugin/javascript.vim
setlocal formatprg=js-beautify
" after/ftplugin/html.vim
setlocal formatprg=html-beautify
So…
Did I make any silly mistakes?
Yes, see above.
If no, then is this an intentional design, a bug, or is that vim has nothing to do with this at all?
Well yes, this is an intentional design that works pretty well. It only caused problems because you misused it.
Is there a way to make vim only source on html.vim when editing html files?
indent/html.vim? Yes, it certainly is possible but why would you want to do that?
ftplugin/html.vim? It already works the way you want and it is the right place for the things you mistakenly put in indent/html.vim to begin with.
--- EDIT ---
Just curious, indent/ files are supposed to set indentation options right, then why shouldn't I set the indentation program there?
Filetype-specific scripts are typically sourced once, when a file of the corresponding filetype is loaded into a buffer. Because it is relatively common to have languages embedded in other languages (JavaScript in HTML) or languages that are supersets of other languages (C++ vs C), Vim makes it possible to source other filetype-specific scripts. That's pretty much a concrete example of code reuse and that's generally considered a good thing.
Indent scripts can source other indent scripts, syntax scripts can source other syntax scripts, and ftplugins can source other ftplugins.
So Vim gives us a useful low-level mechanism but it is up to us to decide what to put where, and that always depends on the context.
In the case of HTML, it makes sense to use the existing JavaScript indent stuff, so $VIMRUNTIME/indent/html.vim sources $VIMRUNTIME/indent/javascript.vim early on and then proceeds with setting HTML-specific stuff. The end result is a html indent script that also supports embedded JavaScript. The html syntax script uses a similar mechanism in order to highlight embedded JavaScript. In some simple cases, you can even have one ftplugin sourcing another ftplugin but $VIMRUNTIME/ftplugin/html.vim doesn't.
But it doesn't always makes sense: options may be overwritten, mappings may be overwritten or defined in contexts where they don't make sense, etc. In this specific case, what external tool to use for formatting is highly context-sensitive: you can't really expect js-beautify to format HTML properly or html-beautify to format JavaScript properly so formatprg must be set separately for the javascript and html filetypes.
ANd this is where your first mistake kicks in.
Here is once again the snippet that sources $VIMRUNTIME/indent/javascript.vim from $VIMRUNTIME/indent/html.vim:
if !exists('*GetJavascriptIndent')
runtime! indent/javascript.vim
endif
:help :runtime is a smart alternative to :help :source that looks for files in :help 'runtimepath'. Because your ~/.vim/indent/javascript.vim is in your runtimepath, it will be sourced. Because there is a !, every matching file is going to be sourced. Because it comes first in runtimepath, it might be overwritten by later scripts.
In your case, $VIMRUNTIME/indent/html.vim automatically sources your ~/.vim/indent/javascript.vim, which contains stuff that shouldn't be set in a html buffer.
The after directory allows you to have the last word on what is set for a given filetype because built-in scripts rarely, if ever, do runtime! after/indent/<filetype>.vim
That explains why it is a bad idea to carelessly put your filetype-specific stuff in ~/.vim/{ftplugin,indent,syntax}/ and why you should put it in ~/.vim/after/{ftplugin,indent,syntax}/ instead.
Does HTML support splitting source over multiple files? I'm looking for some equivalent of C++'s #include; or maybe something like C#'s partial; an element that could take source path and inject the file contents at that place.
Apologies if this has been asked before. Google and SO searches didn't return much. I'm not a web guy, but the only solution I found was using an iframe, which many people do not like for various reasons.
It is just that my html source is becoming huge and I want to manage it by splitting into multiple files.
You can't, at least not in flat-HTML. What you can do is using Javascript to load and place the snippets. iframes are also non-ideal because contrary to what happens with directives like #include and partial, those snippets will never be compiled in one single page.
However, I think it's important here to understand how your pages will be served. Is this a static website? Because in this case I would write a simple script in your language of choice to compile the page. Let's say that you have a base like this:
<html>
<head>
<!-- ... -->
</head>
<body>
{{ parts/navigation.html }}
<!-- ... -->
</body>
</html>
You could write a script that runs through this file line by line and loads the content into a variable named, for example, compiled_html. When it finds {{ file }} it opens file, reads its content and append it to compiled_html. When it gets to the end, it writes the content of the variable into a HTML file. How you would implement it depends on the languages you know. I'm sure that it's pretty straightforward to do it in C#.
This way you'll be able to split the source of your HTML pages into multiple files (and reuse some parts if you need them), but you'll still end up with fully functional single files.
It is easily possible, if you are running PHP:
The PHP Language has the "include" command built in.
Therefore you can have your "index.php" (note you have to change the suffix, for the PHP parser to kick-in) and simply use following syntax.
<html>
<head>
[...] (header content you want to set or use)
</head>
<body>
<?php
include "relative/path/to/your/firstfile.html";
include "relative/path/to/your/secondfile.html";
include "relative/path/to/your/evenwithothersuffix/thirdfile.php";
include "relative/path/to/your/fourth/file/in/another/folder.html";
?>
[...] (other source code you whish to use in the HTML body part)
</body>
</html>
Basically making you main index.php file a container-file and the included html files the components, which you like to maintain seperately.
For further reading I recommend the PHP Manual and the W3Schools Include Page.
not possible with static html.
in general, this problem (lazy-fetching of content) is solved with a template processor.
two options:
template processor runs on the server side
any language
static website generators, server side rendering
template processor runs on the client side
javascript
web frameworks
Okay, my english is not the greatest so I apologize in advance. Question is really stupid and I dont know how that is called but I will try to explain it here better. So I am making a template for one restourant and menus are changing every week. So is it possible to write paragraphs somewhere else ( in separated place (external or internal)) and then "call them" somewhere in .html.
Example. making methods in C# and then calling them anywhere when we want to
In my opinion the simplest method will be to use php.
Then in place with menu you can only use something like this:
<?php inlcude('menus/file.php');
And on server create a folder menus where you wil put php files with html.
All files can be simple html. There is no need to learn php just in place you want to call a file use code i placed earlier.
HTML doesn't have a good way to achieve this (although iframe exists).
This sort of thing is generally handled by software that generates the HTML, either when the page is requested (via something like the very basic SSI support in some webservers to full on server side programming (which you could use C# for)) or at publication time (via a build tool such as Gulp).
You could use jQuery to achieve it (if it is a simple website and simple menu), read more the related function on http://api.jquery.com/load/
You may also read a simple here: HTML File including another HTML file
I may also include a very basic example for you
main.html
<body>
<header>Some header</header>
<content>
<main class="the-menu"></main>
</content>
<script>
$(".the-menu").load("menu.html");
</script>
</body>
In Objective C to build a Mac OSX (Cocoa) application, I'm using the native Webkit widget to display local files with the file:// URL, pulling from this folder:
MyApp.app/Contents/Resources/lang/en/html
This is all well and good until I start to need a German version. That means I have to copy en/html as de/html, then have someone replace the wording in the HTML (and some in the Javascript (like with modal dialogs)) with German phrasing. That's quite a lot of work!
Okay, that might seem doable until this creates a headache where I have to constantly maintain multiple versions of the html folder for each of the languages I need to support.
Then the thought came to me...
Why not just replace the phrasing with template tags like %CONTINUE%
and then, before the page is rendered, intercept it and swap it out
with strings pulled from a language plist file?
Through some API with this widget, is it possible to intercept HTML before it is rendered and replace text?
If it is possible, would it be noticeably slow such that it wouldn't be worth it?
Or, do you recommend I do a strategy where I build a generator that I keep on my workstation which builds each of the HTML folders for me from a main template, and then I deploy those already completed with my setup application once I determine the user's language from the setup application?
Through a lot of experimentation, I found an ugly way to do templating. Like I said, it's not desirable and has some side effects:
You'll see a flash on the first window load. On first load of the application window that has the WebKit widget, you'll want to hide the window until the second time the page content is displayed. I guess you'll have to use a property for that.
When you navigate, each page loads twice. It's almost not noticeable, but not good enough for good development.
I found an odd quirk with Bootstrap CSS where it made my table grid rows very large and didn't apply CSS properly for some strange reason. I might be able to tweak the CSS to fix that.
Unfortunately, I found no other event I could intercept on this except didFinishLoadForFrame. However, by then, the page has already downloaded and rendered at least once for a microsecond. It would be great to intercept some event before then, where I have the full HTML, and do the swap there before display. I didn't find such an event. However, if someone finds such an event -- that would probably make this a great templating solution.
- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
{
DOMHTMLElement * htmlNode =
(DOMHTMLElement *) [[[frame DOMDocument] getElementsByTagName: #"html"] item: 0];
NSString *s = [htmlNode outerHTML];
if ([s containsString:#"<!-- processed -->"]) {
return;
}
NSURL *oBaseURL = [[[frame dataSource] request] URL];
s = [s stringByReplacingOccurrencesOfString:#"%EXAMPLE%" withString:#"ZZZ"];
s = [s stringByReplacingOccurrencesOfString:#"</head>" withString:#"<!-- processed -->\n</head>"];
[frame loadHTMLString:s baseURL:oBaseURL];
}
The above will look at HTML that contains %EXAMPLE% and replace it with ZZZ.
In the end, I realized that this is inefficient because of page flash, and, on long bits of text that need a lot of replacing, may have some quite noticeable delay. The better way is to create a compile time generator. This would be to make one HTML folder with %PARAMETERIZED_TAGS% inside instead of English text. Then, create a "Run Script" in your "Build Phase" that runs some program/script you create in whatever language you want that generates each HTML folder from all the available lang-XX.plist files you have in a directory, where XX is a language code like 'en', 'de', etc. It reads the HTML file, finds the parameterized tag match in the lang-XX.plist file, and replaces that text with the text for that language. That way, after compilation, you have several HTML folders for each language, already using your translated strings. This is efficient because then it allows you to have one single HTML folder where you handle your code, and don't have to do the extremely tedious process of creating each HTML folder in each language, nor have to maintain that mess. The compile time generator would do that for you. However -- you'll have to build that compile time generator.
Is there a way to split a single HTML page (purely static, HTML + JS) in VS2010 (I use VS2010 + ReSharper for my HTML /Js coding) into parts, but get / build a single page at build time.
There was such a feature with Dreamweaver (I have used this years back, think it called libraries). If I was using PHP I'd use something like Include at runtime.
My page contains several div sections serving as tabs, only one visible at time. I want to place the code between these tabs in a single file, to make it easier to maintain. But in the end I do need one single, static HTML file. Again, I want to do this a build time, not at server side.
<DIV>
many lines of HTML
</DIV>
should be replaced by something like
<DIV>
#include tab1.html
</DIV>
I could write a script building the static page and hook it into VS2010, but is there some extension or function already existing?
-- Follow ups on using T4 ---
VS2010 - Assign html code formatting to T4 (.tt) file
VS2010 - disable validation for particular html file (not all files)
I ran across this question while searching for something else. You've probably moved on, but what the heck, maybe the answer will help someone else:
You could get so-called T4 templates to do this:
http://msdn.microsoft.com/en-us/library/bb126445.aspx
Alternately, Microsoft has similar capabilities in Razor, and it's more specific to HTML.
Here is a comparison of the two:
http://blogs.msdn.com/b/garethj/archive/2011/03/11/t4-vs-razor-what-s-the-skinny.aspx