The relative file path suggests a different folder structure? - relative-path

I have the below folder/file structure:
bmi-calculator > public > styles.css
bmi-calculator > views > index.ejs
bmi-calculator > bmi-calculator.js
In my index.ejs file, I have the following lines to link the css file and the js script:
<link rel="stylesheet" href="../public/styles.css">
<script src="../bmi-calculator.js" async defer></script>
However, the css styles sheet isn't linking correctly (the JS file does), but when it is changed to this it links:
<link rel="stylesheet" href="styles.css">
Futhermore, when I change the script to:
<script src="bmi-calculator.js" async defer></script>
My js file continues to link up correctly. However, the above would suggest the following folder structure:
bmi-calculator > views > index.ejs
bmi-calculator > views > bmi-calculator.js
bmi-calculator > views > styles.css
Also, I'm not sure if this changes anything, but in my bmi-calculator.js file I have app.use(express.static('public')); included in as well and I am running the script by using nodemon bmi-calculator.js.
I've read about relative file paths, but this isn't working as I would expect! Why isn't this working as it should?

The express.static sets your context for static files to the public directory. So in your static files, the path to be defined is relative to that context. So you'll be able to access anything in the public directory without doing:
../public/abc.css

Related

Saving HTMLWidget with links to HTML dependencies instead of embedding them

I save my ggplotly object using saveWidget() function. If I do it with selfcontained=TRUE option, all HTML dependencies (javascript libraries and CSS styles) are saved inside the HTML file making it very big. If I use selfcontained=FALSE, those dependencies are saved in separate _file folder, and linked from the HTML file:
<script src="testA_files/htmlwidgets-1.5.3/htmlwidgets.js"></script>
<script src="testA_files/plotly-binding-4.9.2.1/plotly.js"></script>
<script src="testA_files/typedarray-0.1/typedarray.min.js"></script>
<script src="testA_files/jquery-3.5.1/jquery.min.js"></script>
<link href="testA_files/crosstalk-1.1.1/css/crosstalk.css" rel="stylesheet" />
<script src="testA_files/crosstalk-1.1.1/js/crosstalk.min.js"></script>
<link href="testA_files/plotly-htmlwidgets-css-1.52.2/plotly-htmlwidgets.css" rel="stylesheet" />
<script src="testA_files/plotly-main-1.52.2/plotly-latest.min.js"></script>
For jQuery, for example, I know I can use the code.jquery.com repository and replace my call with src="https://code.jquery.com/jquery-3.5.1.min.js". Is there similar public repositories for all other dependencies?
Of all the dependencies you list, plotly is probably the biggest. The latest plotly refers to this cdn:
https://cdn.plot.ly/plotly-basic-2.5.1.min.js
You can see this by look at the plots dependencies like so:
p <- ggplotly(p) %>% partial_bundle(local = FALSE)
p$dependencies

Unable to access local css file

Local css file called site.css is stored in Content folder in .net core project
Tried the following in layout
<link rel="stylesheet" href="#Url.Content("~/Content/site.css")" />
as well as
<link rel="stylesheet" href="~/Content/site.css" />
but didn't work.
In startup I have
app.UseStaticFiles();
Is there anything I am missing? I am unable to access the css in the browser. Gives error in dev tools.
Thank you
UseStaticFiles() only serves content from wwwroot folder. It should works, if you move your css file to wwwroot/Content/.
If you want to serve static content from Content folder, you should apply config like below:
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "Content")),
RequestPath = "/Content"
});

making jquery work in expressjs app

It is a noobish question.
I am writing an expressjs app. I am not able to get jquery or bootstrap working.
// app.js
app.use(express.static(__dirname + '/public'));
Also tried
app.use(__dirname + '/public');
or
app.use(path.join(__dirname + '/public'))
or
app.set(__dirname + '/public');
or
app.set(path.join(__dirname + '/public'))
// views/home.html
<head>
<script src="/js/jquery.min.js"></script>
</head>
<body>
<script>
$(function(){
alert('hello');
});
</script>
</body>
//public>js>jquery.min.js
It is not working. I am using express 4.
Template works fine other than jquery
I have a need for this to work offline while writing this app, so can not use CDN
DIRECTORY STRUCTURE
app.js
views
--layouts
--partials
public
--js
----jquery.min.js
Using 'hbs' package, handlebars for templating
Thanks
Looks to me like you shouldn't be able to reach your view with your current setup. When you say app.use(express.static(__dirname + '/public'));, you are saying that when you hit http://{hostname}:{portNumber}, you'll be served content from the the /public folder. You shouldn't be able to access any resources on your file system that do not fall within the /public folder. So maybe if you set up a folder structure like:
app.js
--public
----views
------layouts
------partials
------home.html
----js
------jquery.min.js
that I think would work (assuming that your view.html still points to jquery.js in the folder structure correctly).

express.js handlebars, get static files directory keep changes according to url

I am new to express. Basically my question is very simple.
I want to serve files like /css javascript from one public directory..
layout.hbs
<html>
<head>
<link href="css/style.css" rel="stylesheet" />
<script src="js/app.js"></script>
</head>
<body>
{{{body}}}
</body>
</html>
router.js --> I have three route that point to one index.hbs
router.get("/", function(req,res){
res.render("index.hbs");
})
router.get("/articles", function(req,res){
res.render("index.hbs");
})
router.get("/articles/show/:id", function(req,res){
res.render("index.hbs");
})
Now the problem is when I run this address:
curl "http://localhost:3000/"
http://localhost:3000/js/app
http://localhost:3000/css/style.css
----------------------------------------------
curl "http://localhost:3000/articles"
http://localhost:3000/articles/js/app
http://localhost:3000/articles/css/style.css
----------------------------------------------
curl "http://localhost:3000/show/1"
http://localhost:3000/show/1/js/app
http://localhost:3000/show/1/css/style.css
notice that the /css and /js path keep changing in accordance to UrlRequest. How to prevent this from happening?
I am using express and handlebars, and have already set my static file
app.use(express.static(path.join(__dirname, 'public');
You should specify the URLs to your JS and CSS as absolute URLs in your template: instead of css/style.css, use /css/style.css.
The first means "use this path relative to this page to browsers (and curl), the second "use this path relative to the host - which is what you want.

ASP.NET MVC 4 - Add Bundle from Controller?

I have some pages on my site that use certain CSS and JS resources - but they are the only page(s) to use that css or js file - so I don't want to include that CSS and JS reference in every page. Rather than modify each View to reference the CSS/JS it needs, I thought I could create a bundle in the Controller and add it to the Bundles that are already registered, and then it would be included in the bundle references, but this does not appear to be possible, or maybe I'm just going about it the wrong way.
In my Controller for a registration page for example, I thought I could write this:
Bundle styleBundle = new Bundle("~/bundles/registrationStyleBundle");
styleBundle.Include("~/Content/Themes/Default/registration.css");
BundleTable.Bundles.Add(styleBundle);
And then have this in my /Views/Shared/_Layout.cshtml:
#foreach(Bundle b in BundleTable.Bundles)
{
if (b is StyleBundle)
{
<link href="#BundleTable.Bundles.ResolveBundleUrl(b.Path)" rel="stylesheet" type="text/css" />
}
else if (b is ScriptBundle)
{
<script src="#BundleTable.Bundles.ResolveBundleUrl(b.Path)" type="text/javascript"></script>
}
}
But this does not work - the only bundles to get rendered to my page end up being the ones I specified in RegisterBundles (in /App_Start/BundleConfig.cs)
Any idea how to achieve this kind of "dynamic" or "runtime" bundling?
EDIT: Following Jasen's advice, what I ended up doing was taking the bundle creation/registration code out of the controller and adding it to RegisterBundles() in /App_Start/BundleConfig.cs. This way, the bundle is already available and the contents get minified. So:
bundles.Add(
new StyleBundle("~/bundles/registrationStyleBundle")
.Include("~/Content/Themes/default/registration.css"));
Then, in my view, I added this:
#section viewStyles{
<link href="#BundleTable.Bundles.ResolveBundleUrl("~/bundles/registrationStyleBundle")." rel="stylesheet" type="text/css" />
}
Then, in /Views/Shared/_Layout.cshtml, I added this:
#RenderSection("viewStyles", required: false)
Use the #section Scripts { } block to conditionally add bundles.
_Layout.cshtml
<body>
...
#RenderSection("Scripts", required: false)
</body>
FooView.cshtml
#section Scripts {
#Scripts.Render("~/bundles/foo")
}
KungFooView.cshtml
#section Scripts {
#Scripts.Render("~/bundles/kungfoo")
}
In my BundleConfig I typically group resources
bundles.Add(new ScriptBundle("~/bundles/Areas/Admin/js").Include(...);
bundles.Add(new StyleBundle("~/bundles/Areas/Admin/css").Include(...);
bundles.Add(new ScriptBundle("~/bundles/Areas/Home/js").Include(...);
bundles.Add(new StyleBundle("~/bundles/Areas/Home/css").Include(...);
Now I can either define multiple layout files or just selectively add bundles to the views.