Javascript file not loading into Jade file - javascript

Here's the file structure i am using
-----+root
----------+app
--------------+common
--------------+config
--------------+controllers
--------------------------+rootPage.js
----------+public
--------------+rootPage.jade
----------+server.js
Here's my jade file
doctype
html(lang = 'en')
head
title PlanUrNight
meta(charset = 'utf-8')
link(rel = 'stylesheet' href = '//maxcdn.bootstrapcdn.com/bootswatch/3.3.0/flatly/bootstrap.min.css')
link(src='//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js' rel = 'stylesheet')
link(rel = 'stylesheet' href = './css/rootPage.css')
body
nav.navbar.navbar-inverse(role= 'navigation')
.navbar-header
button.navbar-toggle.collapsed( type='button', data-toggle='collapse', data-target='#navbar-inverse', aria-expanded='false', aria-controls='navbar')
span.sr-only Toggle navigation
span.icon-bar
span.icon-bar
span.icon-bar
a.navbar-brand(href='#') PlanUrNight
.collapse.navbar-collapse#navbar-inverse
ul.nav.navbar-nav
li: a( href="#") Home
.collapse.navbar-collapse.navbar-right
.facebook-login-wrapper
a.btn.btn-primary(href='/auth/facebook') Facebook
span.fa.fa-facebook
.container-fluid
.row
.col-md-8.col-md-offset-2.main-container
.images-container
img.drink(src='img/drinking.png')
img.dance(src='img/couple_dancing.png')
img.club(src='img/club_ball.png')
.row
.col-md-2.col-md-offset-6.search-container
span.glyphicon.glyphicon-search
.input-group
input.form-control(type='text', placeholder='Search')
script( src='//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js' type='text/javascript')
script( src='./controllers/rootPage.js' type='text/javascript')
I have tried multiple variations of the source, but it just doesn't seem to be loading the JavaScript file. Each time I get an error log in my console, saying Error 404: rootPage.js not found
I am using express with node, and in my server.js file I have the following line for serving static files
app.use(express.static(__dirname+'/public'));
So what am I doing wrong here? Does the usage of the app.use line above change the root of my directory in some way so that I need to change the file path to access my JS files?
Or is there a different way to load JS files in Jade?

Your file organization is a bit wonky. Based on the one middleware you showed us, all files in the /public folder will be served as-is, but no static files elsewhere will be.
Generally, jade files that you're rendering with server logic are in a /views folder which is not served directly, but instead available to server side route handlers or controller logic to call res.render with.
So if you have clientside JS files you want to serve as static content you need them either under the /public folder or create more static middleware calls to point to whatever folder they are in.
/** Edit after first two comments **/
Sorry for not providing more examples, etc before, I was on my phone.
Wonky is perhaps a harsh term and I'm sorry. What I meant was it doesn't really match the standard layouts I've seen. There's a few ways to do it, but most small(ish) Express projects at least start out with the template generated by the express command line tool.
In that case, all the stuff in your ./root/app directory would be server-side code that doesn't get directly served to the client ever. Most of the sites I've seen (exception being the default template from the MEAN.js project) follow a pattern something like this:
app
- errors
- models
- controllers
- routes
- views
public
- css
- js
- img
package.json
server.js
Sometimes there's a lib folder that's a peer of app where you put utility stuff. 'views' is where all the jade templates live.
Everything in the public folder is exposed via a single middleware like you did:
app.use(express.static(__dirname+'/public'));
Everything else will not get served as static files. If you have a clientside JS structure that uses an MVC pattern, you'd then have model, view, and controller folders under ./public/js
The MEAN.js folks take a different approach, making each logical component of the app (e.g. user management, etc) into a module and then organizing each module as folders that look like ./<module name>/server and ./<module name>/client with structure for models, controllers, etc, under each of those depending on if it's server code or client code.
You're correct on how to add more more static middleware.

Try
script( src='./app/controllers/rootPage.js' type='text/javascript')

Related

Basic Python Web application giving jinja2 error [duplicate]

I am trying to render the file home.html. The file exists in my project, but I keep getting jinja2.exceptions.TemplateNotFound: home.html when I try to render it. Why can't Flask find my template?
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def home():
return render_template('home.html')
/myproject
app.py
home.html
You must create your template files in the correct location; in the templates subdirectory next to the python module (== the module where you create your Flask app).
The error indicates that there is no home.html file in the templates/ directory. Make sure you created that directory in the same directory as your python module, and that you did in fact put a home.html file in that subdirectory. If your app is a package, the templates folder should be created inside the package.
myproject/
app.py
templates/
home.html
myproject/
mypackage/
__init__.py
templates/
home.html
Alternatively, if you named your templates folder something other than templates and don't want to rename it to the default, you can tell Flask to use that other directory.
app = Flask(__name__, template_folder='template') # still relative to module
You can ask Flask to explain how it tried to find a given template, by setting the EXPLAIN_TEMPLATE_LOADING option to True. For every template loaded, you'll get a report logged to the Flask app.logger, at level INFO.
This is what it looks like when a search is successful; in this example the foo/bar.html template extends the base.html template, so there are two searches:
[2019-06-15 16:03:39,197] INFO in debughelpers: Locating template "foo/bar.html":
1: trying loader of application "flaskpackagename"
class: jinja2.loaders.FileSystemLoader
encoding: 'utf-8'
followlinks: False
searchpath:
- /.../project/flaskpackagename/templates
-> found ('/.../project/flaskpackagename/templates/foo/bar.html')
[2019-06-15 16:03:39,203] INFO in debughelpers: Locating template "base.html":
1: trying loader of application "flaskpackagename"
class: jinja2.loaders.FileSystemLoader
encoding: 'utf-8'
followlinks: False
searchpath:
- /.../project/flaskpackagename/templates
-> found ('/.../project/flaskpackagename/templates/base.html')
Blueprints can register their own template directories too, but this is not a requirement if you are using blueprints to make it easier to split a larger project across logical units. The main Flask app template directory is always searched first even when using additional paths per blueprint.
I think Flask uses the directory template by default. So your code should be like this
suppose this is your hello.py
from flask import Flask,render_template
app=Flask(__name__,template_folder='template')
#app.route("/")
def home():
return render_template('home.html')
#app.route("/about/")
def about():
return render_template('about.html')
if __name__=="__main__":
app.run(debug=True)
And you work space structure like
project/
hello.py
template/
home.html
about.html
static/
js/
main.js
css/
main.css
also you have create two html files with name of home.html and about.html and put those files in templates folder.
If you must use a customized project directory structure (other than the accepted answer project structure),
we have the option to tell flask to look in the appropriate level of the directory hierarchy.
for example..
app = Flask(__name__, template_folder='../templates')
app = Flask(__name__, template_folder='../templates', static_folder='../static')
Starting with ../ moves one directory backwards and starts there.
Starting with ../../ moves two directories backwards and starts there (and so on...).
Within a sub-directory...
template_folder='templates/some_template'
I don't know why, but I had to use the following folder structure instead. I put "templates" one level up.
project/
app/
hello.py
static/
main.css
templates/
home.html
venv/
This probably indicates a misconfiguration elsewhere, but I couldn't figure out what that was and this worked.
If you run your code from an installed package, make sure template files are present in directory <python root>/lib/site-packages/your-package/templates.
Some details:
In my case I was trying to run examples of project flask_simple_ui and jinja would always say
jinja2.exceptions.TemplateNotFound: form.html
The trick was that sample program would import installed package flask_simple_ui. And ninja being used from inside that package is using as root directory for lookup the package path, in my case ...python/lib/site-packages/flask_simple_ui, instead of os.getcwd() as one would expect.
To my bad luck, setup.py has a bug and doesn't copy any html files, including the missing form.html. Once I fixed setup.py, the problem with TemplateNotFound vanished.
I hope it helps someone.
Check that:
the template file has the right name
the template file is in a subdirectory called templates
the name you pass to render_template is relative to the template directory (index.html would be directly in the templates directory, auth/login.html would be under the auth directory in the templates directory.)
you either do not have a subdirectory with the same name as your app, or the templates directory is inside that subdir.
If that doesn't work, turn on debugging (app.debug = True) which might help figure out what's wrong.
I had the same error turns out the only thing i did wrong was to name my 'templates' folder,'template' without 's'.
After changing that it worked fine,dont know why its a thing but it is.
You need to put all you .html files in the template folder next to your python module. And if there are any images that you are using in your html files then you need put all your files in the folder named static
In the following Structure
project/
hello.py
static/
image.jpg
style.css
templates/
homepage.html
virtual/
filename.json
When render_template() function is used it tries to search for template in the folder called templates and it throws error jinja2.exceptions.TemplateNotFound when :
the file does not exist or
the templates folder does not exist
Create a folder with name templates in the same directory where the python file is located and place the html file created in the templates folder.
Another alternative is to set the root_path which fixes the problem both for templates and static folders.
root_path = Path(sys.executable).parent if getattr(sys, 'frozen', False) else Path(__file__).parent
app = Flask(__name__.split('.')[0], root_path=root_path)
If you render templates directly via Jinja2, then you write:
ENV = jinja2.Environment(loader=jinja2.FileSystemLoader(str(root_path / 'templates')))
template = ENV.get_template(your_template_name)
After lots of work around, I got solution from this post only,
Link to the solution post
Add full path to template_folder parameter
app = Flask(__name__,
template_folder='/home/project/templates/'
)
My problem was that the file I was referencing from inside my home.html was a .j2 instead of a .html, and when I changed it back jinja could read it.
Stupid error but it might help someone.
Another explanation I've figured out for myself
When you create the Flask application, the folder where templates is looked for is the folder of the application according to name you've provided to Flask constructor:
app = Flask(__name__)
The __name__ here is the name of the module where application is running. So the appropriate folder will become the root one for folders search.
projects/
yourproject/
app/
templates/
So if you provide instead some random name the root folder for the search will be current folder.

How to load a CSS file with out generating an extra network request in express / react?

In React I have most of my CSS tied to my modules as follows. Module1.jsx has Module1.css, and so on and so on.
Webpack builds all these modules into a single request via bundle.js.
However, I do have about 40 lines of CSS that I use app wide that does not belong in a single module. In fact some of it targets elements outside of the app, i.e. the body tag.
Currently I have it hard coded in the index.html file which express serves. I could put it in another file and link to it, but his would require another network request.
I would like it in its own file, but then injected into index.html file before it is served.
I'm not sure if webpack can do this, or it can be done via express. But the syntax might look like this:
Instead of this:
<link rel="stylesheet" href="styles.css">
Maybe ssi for server-side-indlcude and the file to include at that location:
<ssi file="styles.css">
It just seems in-efficient to send the index.html to the client, and than for the client to request the CSS, when it can just be sent in the initial request.
In general the reasons for this are:
to clean up index.html and make it more human readable
to follow a separation of concerns design architecture
Ideas on how to do this:
using templates ( is this overkill )
is there a way to implement sever side includes?
does webpack have a way to insert files into file?
can express bundles static files?

How do you change file paths in Angular app?

I'm looking at this sample Angular application.
In the index.html file, there are lines like
<script type="text/javascript" src="/static/angular.js"></script>
However, upon closer inspection there are no folders in the project called static.
How does this work? How does angular locate these references?
Angular has nothing to do with this. It is the express server which takes care of the paths.
Take a look at server/config.js. You will see staticUrl: '/static' mentioned there.
Now open server/server.js (server.js is the script which runs before anything else runs in the app so all the configuration is done within this file) and on line 21 you will see require('./lib/routes/static').addRoutes(app, config);. This requires the static.js file which instructs the app to use /static (mentioned in the config.js file) as the path for static files such as CSS and javascript files.
This is a server side phenomenon. There is a middleware in this file server/lib/routes/static.js :
line : 9
app.use(config.server.staticUrl, express.static(config.server.distFolder));
What this does is : if any http request is started from config.server.staticUrl (whitch is /static for this app) the server tries to respond with the resource that are kept in a config.server.distFolder folder (which is client/dist for this app).
For example :
when you request to this url /static/angular.js the middleware tries to find angular.js file in client/dist/. Because client/dist directory is mapped to the url which starts with /static by the middleware.
When that HTML file is processed by the browser, the layout engine is making a separate HTTP request to the server to download the resource in question:
/static/angular.js
Since all of that is handled by the server routing mechanism there doesn't have to be a folder named static in client code. Your example is using Node.js Express routing which maps /static routes to actual physical paths.
Here is a piece of code that configures static routes:
https://github.com/angular-app/angular-app/blob/master/server/config.js
The important parts are:
staticUrl: '/static', // The base url from which we serve static files (such as js, css and images)
And the destination folder that /static maps to:
distFolder: path.resolve(__dirname, '../client/dist'), // The folder that contains the application files (note that the files are in a different repository) - relative to this file
Per the documentation the dist folder contains the Grunt build results, and if you take a look at the gruntfile you will find all the grunt configuration that makes this possible.
https://github.com/angular-app/angular-app/blob/master/client/gruntFile.js

Angularstrap popover data-template making GET requests

I'm trying to convert an Express app templated with EJS to Angular. When trying to use the Angular Strap popover I want the popover content to show the data from a HTML partial. The problem is when I reference the file the server makes a GET request for that route and cannot be found.
My express configuration has the index.html file in a templates folder. The statics are in a public folder in a neighboring directory. The complete folder structure looks like this:
app
--public
--templates
-index.html
-user.html
The popover content I want is in user.html and it's being referenced from index.html. My angular code looks like this:
<a
title="User Info"
data-content="test"
data-template="/user.html"
bs-popover>whatever</a>
I've tried user.html, /user.html, and any combination of those. In the console it throws a 404 error from the root saying that http://hostname.com/user.html doesn't exist. My question is, how do I reference a partial html file in angular and get it to point to the right file and not to a GET request to the server?
I've also tried using angular-ui-bootstrap but it lacks partials support.
Thanks!
The files need to be in the folder defined by your Express configuration as the statics folder. So /user.html is looking in public/user.html for the file. If it doesn't find it, then it sends a GET request to the server.

Sending only specified javascript files to the front-end

I have an app like this
/app
/views
index.jade
/controllers
controllers1.js
controllers2.js
server.js
Inside server.js I use app.use(express.static(path.join(__dirname, 'app'))); and all requests render index.jade. Inside index.jade I call the controllers with regular <script> tags.
My Problem
I'm uncomfortable with exposing all my scripts to the front-end. e.g.: I don't want people to type www.myurl.com/controllers/controllers1.js and see the script, because I don't want to show all my business logic right away, especially to users who aren't logged in.
Question
Having deactivated express.static(), is it possible through express Middleware to get the contents a certain javascript files and include/send them to index.jade? Ideally I want to control which script files the front-end can receive/see.
There's probably many ways to do this. Should I be using some kind of library for this (maybe Requirejs, idk much about it)?
deactivating express.static is not required
use public folder for all the content which you want to expose to users
like
app
->controllers
public
->js
->->jQuery.js
->->abc.js
->css
->->bootstrap.css
htmls goes here
and use express.static(__dirname,'public') to expose public folder.
One strategy I've used is to separate the public and private node files. The public libraries implement dual purpose node/browser code. I use a folder structure that looks something like this:
/app
/lib
/public
public_library.js
private_library.js
Then it's simple to expose the public directory so that you can do both:
var mylib = require('public/public_library.js');
in your node files and
<script src="lib/public/public_library.js"></script>
in your browser facing code.
Put all libraries you want to expose in the public directory. Put all libraries you want to keep private outside of the public directory.

Categories