How can i make the style sheet rendering in expressjs/ejs common? - node.js

I am using ejs in node for creating an app. And in my ejs, when I navigate from one page to another I have to render the header also to have the styles.
How can I make this common for all pages?
<title>Static Website </title>
<meta charset="utf-8">
<meta name="active-menu">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="./styles/abc.css">
<link rel="stylesheet" type="text/css" href="./styles/def.css"> ```
I don't want load styles on every routing. Render all the styles on first page itself

ejs will render the page every time you refresh the page, so you need to put every css you need. you can pass var that say if a css is needed ex: isDefNedded = true and make a if statement in your ejs header

Related

node express - milliseconds to load classes

I am working with node express. So far I didn´t use a template engine. I create my html file and send it via response.send(template); It works fine.
Now, I have more complex tags like a checkbox with several classes. Loading the route in the browser, it takes some milliseconds till the classes are loaded. Means, first I have a checkbox and it changes then to a button. I am talking about milliseconds, but is there a way to load the classes before actually showing the page?
Do template engines like handlebars or pug have such a feature?
Happy for some help to look in the right direction. Thank you!
If you use a template engine (ejs, pug, etc) you can then use the res.render(...) function. The res.render(...) function allows you to find data from the server side then send it over to the client along with the page.
Example:
const express = require('express');
const app = express();
app.use('view engine', 'ejs'); // Change ejs to your preferred view engine
app.get('/path/to/my/page', function(req, res) {
// Get data
res.render('example', { data: 'my-found-data' }); // Render the template 'example' with the data fetched
}
Additional documentation on using template engines can be found in official expresJS documentation here:
https://expressjs.com/en/guide/using-template-engines.html
What do you mean by classes here?
but is there a way to load the classes before actually showing the page?
CSS classes? if yes, you can provide link to load CSS in header of HTML document you use to load it
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Требуется авторизация</title>
<link rel="stylesheet" href="/assets/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
<link rel="icon" href="/favicon.ico" type="image/x-icon">
<meta name="description" content="">
<meta name="Keywords" content="">
<meta name="robots" content="noindex">
</head>
<body>
See
<link rel="stylesheet" href="/assets/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
It loads bootstrap.min.css from /assets/bootstrap.min.css, and since its in header of page, all css classes are loaded before browser starts rendering page, so it renders it properly.
See https://developer.mozilla.org/en-US/docs/Learn/Getting_started_with_the_web/CSS_basics for details on loading css

I can not match the width of my website with mobiles screen

I have a website which I used the meta name="viewport" content="width=device-width" in it . but the width of that is not match with the width of mobile devices (just mobiles ) . what should i do to match it with the mobiles screen ?
Try adding a style that sets the width dependent on the screen:
body {
width: auto;
}
If you're designing for only mobile devices the W3 site has good tutorials: W3.CSS
<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3pro.css">
<body>
<!-- Content here -->
</body>
</html>

Modifying a HTML file in NodeJS

Let me preface with two things. I am currently using grunt for these tasks and I also know about Yeoman which has what I am asking for. I do really like Yeoman however it is just a little too opinionated for this particular project I am working on.
So I have the following HTML file:
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<!-- START-CSS-MIN:css/build/min.css -->
<link rel="stylesheet" href="css/bootstrap/bootstrap-2.1.1.css">
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/boilerplate.css">
<!-- END-CSS-MIN -->
<!-- START-JS-MIN:js/build/modernizr.js -->
<script src="js/libraries/modernizr.js"></script>
<!-- END-JS-MIN -->
</head>
<body>
<!--[if lt IE 7]>
<p class="chromeframe">You are using an outdated browser. Upgrade your browser today or install Google Chrome Frame to better experience this site.</p>
<![endif]-->
<p>Hello world! This is a basline HTML5 template (based on HTML5 Boilerplate).</p>
<!-- START-JS-MIN:js/build/libraries.js -->
<script src="js/libraries/underscore.js"></script>
<script src="js/libraries/jquery/jquery.js"></script>
<!-- END-JS-MIN -->
</body>
</html>
Now you can see the CSS-MIN and JS-MIN comments. Right now I already have a custom grunt build task that properly collects all those files in the comments (using htmlparser) and then minifies and concats them as directly based on the comments. The last step in the build process is to create a new version of that HTML file (for production use) that replaces the comments with the new file. For example, the code above would be turned into this:
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="css/build/min.css">
<script src="js/build/modernizr.js"></script>
</head>
<body>
<!--[if lt IE 7]>
<p class="chromeframe">You are using an outdated browser. Upgrade your browser today or install Google Chrome Frame to better experience this site.</p>
<![endif]-->
<p>Hello world! This is a basline HTML5 template (based on HTML5 Boilerplate).</p>
<script src="js/build/libraries.js"></script>
</body>
</html>
The question I have is how would I be able to do this in NodeJS? The htmlparser NPM module is great for parsing HTML however I now need something where I am modifying the HTML (removing and adding certain elements in specific locations). Is there any good packages/tutorials on how to do this in NodeJS code?
I'm not quite sure if this is helpful for comment lines, but that should be less of an issue to solve than DOM reference.
Consider using: https://github.com/tmpvar/jsdom
There are other options out there as well. (https://github.com/joyent/node/wiki/modules)
You can use cheerio
The following code will produce exactly the output you provided (apart from some minor whitespace differrences)
const $ = require('cheerio').load(inputHtml);
// Returns a filter function that selects the comments with the provided indexes
const commentRemovalFilter = (commentIndexes)=>{
let commentIndex=-1;
return (index, node)=>{
const isComment = node.type === 'comment';
if(isComment)commentIndex++;
return isComment && commentIndexes.includes(commentIndex);
}
}
$('head').contents().filter(commentRemovalFilter([0,1,2,3])).remove();
$('head link').remove();
$('head script').remove();
//Cheerio respects whitespace provided here
$('head').append(`
<link rel="stylesheet" href="css/build/min.css">
<script src="js/build/modernizr.js"></script>
`)
$('body').contents().filter(commentRemovalFilter([1,2])).remove();
$('body script').remove();
$('body').append(` <script src="js/build/libraries.js"></script>
`)
console.log($.html())
output:
<html><head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="css/build/min.css">
<script src="js/build/modernizr.js"></script>
</head>
<body>
<!--[if lt IE 7]>
<p class="chromeframe">You are using an outdated browser. Upgrade your browser today or install Google Chrome Frame to better experience this site.</p>
<![endif]-->
<p>Hello world! This is a basline HTML5 template (based on HTML5 Boilerplate).</p>
<script src="js/build/libraries.js"></script>
</body></html>

Include a jsp page in another page

All of my JSF pages contain the following imports
<h:head>
<title>My Registration Page</title>
<link href="stylesheet/reset.css" rel="stylesheet" type="text/css" />
<link href="stylesheet/style.css" rel="stylesheet" type="text/css" />
<link rel="icon" type="image/png" href="images/icons/favicon.png" />
<script language="javascript" src="script/script.js"/>
Not i dont want to copy and paste all these lines in the head element of my xhtml page;but want to include only a single page, so i want to remove all these lines from the head and put them into another file and then just include that file.
Kind Regards

Searching von strings in html-head with Cucumber

I'm wondering how if I can check the head of a HTML-document for existence of a particular string with cucumber.
Actually I'm interested in specific robots directives, so I launch in the first of my steps a browser (atm Firefox) and open a local site.
In the second step I check the entire html-code for a string:
#b.html.include?('<meta name="robots" content="noindex, follow">').should == true
And see my scenario failing at the second step. (expected true, got false)
Surprisingly a check for an partial string is succesfull:
#b.html.include?('name="robots"').should == true
But as soon as I check for
#b.html.include?('<meta name="robots"').should == true
or just
#b.html.include?('a name="robots"').should == true
I get a false again.
So, I thought the presence of whitespaces causes this behavior.
A quick check with only a bonus whitespace
#b.html.include?(' name="robots"').should == true
and the testscenario is green.
A search for a whole sentence in the document body
#b.html.include?('<h1>Yarr, that "is" supeb!</h1>').should == true
is also passing.
I've also tried to move the h1 heading into the head of the document (test still passing) and the meta-tag into the body (test is still failing)
I'm using cucumber 1.2.0 and ruby 1.9.3p0 with Firefox driven via watir-webdriver and wondering if I'm doing something wrong.
Actually I have just one feature with this simple steps and a minimal html-site with meta-data and this one "Yarr" sentence. No rails, no rake. OS X 10.7
Please tell me if I should provide more information… I'm tinkering with this stuff for hours.
Edit1: added the HTML of the site I check.
<!DOCTYPE html>
<html>
<head>
<title>Home</title>
<meta charset="utf-8">
<link rel="stylesheet" media="screen" href="/public/stylesheets/main.css">
<link rel="shortcut icon" type="image/png" href="/public/images/favicon.png">
<script src="/public/javascripts/jquery-1.6.4.min.js" type="text/javascript" charset="utf-8"></script>
<link rel="canonical" href="google.de">
<meta name="robots" content="noindex, follow">
</head>
<body>
<h1>Yarr, that "ist" superb!</h1>
</body>
</html>
The Problem:
It seems that the properties of HTML tags will not always be in the order that they were written. See this:
puts #b.html
#=> <!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<title>Home</title>
<meta charset="utf-8" />
<link href="/public/stylesheets/main.css" media="screen" rel="stylesheet" />
<link href="/public/images/favicon.png" type="image/png" rel="shortcut icon" />
<script charset="utf-8" type="text/javascript" src="/public/javascripts/jquery-1.6.4.min.js"></script>
<link href="google.de" rel="canonical" />
<meta content="noindex, follow" name="robots" />
</head>
<body>
<h1>Yarr, that "ist" superb!</h1>
</body></html>
Notice that the <meta content="noindex, follow" name="robots" /> is not the same order as your HTML file. This explains why your tests are giving the results they are.
Suggest Solution:
Assuming that you only care that the particular meta tag appears in the header (and not the particular order the tag is written), I would suggest using:
b.head.meta(:name => 'robots', :content => 'noindex, follow').exists?.should == true

Resources