EJS View Not Rendering - javascript

I am trying to load ejs templates in my express app. I set the 'view engine' to ejs and, passed an ejs template to the response.render. However,when I am navigating to localhost:8000, I am only seeing the include statements in literal form.
The template file:
index.ejs
{% include('commonheader') %}
<div id='mainbody' class='container-fluid'>
<nav>
{%- include('mainheader', {
navbar: navbar_options
}) %}
</nav>
</div>
{%- include('commonfooter', {
footer: sitemap
}) %}
commonheader.ejs
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8'>
<title><%= title %></title>
<!-- bootstrap -->
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
crossorigin="anonymous">
<!-- bootstrap js -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
crossorigin="anonymous"></script>
<!-- Jquery -->
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<!-- Custom stylesheets and js -->
<%- if(stylesheets){
if(typeof stylesheets == []){
Array.prototype.forEach(function(sheet){
%}<link rel='stylesheet' href= {%= sheet %}>{%
}, stylesheets);
}
else{
%}<link rel='stylesheet' href= {%= Array.prototype.shift.call(stylesheets) %}>{%;
}
}; %}
</head>
<body>
commonfooter.ejs
<footer>
<% if(footer){
for(let k in footer){
if(typeof footer[k] []){
Array.prototype.forEach.call(function(link){
%}<a href= {%= link['href'] %}>
<li>{%= link['name'] %}</li>
</a>{%
});
}
else{
%}<a href= {%= link['href'] %}>
<ul>{%= link['name'] %}</ul>{%
}
}
%}
</footer>
</body>
</html>
routes.js
const express = require('express');
const path = require('path');
const appinst = express();
const _template_dir = '/static';
const _root_addr = '127.0.0.1:8000';
// bind render engine to ejs
appinst.set('views', path.join(__dirname,'views'));
appinst.set('view engine', 'ejs');
appinst.get('/', function(request, response){
response.render('index', {
css_stylesheets: [
'css/index.css',
],
navbar_options: [
{
'href': _root_addr + '/',
'name': 'Home'
},
{
'href': _root_addr + '/create',
'name': 'Create'
},
{
'href': _root_addr + '/howto',
'name': 'How To'
}
],
sitemap: [
{
'href': _root_addr + '/',
'name': 'Home'
},
{
'href': _root_addr + '/aboutus',
'name': 'About Us'
},
{
'href': _root_addr + '/create',
'name': 'Create'
},
{
'href': _root_addr + '/howto',
'name': 'How To'
},
{
'href': _root_addr + '/contactus',
'name': 'Contact Us'
}
]
});
});
Browser Output:
{% include('commonheader') %}
{%- include('mainheader', { navbar: navbar_options }) %}
{%- include('commonfooter', { footer: sitemap }) %}

i think you mistyped the inclusion, should look like this:
<%- include('mainheader', { navbar: navbar_options }); %>
but from your code you're missing the opening and closing tag <%- %>
you're only using the %- and %
{%- include('mainheader', { navbar: navbar_options }) %}

Related

How can I use javascript library function in nuxt.js?

This source worked in html file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Kakao JavaScript SDK</title>
<script src="https://developers.kakao.com/sdk/js/kakao.js"></script>
<script>
// SDK를 초기화 합니다. 사용할 앱의 JavaScript 키를 설정해 주세요.
Kakao.init('JAVASCRIPT_KEY');
// SDK 초기화 여부를 판단합니다.
console.log(Kakao.isInitialized());
</script>
</head>
<body></body>
</html>
So I thought the next source will work on Nuxt.js.
But it showed just
'ReferenceError
Kakao is not defined' in these source
in nuxt.config.js
// Global page headers (https://go.nuxtjs.dev/config-head)
head: {
title: 'P-Cloud OCR',
meta: [
{ 'http-equiv': 'X-UA-Compatible', content: 'IE=Edge' },
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: '' },
],
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }],
script: [
{ src: 'https://developers.kakao.com/sdk/js/kakao.js'},
]
}, ```
in pages/login.vue
<script>
export default {
...
}
Kakao.init('JAVASCRIPT_KEY');
console.log('Kakao.isInitialized() >>', Kakao.isInitialized());
</script>
Why is this source not working?
There are basically 2 approaches you can do:
1. Load the library directly in your layout/page/component
head () {
if (window.Kakao) {
this.afterKakaoLoaded()
return
}
return {
script: [
{
hid: 'kakao',
src: 'https://developers.kakao.com/sdk/js/kakao.js',
callback: () => {
this.afterKakaoLoaded()
}
}
]
}
},
methods: {
afterKakaoLoaded () {
window.Kakao.init('...')
}
}
2. Load the library within a plugin
Josh Deltener wrote a great article about how to achieve that: https://deltener.com/blog/nuxt-third-party-code-is-poison/
In nuxt you can overwrite the default .nuxt/views/app.template.html.
You need to create app.html file at the root of the project. Then put the below code inside this file:
app.html
<!DOCTYPE html>
<html lang="en" {{ HTML_ATTRS }}>
<head {{ HEAD_ATTRS }}>
{{ HEAD }}
</head>
<body {{ BODY_ATTRS }}>
{{ APP }}
</body>
</html>
Then you can follow the traditional way that you mentioned in question:
<!DOCTYPE html>
<html lang="en" {{ HTML_ATTRS }}>
<head {{ HEAD_ATTRS }}>
{{ HEAD }}
<script src="https://developers.kakao.com/sdk/js/kakao.js"></script>
<script>
// SDK를 초기화 합니다. 사용할 앱의 JavaScript 키를 설정해 주세요.
Kakao.init('JAVASCRIPT_KEY');
// SDK 초기화 여부를 판단합니다.
console.log(Kakao.isInitialized());
</script>
</head>
<body {{ BODY_ATTRS }}>
{{ APP }}
</body>
</html>
But be aware that in this method, all pages in your application load this script.

Is it possible to create a global Ejs component?

As you can see I included my navbar component in my index.ejs file and I am doing the same thing with every other file I have, like user page for example. Is there any way that I can use my navbar component in all of my ejs files by including it somewhere once? instead of including it separately in each ejs file?
Right now I am doing this in every one of my files:
index.ejs:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<% include components/navbar %>
rest of the code...
</body>
</html>
as you requested in comments , this is my way to do it :
i have "views" folder in project including these folders inside :
Assets
Layouts
and dynamic ejs files beside them
let's say we want to render this layout which has a header in each page , but with different body :
layout :
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<% for (let cssLink of cssLinks) { %>
<link rel="stylesheet" href="<%= cssLink %>" />
<% } %>
<title>home page</title>
</head>
<body>
<h1>THIS IS HEADER!</h1>
<div id="demo">
<%- mainView %>
</div>
</body>
</html>
you can see there is a variable mainView in the body , so let's see how can we insert our dynamic body there :
i have a function inside my utility folder which reduces the repeat of code :
const ejs = require('ejs');
const path = require('path');
const layoutsPath = path.join(__dirname, "./../views/layouts/");
const assetsPath = path.join(__dirname, "./../views/assets/");
const viewsPath = path.join(__dirname, './../views/');
const load = (basePath, filename, data, cb = null) => {
let route ;
switch (basePath) {
case 'layout': {
route = layoutsPath;
break;
}
case 'asset': {
route = assetsPath;
break;
}
case 'view': {
route = viewsPath;
break;
}
default: {
route = basePath;
}
}
ejs.renderFile(path.join(route, filename), data, (err, str) => {
if (err) {
console.log(err);
return err;
}
if (cb === null) {
return str;
} else {
return cb(str);
}
});
}
module.exports = {
load
}
now in the index.js i want to output my home.ejs inside my header.ejs to the client :
let allUsers = await usersModule.findAll();
let renderedHTML = '';
load('view', 'home.ejs', { allUsers }, (rendered) => {
load('layout', 'header.ejs', { mainView: rendered, cssLinks: ['/css/header.css'] }, (fullView) => {
renderedHTML = fullView;
});
});
res.status(200).send(renderedHTML);
so here i am getting my required data for my body from database , passing it to the home.ejs , there i loop and render my body view , e.x for home.ejs :
<div>
<% for (let user of allUsers) { %>
<ul>
<li>email : <%= user.email %></li>
<li>name : <%= user.name %></li>
</ul>
<% } %>
</div>
rendered body is passed to our callback as parameter , we can pass it to our header now with variablename mainView , so in the header, the entire rendered body will be insert in the right place in our layout .
now our layout and dynamic body have merged and are ready to be sent to the client

Error in displaying chart in Django with chartit

I have an application for which I am trying to display a simple chart of number of proposals per country. I am using pivotchart in chartit as explained here
I have a model like this
class Proposal(models.Model):
org = models.CharField(max_length=200)
country = models.CharField(max_length=100)
recdate = models.DateField(blank=False)
subdate = models.DateField(blank=False)
status = models.CharField(choices = stat_val, max_length=20)
and as explained in the chartit GitHub, I have added this to views
from django.db.models import Count
from chartit import PivotDataPool, PivotChart
from django.shortcuts import render_to_response
def proposal_pivot_chart_view(request):
# Step 1: Create a PivotDataPool with the data we want to retrieve.
proposalpivotdata = PivotDataPool(
series=[{
'options': {
'source': Proposal.objects.all(),
'categories': ['country'],
},
'terms': {
'countprop': Count('id'),
}
}]
)
# Step 2: Create the PivotChart object
chart1 = PivotChart(
datasource=proposalpivotdata,
series_options=[{
'options': {
'type': 'column',
'stacking': True
},
'terms': ['countprop']
}],
chart_options={
'title': {
'text': 'Proposals by Countries'
},
'xAxis': {
'title': {
'text': 'Country'
}
}
}
)
# Step 3: Send the PivotChart object to the template.
return render_to_response({'chart1': chart1})
and I have created a template like this
<!DOCTYPE html>
<html>
<head>
{% load staticfiles %}
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}" >
<link rel="stylesheet" href="{% static 'bootstrap/css/light-bootstrap-dashboard.css' %}" >
<link rel="stylesheet" href="{% static 'bootstrap/css/animate.min.css' %}">
<link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
<link href='http://fonts.googleapis.com/css?family=Roboto:400,700,300' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="{% static 'bootstrap/css/pe-icon-7-stroke.css' %}">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" type="text/javascript"></script>
<script src="{{ MEDIA_URL }}highcharts/js/highcharts.js" type="text/javascript"></script>
{% load chartit %}
{{ rainpivchart|load_charts:"container" }}
</head>
<body>
{% include "proposal/main-banner.html"%}
<div id='container'></div>
<button>Back to Proposal List</button>
</body>
</html>
But there is some problem and I am getting error
TemplateDoesNotExist at /chart1/
{'chart1': <chartit.charts.PivotChart object at 0x046ADF30>}
Request Method:
GET
Request URL:
http://127.0.0.1:8000/chart1/
Django Version:
1.10.6
Exception Type:
TemplateDoesNotExist
Exception Value:
{'chart1': <chartit.charts.PivotChart object at 0x046ADF30>}
Exception Location:
C:\Users\Parag\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django-1.10.6-py3.6.egg\django\template\loader.py in get_template, line 25
Python Executable:
C:\Users\Parag\AppData\Local\Programs\Python\Python36-32\python.exe
Python Version:
3.6.0
Python Path:
['C:\\Users\\Parag\\AppData\\Local\\Programs\\Python\\Python36-32\\Lib\\site-packages\\Django-1.10.6-py3.6.egg\\django\\bin\\myoffice',
'C:\\Users\\Parag\\AppData\\Local\\Programs\\Python\\Python36-32\\python36.zip',
'C:\\Users\\Parag\\AppData\\Local\\Programs\\Python\\Python36-32\\DLLs',
'C:\\Users\\Parag\\AppData\\Local\\Programs\\Python\\Python36-32\\lib',
'C:\\Users\\Parag\\AppData\\Local\\Programs\\Python\\Python36-32',
'C:\\Users\\Parag\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\site-packages',
'C:\\Users\\Parag\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\site-packages\\django-1.10.6-py3.6.egg']
Server time:
Tue, 18 Apr 2017 16:09:08 +0400
Template-loader postmortem
Django tried loading these templates, in this order:
Using engine django:
django.template.loaders.app_directories.Loader: C:\Users\Parag\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django-1.10.6-py3.6.egg\django\contrib\admin\templates\{'chart1': <chartit.charts.PivotChart object at 0x046ADF30>} (Source does not exist)
django.template.loaders.app_directories.Loader: C:\Users\Parag\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django-1.10.6-py3.6.egg\django\contrib\auth\templates\{'chart1': <chartit.charts.PivotChart object at 0x046ADF30>} (Source does not exist)
django.template.loaders.app_directories.Loader: C:\Users\Parag\AppData\Local\Programs\Python\Python36-32\lib\site-packages\highcharts\templates\{'chart1': <chartit.charts.PivotChart object at 0x046ADF30>} (Source does not exist)

How to show custom server errors in UI using Plupload and Symfony3

INTRODUCTION
In order to upload multiple files to the server I am using:
Symfony v3.2.6
OneUpUploaderBundle
OneUpFlysystemBundle
Plupload file uploading library
NOTE
Please note that: this configuration works without a hitch for single and multiple file uploads. It just does not show custom server errors in the clients browser.
TARGET
I would like to show file exists error in UI
PROBLEM
I am using validator to restrict some uploadable files.
At the moment files that validator restricts are not uploaded (ValidationException is beeing trown).
I do not know how to make Plupload to show file already exist errors.
CODE
My template with relevant javascript code
{% extends 'base.html.twig' %}
{% block stylesheets %}
{{ parent() }}
<link type="text/css" rel="stylesheet" href="{{ asset('js/plupload/jquery-ui-1.12.1/jquery-ui.css') }}" />
<link type="text/css" rel="stylesheet" href="{{ asset('js/plupload/jquery.ui.plupload/css/jquery.ui.plupload.css') }}" media="screen" />
{% endblock %}
{% block content %}
<div id="box-upload">
<div id="uploader">
<p>Your browser doesn't have HTML5 support.</p>
</div>
</div>
{% endblock %}
{% block javascripts %}
<script type="text/javascript" src="{{ asset('js/browserplus/browserplus.js') }}"></script>
<script type="text/javascript" src="{{ asset('js/plupload/plupload.full.min.js') }}"></script>
<script type="text/javascript" src="{{ asset('js/jquery-2.2.4.js') }}"></script>
<script type="text/javascript" src="{{ asset('js/plupload/jquery-ui-1.12.1/jquery-ui.js') }}"></script>
<script type="text/javascript" src="{{ asset('js/plupload/jquery.ui.plupload/jquery.ui.plupload.js') }}"></script>
<script type="text/javascript" src="{{ asset('js/plupload/i18n/lv.js') }}"></script>
<script type="text/javascript">
'use strict';
$(function()
{
var uploader;
uploader = $("#uploader");
uploader.plupload(
{
// General settings
runtimes: 'html5',
url: "{{ oneup_uploader_endpoint('gallery') }}",
multi_selection: true,
// Maximum file size
max_file_size: '5mb',
chunk_size: '5mb',
// Specify what files to browse for
filters: [
{title: "Image files", extensions: "jpg,jpeg,png,gif"},
{title: "Zip files", extensions: "zip,7z"},
{title: "Pdf files", extensions: "pdf"},
{title: "Binary files", extensions: "bin"},
{title: "Text files", extensions: "txt"},
{title: "Media files", extensions: "avi"}
],
// Rename files by clicking on their titles
rename: true,
// Sort files
sortable: true,
// Enable ability to drag'n'drop files onto the widget (currently only HTML5 supports that)
dragdrop: true,
// Views to activate
views: {
list: true,
thumbs: false, // Show thumbs
active: 'list'
}
});
var $uploader = uploader.plupload('getUploader');
// Add Clear Button
var $button = $("<button>"+ plupload.translate("Clear list") + "</button>").button({icons: {primary: "ui-icon-trash"}}).button("disable").appendTo('.plupload_buttons');
// Clear Button Action
$button.click(function()
{
removeErrorMessages();
$uploader.splice();
$(".plupload_filelist_content").html('');
$button.button("disable");
return true;
});
// Clear Button Toggle Enabled
$uploader.bind('QueueChanged', function ()
{
if ($uploader.files.length > 0)
{
$button.button("enable");
}
else
{
$button.button("disable");
}
});
// Clear Button Toggle Hidden
$uploader.bind('StateChanged', function ()
{
if ($uploader.state == plupload.STARTED)
{
$button.hide();
}
else
{
$button.show();
}
});
// Clear Button Toggle Hidden
$uploader.bind('Browse', function ()
{
removeErrorMessages();
$uploader.splice();
});
$uploader.bind('Error', function(uploader, error)
{
console.error(error.message);
console.log(error.message);
});
function removeErrorMessages()
{
$(".ui-state-error").remove();
}
});
</script>
{% endblock %}
My validator
<?php
namespace AppBundle\EventListener;
use Oneup\UploaderBundle\Event\ValidationEvent;
use Oneup\UploaderBundle\Uploader\Exception\ValidationException;
use Symfony\Component\DependencyInjection\ContainerInterface as Container;
class AllowedMimeTypeValidationListener
{
/**
* #var Container
*/
private $container;
private $file_extension_array = [];
private $file_type_array = [];
private $banned_files = [];
public function __construct(Container $container)
{
$this->container = $container;
}
public function onValidate(ValidationEvent $event)
{
$ultra_helpers = $this->container->get('app.ultra_helpers');
$ultra_text = $this->container->get('app.ultra_text');
array_push($this->file_extension_array, '.gif');
array_push($this->file_extension_array, '.jpg');
array_push($this->file_extension_array, '.jpeg');
array_push($this->file_extension_array, '.png');
array_push($this->file_extension_array, '.zip');
array_push($this->file_extension_array, '.7z');
array_push($this->file_extension_array, '.pdf');
array_push($this->file_extension_array, '.bin');
array_push($this->file_extension_array, '.txt');
array_push($this->file_type_array, 'image/gif');
array_push($this->file_type_array, 'image/jpg');
array_push($this->file_type_array, 'image/jpeg');
array_push($this->file_type_array, 'image/png');
array_push($this->file_type_array, 'application/zip');
array_push($this->file_type_array, 'application/x-7z-compressed');
array_push($this->file_type_array, 'application/pdf');
array_push($this->file_type_array, 'application/octet-stream');
array_push($this->file_type_array, 'text/plain');
array_push($this->banned_files, 'do_not_allow_me_1.txt');
array_push($this->banned_files, 'do_not_allow_me_3.txt');
array_push($this->banned_files, 'do_not_allow_me_2.txt');
$file = $event->getFile();
$file_extension = '.'. $file->getExtension();
$file_mime_type = $file->getMimeType();
$file_info = $ultra_helpers->filterFileInfoFromFilename($file->getClientOriginalName());
$transliterated_file_name = $ultra_text->transliterateText($file_info['name']);
$full_file_name = $transliterated_file_name .'.'. $file_info['extension'];
if (in_array($full_file_name, $this->banned_files))
{
throw new ValidationException('error.file_exists');
}
// Is file mime type the same as extension mime type
$mime_type_position = array_search($file_extension, $this->file_extension_array);
if ($mime_type_position !== false)
{
$mime_type_by_extension = $this->file_type_array[$mime_type_position];
if ($mime_type_by_extension !== $file_mime_type)
{
throw new ValidationException('error.mime_type_mismatch');
}
}
// Is file type not in activated file type array
if (!in_array($file_mime_type, $this->file_type_array))
{
throw new ValidationException('error.forbidden_mime_type');
}
}
}
FINALLY
What am I missing?
CONCLUSION
Please advise.
Thank You for your time and knowledge.
To show error in UI one has to listen to FileUploaded event and manually trigger an error (like in code example below).
$uploader.bind('FileUploaded', function(up, file, info)
{
var response;
response = jQuery.parseJSON(info.response);
// trigger error manually
up.trigger("error", {message: "Test error message", code: 12345, details: "Testing errors"});
// add some CSS class to the corresponding file in UI
$("#"+ file.id).addClass("highlight-file");
});

Node Js Express Iterate through array

I have split the STDOUT of a shell command into an array, and am passing this to hogan view engine with express.
The below is the from the router file - index.js
/* Test Shell Execute. */
router.get('/shell', function(req, res){
exec('ls -1', function (error, stdout, stderr) {
result = stdout.toString().split("\n");
res.render('shell', { title: "File Explorer",
array1: result[0],
array2: result[1],
array3: result[2],
array4: result[3],
array5: result[4],
error: error,
stderr: stderr
});
});
});
This is working fine, however rather than manually send through each item in the array, I would like to iterate through the items at the view end and then ouput. However I am using Hogan view engine and it doesn't seem to recognise the script tag at all.
This is from my view shell.hjs file.
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1>{{ title }}</h1>
<p>Welcome to {{ title }}</p>
<p>Array1 = {{ array1 }}</p>
<p>Array2 = {{ array2 }}</p>
<p>Array3 = {{ array3 }}</p>
<p>Array4 = {{ array4 }}</p>
<script>
for(var i = 0; i > result.length; i++ ) {
document.write('<p>' + result[i] + '</p>')
}
</script>
</body>
</html>
Question: What am I doing wrong and what is the best/easiest way to do this?
Since hogan.js is based on mustache.js, it's always better try to convert your arrays into objects. Try this:
router.get('/shell', function(req, res){
exec('ls -1', function (error, stdout, stderr) {
result = stdout.split("\n"),
filesArray = [];
result.map(function (file, index) {
filesArray.push({index: ++index, file: file});
});
res.render('shell', { title: "File Explorer",
result: filesArray,
error: error,
stderr: stderr
});
});
});
And, in your template:
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1>{{ title }}</h1>
<p>Welcome to {{ title }}</p>
<ul>
{{#result}}
<li>Array{{index}} = {{file}}</li>
{{/result}}
</ul>
</body>
</html>

Categories

Resources