Gulp Haml Include HTML as a partial - gulp

I'm using gulp to render haml using gulp-haml-coffee
I want to do something like this:
header.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Website Title</title>
<link rel="stylesheet" href="style.css?v=1.0">
</head>
home.haml
INCLUDE header.html
.content
Regular Haml Content
INCLUDE footer.html
footer.html
</body>
</html>
The tricky part for me is that it is a mix of HTML and Haml and I want them to be combined into one file automatically using Gulp.
Here is the current Gulp task:
// HAML
gulp.task('haml', function() {
return gulp.src('app/source/**/*.haml')
.pipe(customPlumber('HAML Error'))
.pipe(sourcemaps.init())
.pipe(haml({trace:true}))
.pipe(sourcemaps.write())
.pipe(gulp.dest('./app/compiled'))
.pipe(browserSync.reload({
stream: true
}))
});
The haml conversion is working but I can't figure out how to include plain HTML files as part of the conversion.
I'm going to be creating several other haml files (about, contact, etc.)
This is what I would want the rendered HTML to be:
home.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Website Title</title>
<link rel="stylesheet" href="style.css?v=1.0">
</head>
<div class="content">
Regular Haml Content
</div>
</body>
</html>

With gulp-haml Impossible to compile Ruby code like:
= Haml::Engine.new(File.read('./includes/menu-main.haml')).render
because gulp-haml has no full Ruby engine functionality. If you want to use Ruby, download it and install, then install haml for it (but Ruby requests are very slow ~1-3s). Or, use some other templater, like gulp-file-include, so you can compile then include your compiled .HTML files (im using gulp-jhaml, it has same features with gulp-haml):
var haml = require('gulp-jhaml'),
gih = require('gulp-include-html'),
browserSync = require('browser-sync');
gulp.task('haml', function() {
return gulp.src(['source-folder/*.haml'])
.pipe(haml({}, {eval: false}))
.on('error', function(err) {
console.error(err.stack)
})
.pipe(gulp.dest('source-folder/html'));
});
gulp.task('html-include', ['haml'], function () {
gulp.src(['source-folder/html/*.html'])
.pipe(gih({
prefix: '##'
}))
.pipe(gulp.dest('result-folder'));
});
gulp.task('watch', ['html-include', 'browser-sync'], function() {
gulp.watch('source-folder/*.haml', ['html-include']);
gulp.watch('result-folder/*.html', browserSync.reload);
});
gulp.task('default', ['watch']);
You can also try gulp-pug with a native function include. Pug - was called 'Jade' before.

Related

How to link css file with ejs?

In my directory I have created a public folder in which I have put another folder named css in which is located styles.css. In another folder in my directory named views I have put my ejs file, with which I want to link styles.css like this:
<link rel="stylesheet" type="css/text" href="css/styles.css">
However this does not work.
I dont even get an error in my browsers console.
If you are using npm and Express, we need to set up a public folder for the static content (like your css file):
1) In your root folder, create a folder called 'public', then another one inside called 'css' and place your styles.ccs file in there.
2) In your JS application file (e.g. app.js), we need to have something like this:
//jshint esversion:6
const express = require('express');
const ejs = require("ejs");
const app = express();
app.set('view engine', 'ejs');
app.use(express.static("public"));
app.get('/', (req, res) => {
res.render('index', { foo: 'FOO' });
});
3) In your root folder, create a folder called 'views' and inside place the EJS file you want to render (e.g. index.ejs), stablishing the link like this: <link rel="stylesheet" href="/css/styles.css">:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="/css/styles.css">
<title>Document</title>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>
In this case, you should be able to see the css code applied in the home route "/", rendering the index.ejs file. I hope it help you!

ASP.NET Core - serve different HTML file for SPA?

Question
How can I serve different HTML (entry) files for an SPA application (Vue) in ASP.NET Core?
Explanation
Depending on a condition, I would like to serve a different HTML page (much like a controller would do for a non-SPA). The page would still include the entry point for Vue apps <div id="app">, but some other changes should be done before serving the HTML.
I know I somehow have to change the startup.cs file because that renders the HTML with app.UseStaticFiles() and app.UseSPAStaticFiles()
Example
Condition 1 is fulfilled, base.html is served from client -> public -> base.html
Condition 2 is fulfilled instead, special.html is served from client -> public -> special.html
Code
The basic HTML looks something like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>Title</title>
</head>
<body>
<noscript>
<strong>We're sorry but this webpage doesn't work properly without JavaScript enabled. Please enable it to
continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
The important parts of startup.cs looks like this:
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
// ....
app.UseStaticFiles();
app.UseSpaStaticFiles();
// ....
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
if (env.IsDevelopment())
{
endpoints.MapToVueCliProxy(
"{*path}",
new SpaOptions { SourcePath = "ClientApp" },
npmScript: "serve",
regex: "Compiled successfully");
}
// Add MapRazorPages if the app uses Razor Pages. Since Endpoint Routing includes support for many frameworks, adding Razor Pages is now opt -in.
endpoints.MapRazorPages();
});
// ....
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
});

Trouble with gulp and browser sync

I am currently working on a starter project for future use that uses gulp and browser-sync to auto load new changes in the browser. I have it working for scss to css and for auto reloading html changes. The issue is that when it auto reloads html changes scss changes are all removed. For example, if I set changed the background color and save, the changes show up. Then I go to index.html and make a change and that shows up as well but removes the changes from the styles.scss file.
I have tried doing this with tasks as well as with functions. Neither has worked.
EDIT: I have gotten it to work by putting the index.html file in the main (./) directory. But I shouldn't have to do that to get it to work. Not sure why it doesn't work with index in the src folder
var gulp = require('gulp');
var browserSync = require('browser-sync').create();
var sass = require('gulp-sass');
// Compile sass into CSS & auto-inject into browsers
function style(){
return gulp.src('./src/scss/**/*.scss')
.pipe(sass())
.pipe(gulp.dest('./src/css'))
.pipe(browserSync.stream());
}
function watch() {
browserSync.init({
server: {
baseDir: './src'
}
});
gulp.watch('./src/scss/**/*.scss', style);
gulp.watch('./src/*.html').on('change', browserSync.reload);
gulp.watch('./src/js/**/*.js').on('change', browserSync.reload);
}
exports.style = style;
exports.watch = watch;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="css/styles.css">
<title>Document</title>
</head>
<body>
<h1>Hello World!</h1>
<p>This is a basic starter file!</p>
</body>
</html>
There are no error messages when I run this. The only issue is that saving the .html file removes the styles.scss changes.

Web Component / HtmlElement : unit testing

I'm trying to test a web component.
Here is my project structure :
├── package.json
├── src
│   ├── app.js
│   └── index.html
└── test
└── hello-world-test.html
Here is my working code :
class HelloWorld extends HTMLElement {
connectedCallback () {
this.innerHTML = 'Hello, World!'
}
}
customElements.define('hello-world', HelloWorld);
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script src="app.js"></script>
</head>
<body>
<hello-world></hello-world>
</body>
</html>
I'm trying to test that web component with web-component-tester.
I installed the utility globally :
npm install -g web-component-tester
I declared it in the package.json file :
"devDependencies": {
"web-component-tester": "^6.9.0"
}
then, I wrote my test in the test folder and saved it to hello-world-test.html:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script src="../node_modules/web-component-tester/browser.js"></script>
<script src="app.js"></script>
</head>
<body>
<test-fixture id="hello-world-fixture">
<hello-world></hello-world>
</test-fixture>
<script>
suite('<hello-world>', function(){
let component = document.querySelector('hello-world');
test('contains hello world string ?', () => {
let index = component.innerText.indexOf('Hello');
assert.isAtLeast(index, 0);
});
});
</script>
</body>
</html>
Finally, I typed :
wct --npm
Then obtained the following error in Chrome :
What am I missing to run the test correctly ?
The only decent materials I've found are this one and that one but they are outdated.
There are many errors :
First, please read the whole documentation as in the last paragraph it's clear that for those who use npm you need an additional dependency through the wctPackageName :
Components which wish to support npm-based installation should include
wct-browser-legacy in their devDependencies, which is a package that
contains only the client-side javascript necessary for executing WCT
tests in an npm-based environment. WCT will attempt to identify which
package provides the client-side code by checking for compatible
packages in the following order of preference: wct-mocha,
wct-browser-legacy and web-component-tester. If you want to specify
which package provides WCT client-side code, use the
--wct-package-name flag or wctPackageName option in wct.conf.json with the npm package name.
So you will need to add wct-browser-legacy in your devDependencies
Giving your project structure, you are including the app.js as if it was at the same level. It should be ../src/app.js.
You should add the type="module" to that import
You declared a fixture but didn't take profit of it through the function fixture
If I had to correct your code :
The command should be wct --npm -wct-package-name=wct-browser-legacy. Or even better create a wct.conf.js file with the following information :
module.exports = {
npm:true,
verbose: true,
plugins: {
local: {
browsers: ["chrome"]
}
},
wctPackageName: "wct-browser-legacy"
};
Your test should be modified as following :
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script src="../node_modules/web-component-tester/browser.js"></script>
<script src="../src/app.js"></script>
</head>
<body>
<test-fixture id="helloWorldFixture">
<template>
<hello-world>
</hello-world>
</template>
</test-fixture>
<script>
suite('<hello-world>', () => {
let component;
setup(() => {
component = fixture('helloWorldFixture');
});
test('contains hello world string ?', () => {
let index = component.innerText.indexOf('Hello');
assert.isAtLeast(index, 0);
});
});
</script>
</body>
</html>
Please, notice that I used the fixture's id and put the component initialisation in the setup function.
Zakaria's answer is good, but I suggest ditching wct-browser-legacy in favor of wct-mocha as it is lighter-weight and doesn't have out-of-date dependencies like old version of lodash and sinon etc.
See the README for full details: https://www.npmjs.com/package/wct-mocha
tl;dr version:
$ npm rm --save wct-browser-legacy
$ npm install --save-dev \
#webcomponents/webcomponentsjs \
#polymer/test-fixture \
wct-mocha \
mocha \
chai
You shouldn't need to specify it, but if you have wct.conf.js file you should change an existing wctPackageName entry to:
wctPackageName: "wct-mocha"
Your HTML needs to change a little and you need to make sure mocha is a direct dependency, since wct-mocha will not autoload. You'd also need to do that with chai if you're using chai assertions and #polymer/test-fixture if you use those.
<head>
<meta charset="utf-8">
<script src="../node_modules/#webcomponents/webcomponentsjs/webcomponents-loader.js"></script>
<script src="../node_modules/mocha/mocha.js"></script>
<script src="../node_modules/chai/chai.js"></script>
<script src="../node_modules/#polymer/test-fixture/test-fixture.js"></script>
<script src="../node_modules/wct-mocha/wct-mocha.js"></script>
</head>

Gulp to version filename and replace links

For any URL which doesn't start with /static, I serve this index.html:
<!doctype html>
<html lang="en-GB">
<head>
<meta charset="utf-8">
<title>Title</title>
<link rel="import" href="/app.html">
</head>
...
</html>
Note: the / in /app.html to ensure it always serves app.html from the root.
I wish to run gulp/vulcanize over app.html to:
create a bundle which sits in: /static/<version-or-timestampp-or-hash-here>/app.html
change the import in index.html to point to the the above generated bundle
I currently have the following gulp file that will do the vulcanize, but it won't do the versioning or change index.html link:
var gulp = require('gulp');
var vulcanize = require('gulp-vulcanize');
gulp.task('vulcanize', function() {
return gulp.src(['app.html'])
.pipe(vulcanize({
stripComments: true,
inlineScripts: true,
inlineCss: true
}))
.pipe(gulp.dest('static'));
});
gulp.task('default', ['vulcanize']);
How do I achieve the two points above?