Node.js and swig template engine - including template inside template - node.js

I trying to create main page (part of node.js and mongoDB application) that includes login form.
To add view part I included js files with function that returns HTML, but as I can see much better is using template engine.
Everything is OK until I including one compiled swig part inside another one.
The output of main page is OK, but login part outputs like text on the page.
How is possible to output the login HTML as HTML instead of plain text?
Does more information needed to understand the issue?
Thank you in advance.
var swig = require('swig');
var mainPage_tpl = swig.compileFile(__dirname+'/../views/mainpage_tpl.html');
var formLogin_tpl = swig.compileFile(__dirname+'/../views/login_tpl.html');
var loginOutput = formLogin_tpl();
var mainPageOutput = mainPage_tpl({
title: 'Sometitle',
pagetitle: 'Somepagetitle',
content: loginOutput
});
exports.get = function(req, res){
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(mainPageOutput);
res.end();
}
mainpage_tpl.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{title}}</title>
<link rel="stylesheet" href="/assets/reset.css" />
<link rel="stylesheet" href="/assets/style.css" />
<script type="text/javascript" src="/assets/jquery-2.0.0.js"></script>
<script type="text/javascript" src="/assets/script.js"></script>
</head>
<body id="login_page">
<h1>{{pagetitle}}</h1>
<div id="content">{{content}}</div>
</body>
</html>

If you want to include literal HTML, you need to tell Swig to not escape it using the safe filter:
...
<div id="content">{{ content|safe }}</div>
...

Related

Embedding twitter timeline does not render in angular 7

I am following https://help.twitter.com/en/using-twitter/embed-twitter-feed for embedding timeline in the angular page. Only button renders but not the actual timeline.
The index.html looks like:
<body style="margin:0">
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<app-root></app-root>
</body>
app.component.html looks like below:
<a class="twitter-timeline"
href="https://twitter.com/TwitterDev/lists/national-parks?ref_src=twsrc%5Etfw">
A Twitter List by TwitterDev
</a>
Also tried things like app.component.ts:
ngOnInit(){
if ((<any>window).twttr.ready())
(<any>window).twttr.widgets.load();
}
But no luck
you need to load widgets.js script after twitter-timeline element is been render so if you place the script in index.html it is will load and the element hasn't render yet.
๐ŸŒŸ the best way around it is to create a script tag dynamically after the element is rendered.
twitter component
export class TwitterComponent {
#Input() user:string;
constructor(private renderer2: Renderer2,private el: ElementRef) {}
ngAfterViewInit() {
let scriptEl = document.createElement('script');
scriptEl.src = "https://platform.twitter.com/widgets.js"
this.renderer2.appendChild(this.el.nativeElement, scriptEl);
}
}
template
<a class="twitter-timeline" href="https://twitter.com/{{user}}">Tweets by {{user}}</a>
app componenet template
<app-twitter [user]="name"></app-twitter>
angular twitter widgets โšกโšก
ngAfterViewInit() a lifecycle hook that is called after Angular has fully initialized a component's view.
Updated ๐Ÿ”ฅ๐Ÿ”ฅ
a simple soulution mention in this answer before by user named Bernardo Baumblatt
put the script link in the index.html
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8">
</script>
load the twitter widgets when ngAfterViewInit method call
ngAfterViewInit() {
// #ts-ignore
twttr.widgets.load();
}
in any case the script has not loaded yet you will got an error like ๐Ÿ†˜ twttr is not defined ๐Ÿ‘‰ so download the widgets.js script and include it to your project by using import
main.ts
import './app/widgets.js'
demo ๐Ÿ’ฅ๐Ÿ’ฅ
I had a requirement of dynamically rendering timelines based on different twitter timelines.
I found a workaround by creating a variable in the constructor that stores the href based on the twitter username .
So for example if your link is "https://twitter.com/TwitterDev/lists/national-parks?ref_src=twsrc%5Etfw"
, you just put this in the constructor in a previously defined global variable , say "embedLink"
such as in your ts component:
#Component({
selector: 'app-tree-dashboard',
templateUrl: './tree-dashboard.component.html',
styleUrls: ['./tree-dashboard.component.css']
})
export class TreeDashboardComponent implements OnInit,AfterViewInit {
embedLink='';
constructor(private matIconRegistry: MatIconRegistry,
) {
this.embedLink= "https://twitter.com/TwitterDev/lists/national-parksref_src=twsrc%5Etfw"
}};
and then in your HTML :
<a class="twitter-timeline" href={{embedLink}}></a>
And lastly you only need to add the script in index.html which you have done already.
So you're good to go!
Below is my code. I'm creating blank website so I think it's should not be a problem. What I think is maybe the order of the script in index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Twitter</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
</head>
<body>
<app-root></app-root>
</body>
<script
async
src="https://platform.twitter.com/widgets.js"
charset="utf-8"
></script>
</html>
In my app.component.html
<a class="twitter-timeline"
href="https://twitter.com/TwitterDev/lists/national-parks?ref_src=twsrc%5Etfw">
A Twitter List by TwitterDev
</a>
You can view my code here

hbs rendered site with handlebars.js in the script - nodejs

I use hbs to render my pages with partials for navigation and footers.
router.get('/test', function (req, res) {
return res.render('test');
});
On one page I have template that uses mustache.js. This template doesn't work as it should as the {{}} seems to be picked up on the hbs render. Below is a basic example that illustrates the error. If I load this as a static page with express I get "Joe is a Web Developer", if I render it with hbs I get "is a".
Are there any work arounds that wont involve me changing how all my pages are rendered?
<!doctype html>
<html lang="en">
<head>
<title>Mustache.js Inline Method</title>
<script type="text/javascript" src="js/libs/mustache.js" ></script>
<script>
var view = {
name : "Joe",
occupation : "Web Developer"
};
function loadtemp(){
var output = Mustache.render("{{name}} is a {{occupation}}", view);
document.getElementById('person').innerHTML = output;
}
</script>
</head>
<body onload="loadtemp()" >
<p id="person"></p>
</body>
</html>
It was simple enough. I just had to escape the brackets with a \
So all it took was
\{{name}}

Conditional class in Marko JS Template

I am using the layout taglib to extend a page to its template but i don't know how to pass a variable to the main layout and apply a conditional class.
Considering this is my main-layout.marko
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body class="#### (TITLE === 'REGISTER')?'ACTIVE':'INACTIVE' ####">
<layout-placeholder name="title"/>
<layout-placeholder name="body"/>
</body>
</html>
this is my registration.marko
<layout-use template="./layout.marko">
<layout-put into="title">
$data.title
</layout-put>
<layout-put into="body">
some content
</layout-put>
</layout-use>
and finally this is the code I use to render the page and pass the title data
router.get('/register', function(req, res, next) {
registration.render({
title: 'register'
}, res);
});
How can I create a conditional class on the main-layout.marko file that switches between active or inactive depending on the page title?
Thanks
You can pass data to a layout by adding additional attributes to your <layout-use> tag. See: marko-layout ยป Layout Data
For your example, the following will work:
In main-layout.marko:
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body class="#### ${data.title === 'REGISTER' ? 'ACTIVE' : 'INACTIVE' } ####">
<layout-placeholder name="title">
${data.title}
</layout-placeholder>
<layout-placeholder name="body"/>
</body>
</html>
In registration.marko:
<layout-use template="./layout.marko" title="${data.title}">
<layout-put into="body">
some content
</layout-put>
</layout-use>
That should solve your problem, but let me know if you are still stuck.
there is another way of passing data t all of its template that is using $global in which you are passing your data .
and after using global you dont need to add attribute to any tag . you can access it by using like
out.global.username

Create HTML element with YUI

I am using following code to create a html element in the page body with using YUI.
This code doesn't produce any error.
The issue is, the paragraph element is not created in the html page.
<html>
<head>
<title>YUI Test</title>
<meta charset="UTF-8">
<script src="http://yui.yahooapis.com/3.14.1/build/yui/yui-min.js"></script>
<script>
// Create a YUI sandbox on your page.
YUI().use('node', function(Y) {
// Create DOM nodes.
var contentNode = Y.Node.create('<p>');
contentNode.setHTML('This is a para created by YUI...');
});
</script>
</head>
<body>
<h1>Page body section...</h1>
</body>
</html>
The node is created, but it is also detached from the DOM. You have to attach it to the DOM by using either
Y.one('body').append(contentNode);
or
contentNode.appendTo(Y.one('body'));
or
Y.one('nav.main-navigation').insert(contentNode, 'before');
or any of the other methods for manipulating dom in YUI.

Setting Center Point in Google Search

I am trying to learn how to use Google Local Search API. I am unable to set the local search center point to Pakistan. Please guide me. Thanks.
The line in code with the problem is:
localSearch.setCenterPoint("Pakistan, PAK");
The fiddle showing that results from NewYork are being displayed is here.
The whole code is,
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Hello World - Google Web Search API Sample</title>
<script src="https://www.google.com/jsapi"
type="text/javascript"></script>
<script language="Javascript" type="text/javascript">
//<!
//google.load('search', '1');
google.load("search", "1", {"nocss" : true});
function OnLoad() {
// Create a search control
var searchControl = new google.search.SearchControl();
// Add in a full set of searchers
var localSearch = new google.search.LocalSearch();
searchControl.addSearcher(new google.search.NewsSearch());
// Set the Local Search center point
localSearch.setCenterPoint("Pakistan, PAK");
// tell the searcher to draw itself and tell it where to attach
searchControl.draw(document.getElementById("searchcontrol"));
// execute an inital search
searchControl.execute("Facebook");
}
google.setOnLoadCallback(OnLoad);
//]]>
</script>
</head>
<body>
<div id="searchcontrol">Loading</div>
</body>
</html>
I believe you need to know what the latitude and longitude of PAK is for it to find it.
setCenter(latlng:LatLng);

Resources