How can I use templates to generate static web pages? - html

I want to add one HTML file into another.
For example: I have header.html and footer.html
Now I am trying to create aboutus.html where I want to add these two HTML files
there is no dynamic code in these file except JavaScript.
How can I do this without using any scripting language except JavaScript and CSS?

Server Side Includes (SSI) exist for this particular functionality. However, you need to have the server configured for such includes. Apache supports it. Not sure about other web servers.

or Server Side Includes (SSI), all embedding is done there on the server side...

In the case of web sites with no dynamic content but have common elements, I generate the final pages on my development machine using Perl's Template Toolkit and upload the resulting static HTML files to the server. Works beautifully.
For example:
header.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1">
<title>[% title %]</title>
<link rel="stylesheet" href="/site.css" type="text/css">
<meta name="description" content="[% description %]">
<meta name="keywords" content="[% keywords.join(',') %]">
</head>
<body>
<div id="banner">
<p>Banner</p>
</div>
footer.html
<address>
Last update:
[%- USE date -%]
[%- date.format(date.now, '%Y-%m-%d %H:%M:%S') -%]
</address>
</body>
</html>
aboutus.html
[%- INCLUDE header.tt.html
title = 'About Us'
description = 'What we do, how we do it etc.'
keywords = 'rock, paper, scissors'
-%]
<h1>About us</h1>
<p>We are nice people.</p>
You can now use tpage or ttree to build your pages.

The only way to do this on the client side without javascript is to use frames or iframes. If you want to use javascript, you can use AJAX. Most javascript frameworks provide corresponding convenience methods (e.g. jQuery's load function).
Obviously there are many server side solutions, including the popular SSI extension for apache (see other posts).

I'm not entirely sure what it is you want but an entirely client side method of doing it would be to embed them with the <object> tag.
<html>
<head>
<title>About Us</title>
</head>
<body>
<object data="header.html"><!--Something to display if the object tag fails to work. Possibly an iFrame--></object>
<!--Content goes here...-->
<object data="footer.html"></object>
</body>
</html>
I do not think that this would work if either header.html or footer.html have javascript that accesses the parent document. Getting it to work the other way might be possible though.

Check out ppk's website (quirksmode.org), and go to the javascript archives,
(http://quirksmode.org/js/contents.html). He uses an ajax function he wrote called sendRequest (found at http://quirksmode.org/quirksmode.js). Since IE9+ plays nice with standards, I've simplified it some:
function sendRequest(url,callback,postData) {
var req = new XMLHttpRequest();
if (!req) return;
var method = (postData) ? "POST" : "GET";
req.open(method,url,true);
req.setRequestHeader('User-Agent','XMLHTTP/1.0');
if (postData)
req.setRequestHeader('Content-type','application/x-www-form-urlencoded');
req.onreadystatechange = function () {
if (req.readyState != 4) return;
if (req.status != 200 && req.status != 304) {
// alert('HTTP error ' + req.status);
return;
}
callback(req);
}
if (req.readyState == 4) return;
req.send(postData);
}
Then use the sendRequest function by wrapping the setFooter, setHeader functions and any other content functions around it.

why not use php or any other side scripting language?
doing this with javascript will not all users allow to watch your page.

Whilst this can be done with JS in a number of ways (AJAX, iframe insertion) it would be a very bad idea not to do this within the mark-up directly or (much) better on the server side.
A page reliant on JS for it's composition will not be fully rendered on a significant proportion of user's browsers, and equally importantly will not be correctly interpreted by google et al, if they like it at all.
You can do it, but please, please, don't.

Obviously header.html and footer.html are not html files -- with full fledged headers etc. If you have just html snippets and you want to include them so you can create different pages - like aboutus.html, terms.html, you have a couple of options:
Use a framework like Rails - which allows you to use layouts and partials. [** heavy **]
Write a simple tool that will generate all the files by concat-ing the appropriate files.
I assume you are doing this to avoid duplicating header and footer content.

Another way would be using ajax to include the remote html files.

Framesets would be the way to do this without any script or serverside influences.
<frameset rows="100,*,100">
<frame name="header" src="header.html" />
<frame name="content" src="content.html" />
<frame name="footer" src="footer.html" />
</frameset>
HTML5 framesets:http://www.w3schools.com/tags/html5_frameset.asp
This is a very dated solution, most web hosts will support server side includes or you could use php to include your files
http://php.net/manual/en/function.include.php
Cheers

Related

Google HTML Service - Evaluate Template and Keep Comments

I am using Google's HTML service to evaluate an HTML template and then sending the HTML it creates through Google's Mail App service as an e-mail. I have the following code to render the e-mail different for Microsoft Office clients:
<!--[if mso]><v:roundrect...v:roundrect><![end if]-->
<!--[if !mso]><td align='center'...</td><![endif]-->
My issue is that the HTML service evaluates the aforementioned code as commented out and the HTML that gets passed to the Mail App no longer has those lines of code in it.
I have been banging my head against the wall to figure out how to get Google's HTML service to not treat these as comments. Any thoughts?
Thanks!
There is a round-about way to retain HTML comments after template evaluation, but it comes with its owns issues.
You first enclose the comments in your template in CDATA tags. See example below:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<![CDATA[<!-- This is a comment -->]]>
<p>GET - Gmail Push Notification Endpoint</p>
</body>
</html>
When evaluated you'll end up with the following:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<!-- This is a comment -->
<p>GET - Gmail Push Notification Endpoint</p>
</body>
</html>
Notice that certain characters (the < and >) are encoded as html entities, so you need to convert these back somehow. Unfortunately, Javascript does not have a native way to do that, so you either have to write your own script to replace them or use an existing library. I do the later and leverage the he library. You can create a script file in your Apps Script project and drop that code in as a dependency or put it in it's own project and deploy it as a dedicated Apps Script library.
Now you can bring it all together as follows:
// create template
let template = HtmlService
.createTemplateFromFile('template_with_comments_wrapped_in_CDATA_tags');
// add properties to template for evaluation
template.props = {...};
// get evaluated content as string
let evaluated = template
.evaluate()
.getContent();
// decode html entities
let decoded = he.decode(evaluated);
// return decoded as HtmlOutput
return HtmlService.createHtmlOutput().setContent(decoded);
And there you go.
Enclosing content in a template with CDATA tags has a number of applications, it even allows you to use non-HTML content as templates, so you can use this technique to create templates for all sorts of content (JSON, RFC822, etc.). Its a good trick to have in your arsenal of tools.
The reason why that is happening is because those are HTML comments indeed.
Check this reference to learn about how to comment in HTML.
To solve your problem, simply comment out your lines of code (i.e remove <!-- and -->):
[if mso]><v:roundrect...v:roundrect><![end if]
[if !mso]><td align='center'...</td><![end if]

Razor CSS file location as Variable

I am wrapping a razor view in an iframe. The razor view is a web service on a different domain.
Here is what I am doing:
<!DOCTYPE html>
<html>
<body>
<p align="center">
<img src="http://somewhere.com/images/double2.jpg" />
</p>
<p align="center">
<iframe src="https://secure.somewhereelse.com/MyPortal?CorpID=12334D-4C12-450D-ACB1-7372B9D17C22" width="550" height="600" style="float:middle">
<p>Your browser does not support iframes.</p>
</iframe>
</p>
</body>
</html>
This is the header of the src site:
<!DOCTYPE html>
<html>
<head>
<title>#ViewBag.Title</title>
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/themes/cupertino/jquery-ui-1.8.21.custom.css")" rel="stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery-ui-1.8.11.min.js")" type="text/javascript"></script>
</head>
I want the iframe src to use the CSS of the calling site.
Is there a way to pass in the CSS URL or have it inherit the CSS of the calling site?
I'd even settle for the css file location being a parameter being passed in from the originating site.
Anyone have any suggestions?
You cannot enforce your css on your site using an iframe. The css must be included in the source of the page included in an iframe. It used to be possible but in certain cases using javascript, and for the page to be on the same domain.
The only other way you may be able to use your own css is if the web service allows you to pass in the url of the css. But you would have to consult the documentation of the web service to find that out.
I would pass the CSS url as an argument to the iframe's src attribute:
<iframe src="http://somedomain.com/?styleUrl=#(ResolveStyleUrl())"></iframe>
Where ResolveStyleUrl might be defined as:
#functions {
public IHtmlString ResolveStyleUrl()
{
string url = Url.Content("~/Content/site.css");
string host = "http" + (Request.IsSecureConnection ? "s" : "") + "//" + Request.Url.Host + url;
return Raw(url);
}
}
This is of course assuming that the domain would accept a style url query string and render the appropriate <link /> on the remote page?
Eroc, I am sorry you cannot enforce your css on others' site using an iframe because most browsers will give an error like the one chrome gives:
Unsafe JavaScript attempt to access frame with URL http://terenceford.com/catalog/index.php? from frame with URL http://www.example.com/example.php. Domains, protocols and ports must match.
But this does not mean that you cannot extract the html from that page (which may be modified as per your ease)
http://php.net/manual/en/book.curl.php can be used for site scrapping with http://simplehtmldom.sourceforge.net/
First play with these functions:
curl_init();
curl_setopt();
curl_exec();
curl_close();
and then parse the html.
After trying yourself, you can look at this example below that I made for parsing beemp3 content, when I wanted to create a rich tool for directly downloading songs, unfortunately I couldn't because of the captcha but it is useful for you
directory structure
C:\wamp\www\try
-- simple_html_dom.php
-- try.php
try.php:
<?php
/*integrate results for dif websites seperately*/
require_once('simple_html_dom.php');
$q='eminem';
$mp3sites=array('http://www.beemp3.com/');
$ch=curl_init("{$mp3sites[0]}index.php?q={$q}&st=all");
curl_setopt($ch,CURLOPT_HEADER,0);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
//curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
$result=curl_exec($ch);
curl_close($ch);
$html=str_get_html("{$result}");
$ret = $html->find("a");
echo "<head><style type='text/css'>a:link,a{font-size:16px;font-weight:bold;font-family:helvetica;text-decoration:none;color:#458;}a:hover{color:#67b;text-decoration:underline;}a:visited{color:silver;}</style></head>";
$unik=array(null);
foreach($ret as $link)
{
$find="/(.{1,})(\.php)[?](file=.{1,})&song=(.{1,})/i";
$replace="$4";
if(preg_match("{$find}",$link->href))
{
$unik[]=$link->href;
if(current($unik)===prev($unik)){unset($unik);}
else{
echo "<a href='".$mp3sites[0].$link->href."'>".urldecode(preg_replace($find,$replace,$mp3sites[0].$link->href))."</a><br/>";
}}
}
?>
I know that you do not code in php, but I think you are capable of translating the code. Look at this:
php to C# converter
I spent time on this question because only I can understand what it means to offer bounty.
May be the answer seems unrelated (because I have not used javascript or html based solution), but because of cross-domain issues this is an important lesson for you. I hope that you find similar libraries in c#. Best of luck
The only way I know to achieve that is to make the HTTP request on your server side, fetch the result and hand it back to the user.
A minima, you'll need either to strip completely the header from the targeted site to inject the content in your page using AJAX, or to inject your own css in the page headers to put it into an IFRAME.
Either way you have to implement the proxy method, which will take the targetted URL as an argument.
This technique has many downsides :
You have to do the queries on you server, which can cost a lot of bandwidth and CPU
You have to implement the proxy
You cannot transmit the domain specific cookies from the user, though you can manage new cookies have by rewriting them
If you do a lot of requests you server(s) is/are likely to become blacklisted on the targeted website(s)
The benefits sound low compared to the hassles.

How to include Perl into shtml files

Hi I am trying to include a perl script within my shtml file. Unfortunately when I do my script doesnt seem to run but instead it just displays the content of the script.
The code I am using is as follows:
test.shtml:
<html>
<title> business home page </title>
<body>
</br>
<!--#echo var="DATE_LOCAL" -->
<br />
<!--#include virtual="hello.pl"-->
</body>
</html>
hello.pl:
#!C:/Sun/WebServer6.1/bin/https/perl/perl
print "Content-type:text/html\n\n";
print "Hello World!";
I am not sure what I am doing wrong. Incase you all wanted to know the server I am using is Sun One WebServer 6.1 (OS = Windows XP). Thanks for your responses!
The de facto standard SSI directive for executing dynamic content within an SSI page is
<!--#exec cgi="hello.pl"-->
That works with Apache mod_include and at least a few other web servers that support SSI. No idea if it will work on your platform, but give it a shot.
Try getting rid of the first print statement in your Perl program, which sets the content-type header. That's not a useful thing to do in the body of an HTML page, which is where your SSI is located.
SSI is a rather quaint technology these days, even if it is occasionally useful, so if you are serious about learning web programming then this is not an area where you should spend much time.

Call one html file from another

I want to call one html page fron another in a div.
I tried using
<include file="NavigationTree.html" />
and
<? include("/starfix/pages/NavigationTree.html"); ?>
But it doesn't work.
Am I doing something wrong or do i need to do it some other way?
You may want to consider using Server Side Includes (SSI).
You would place your HTML snippet into a separate file, such as NavigationTree.html, and then you would simply reference it in your web pages by using:
<!--#include virtual="NavigationTree.html" -->
SSI is supported by all the popular web servers, including Apache, IIS and lighttpd.
Note that if you are using a shared host, you may have to use the .shtml, .stm, or .shtm extension for SSI to work. If you have root access to your web server, it can be easily configured to enable SSI for any extension, including html.
This is not possible in pure HTML.
The former is a notation I have never seen before, it is not HTML, maybe it works in some specific server-side templating language.
The latter is PHP. It should work but you need to bear in mind include() works with absolute paths inside the server's file system.
You should specify a relative path:
<? include("./NavigationTree.html"); // will work if it's in the same directory ?>
or an absolute one that will probably look something like this:
<? include("/path/to/your/www/dir/starfix/pages/NavigationTree.html"); ?>
(ask your admin for the absolute path to your web root)
You can maybe also do a HTTP include:
but that's unwise because it tends to be slow, and generates a second request on each page request.
You can also use SSI as outlined by #Daniel.
You could also use jQuery for this,
e.g.
<div id="yourDiv" />
<script>
$("#yourDiv").load("NameOfYourPageToReadFrom.ext #NameOfDivToReadFrom");
</script>
This puts the contents of the 'NameOfDivToReadFrom' DIV in the called file ''NameOfYourPageToReadFrom' into the loaded DIV ('yourDiv') in your current file.
Remember to add the definition to the header part of your html.
e.g.
<head>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
</head>
You can use an iframe for that, e.g.:
<iframe width="500" height="300" frameborder="no" scrolling="no" marginheight="0" marginwidth="0"
src="http://www.example.com/page.html"></iframe>

Common Header / Footer with static HTML

Is there a decent way with static HTML/XHTML to create common header/footer files to be displayed on each page of a site? I know you can obviously do this with PHP or server side directives, but is there any way of doing this with absolutely no dependencies on the server stitching everything together for you?
Edit: All very good answers and was what I expected. HTML is static, period. No real way to change that without something running server side or client side. I've found that Server Side Includes seem to be my best option as they are very simple and don't require scripting.
There are three ways to do what you want
Server Script
This includes something like php, asp, jsp.... But you said no to that
Server Side Includes
Your server is serving up the pages so why not take advantage of the built in server side includes? Each server has its own way to do this, take advantage of it.
Client Side Include
This solutions has you calling back to the server after page has already been loaded on the client.
JQuery load() function can use for including common header and footer. Code should be like
<script>
$("#header").load("header.html");
$("#footer").load("footer.html");
</script>
You can find demo here
Since HTML does not have an "include" directive, I can think only of three workarounds
Frames
Javascript
CSS
A little comment on each of the methods.
Frames can be either standard frames or iFrames. Either way, you will have to specify a fixed height for them, so this might not be the solution you are looking for.
Javascript is a pretty broad subject and there probably exist many ways how one might use it to achieve the desired effect. Off the top of my head however I can think of two ways:
Full-blown AJAX request, which requests the header/footer and then places them in the right place of the page;
<script type="text/javascript" src="header.js"> which has something like this in it: document.write('My header goes here');
Doing it via CSS would be really an abuse. CSS has the content property which allows you to insert some HTML content, although it's not really intended to be used like this. Also I'm not sure about browser support for this construct.
The simplest way to do that is using plain HTML.
You can use one of these ways:
<embed type="text/html" src="header.html">
or:
<object name="foo" type="text/html" data="header.html"></object>
You can do it with javascript, and I don't think it needs to be that fancy.
If you have a header.js file and a footer.js.
Then the contents of header.js could be something like
document.write("<div class='header'>header content</div> etc...")
Remember to escape any nested quote characters in the string you are writing.
You could then call that from your static templates with
<script type="text/javascript" src="header.js"></script>
and similarly for the footer.js.
Note: I am not recommending this solution - it's a hack and has a number of drawbacks (poor for SEO and usability just for starters) - but it does meet the requirements of the questioner.
you can do this easily using jquery. no need of php for such a simple task.
just include this once in your webpage.
$(function(){
$("[data-load]").each(function(){
$(this).load($(this).data("load"), function(){
});
});
})
now use data-load on any element to call its contents from external html file
you just have to add line to your html code where you want the content to be placed.
example
<nav data-load="sidepanel.html"></nav>
<nav data-load="footer.html"></nav>
The best solution is using a static site generator which has templating/includes support. I use Hammer for Mac, it is great. There's also Guard, a ruby gem that monitors file changes, compile sass, concatenate any files and probably does includes.
The most practical way is to use Server Side Include. It's very easy to implement and saves tons of work when you have more than a couple pages.
HTML frames, but it is not an ideal solution. You would essentially be accessing 3 separate HTML pages at once.
Your other option is to use AJAX I think.
You could use a task runner such as gulp or grunt.
There is an NPM gulp package that does file including on the fly and compiles the result into an output HTML file. You can even pass values through to your partials.
https://www.npmjs.com/package/gulp-file-include
<!DOCTYPE html>
<html>
<body>
##include('./header.html')
##include('./main.html')
</body>
</html>
an example of a gulp task:
var fileinclude = require('gulp-file-include'),
gulp = require('gulp');
gulp.task('html', function() {
return gulp.src(['./src/html/views/*.html'])
.pipe(fileInclude({
prefix: '##',
basepath: 'src/html'
}))
.pipe(gulp.dest('./build'));
});
You can try loading them via the client-side, like this:
<!DOCTYPE html>
<html>
<head>
<!-- ... -->
</head>
<body>
<div id="headerID"> <!-- your header --> </div>
<div id="pageID"> <!-- your header --> </div>
<div id="footerID"> <!-- your header --> </div>
<script>
$("#headerID").load("header.html");
$("#pageID").load("page.html");
$("#footerID").load("footer.html");
</script>
</body>
</html>
NOTE: the content will load from top to bottom and replace the content of the container you load it into.
No. Static HTML files don't change. You could potentially do this with some fancy Javascript AJAXy solution but that would be bad.
Short of using a local templating system like many hundreds now exist in every scripting language or even using your homebrewed one with sed or m4 and sending the result over to your server, no, you'd need at least SSI.
The only way to include another file with just static HTML is an iframe. I wouldn't consider it a very good solution for headers and footers. If your server doesn't support PHP or SSI for some bizarre reason, you could use PHP and preprocess it locally before upload. I would consider that a better solution than iframes.