(Dojo 1.10) URL returned by dojoLoader seems wrong/inconsistent, how can I configure this correctly? - dojo

We recently updated our server with signed certificates and changed the base URL from https://servername/ to https://servername.domain.info/ . This has broken module loading in Dojo and I can't seem to correct it. The current config looks like this:
var dojoConfig = {
async: true,
packages: [
{
name: "js",
location: location.pathname.replace(/\/[^/]+$/, "") + 'Scripts'
},
{
name: "widgets",
location: location.pathname.replace(/\/[^/]+$/, "") + 'Scripts/widgets'
},
{
name: "dgrid",
location: location.pathname.replace(/\/[^/]+$/, "") + 'Scripts/3.14/dgrid'
},
{
name: "dijit",
location: location.pathname.replace(/\/[^/]+$/, "") + 'Scripts/3.14/dijit'
}
]
};
This used to work, and it still works on my dev machine when the root URL is just 'localhost'. Looking at the errors in the console it seems to be trying to find the modules at https://servername/ instead of https://servername.domain.info/ and I've tried everything I could find to point it in the right direction, including setting baseUrl: 'https://servername.domain.info' explicitly. Anything I've tried results in different URL strings, sometimes just the pathname and no base URL, sometimes pathname plus protocol with no domain info, etc. For reference, I also tried just adding the server URL to each location's URL string and I get the same error that seems to drop all but the first word from the server domain name.
I'm not sure what I'm doing wrong and I'm baffled by what dojoLoader decides to drop. I've read and reread the documentation but not much is said about how the base URL is calculated as far as I can find, just stuff on how to set baseUrl in the config to something.
edit: Per the comment below, I realize more info is needed. I am using Visual Studio 2015 and publishing to Windows Server 2012 R2 running IIS (v7 iirc). It does look like maybe Visual Studio is messing with the URL somehow, Dojo is not to blame. I was able to work around it by editing the file directly on the server and setting a location URL for every package (and their dependencies). I'd still like to know why it's happening and how I can set it up correctly.
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title - ProjectName</title>
<link rel="stylesheet" href="~/Content/font-awesome.min.css" />
<link rel="stylesheet" href="~/Content/jquery-ui-1.10.3.custom.css" />
<link rel="stylesheet" href="~/Scripts/3.14/esri/css/esri.css" />
<link rel="stylesheet" href="~/Content/bootstrap-datetimepicker.min.css" />
#Scripts.Render("~/bundles/modernizr")
<link rel="stylesheet" href="~/Content/map.css" />
#Styles.Render("~/Content/css")
</head>

Related

REST api doesn't seem to work in grails with vue profile

I was following this guide about creating a grails+vue web and created the following "Person" class:
package kpm2
import grails.rest.*
#Resource(uri = '/person', formats = ["json", "xml"])
class Person {
String name
int age
static constraints = {
name blank: false
}
}
#Resource should make it possible to perform REST operations, such as (as shown in the guide):
$ curl -X "GET" "http://localhost:8080/vehicle"
HTTP/1.1 200
X-Application-Context: application:development
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Fri, 06 Jan 2017 19:28:49 GMT
Connection: close
[{"id":1,"driver":{"id":1},"make":{"id":1},"model":{"id":1},"name":"Pickup"},
{"id":2,"driver":{"id":1},"make":{"id":1},"model":{"id":2},"name":"Economy"},
{"id":3,"driver":{"id":2},"make":{"id":2},"model":{"id":3},"name":"Minivan"}]
(in the guide they make a vehicle garage with other interconnected classes, but for simplicity and testing purposes I just created a simple Person class. I also followed the guide completely before, but it also didnt work)
But it doesnt work for me. I get this :
$ curl -X "GET" "http://localhost:8080/#/person"
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="/favicon.ico">
<title>Welcome to Grails & Vue</title>
<link href="/js/app.js" rel="preload" as="script"><link href="/js/chunk-vendors.js" rel="preload" as="script"></head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
<script type="text/javascript" src="/js/chunk-vendors.js"></script><script type="text/javascript" src="/js/app.js"></script></body>
</html>
http://localhost:8080/#/person doesnt seem to exist, even though i specified it in #Resource(uri = "/person")
I dont know what the problem is. I even did some integration tests to see if a Person can be added to the database and they check out.
Following further the guide, the "persons" I added to the database in BootStrap.groovy are not shown in the table that should contain them.
Also the official guide for REST in grails doesn't work in the same way.
I created a new grails app with grails create-app -profile=vue with grails version 5.18
I found that the problem was because of the ports in the docker container configuration.
It worked with this container build:
docker run -p 8080:8080 -p 8081:3000 -v $(pwd):/app <image>

vue project not working when change the base url in index.html file to my website url

This is my index.html file
when I change the base url to my website domain "https://new.weservio.com/" this error appears
Uncaught TypeError: Failed to resolve module specifier "vue". Relative references must start with either "/", "./", or "../". when I try to import vue according to this solution https://microeducate.tech/importing-a-package-in-es6-failed-to-resolve-module-specifier-vue/ .other modules can't be resolved too.
<html lang='en'>
<head>
<meta charset='UTF-8' />
<link href='images/logo.png' rel='icon' />
<meta content='width=device-width, initial-scale=1.0' name='viewport' />
<link href='https://fonts.googleapis.com' rel='preconnect'>
<link crossorigin href='https://fonts.gstatic.com' rel='preconnect'>
<link href='https://fonts.googleapis.com/css2?family=Poppins:wght#300;400;500;700;900&family=Tajawal:wght#300;400;500;700;900&display=swap'
rel='stylesheet'>
<link href=' https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.0-beta.14/vue.esm-browser.js' >
<title></title>
<!--
EDIT THE FOLLOWING CODE INSIDE THE BASE TAG
'http://localhost:3000/' ==> 'REPLACE IT WITH YOUR BASE URL'
-->
<base href='https://new.weservio.com/'>
</head>
<body class='rtl:font-tajawal font-poppins overflow-x-hidden'>
<div id='app'></div>
notice: when I leave the url as "http://localhost:3000/" and run the project locally with npm run dev .The website is working fine.
notice: This site was working correctly before on same domain url ,but I was tring to use ftp-simple extention on vs code to load automaticllay after save to server from my working directory .then the website is not working anymore .I don't know if this related.

How can I add my ExtWebComponent to a JSP?

I would like to add my web components to my JSP. How do I wire up my ExtWebComponents to do this?
My server side runs in a Servlet Container.
I have a project example showing how to do just that. The client side is the ExtWebComponents and a server side is Java.
Project Notes
Maven multi-module project
Java servlet container on the backend
The client is an ExtWebComponents project, using the pom.xml only to import it easily as a module into an IDE. And to fire off npm builds.
Example Project
JSP Example
<!DOCTYPE HTML>
<html manifest="">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=10, user-scalable=yes">
<title>Sandbox Project</title>
<link rel="icon" type="image/x-icon" href="resources/favicon.ico">
<script src="webcomponents-bundle.js"></script>
<link href="ext/ext.css" rel="stylesheet">
</head>
<body>
Testing
<my-sandbox-view></my-sandbox-view>
<%
out.write("<h2>Test jsp<h2>");
%>
<!-- The webpacked resource bundle is imported here -->
<script type="text/javascript" src="ext/ext.js"></script><script type="text/javascript" src="app.js"></script></body>
</html>
Example Source
Resources from Client to Server
You have to tell webpack to copy the resources to your web app directory so they can be used in your Java project. For example this is how it could be done using a custom plugin, and then using webpack --watch.
// This causes infinite loop, so I can't use this plugin.
// new CopyWebpackPlugin([{
// from: __dirname + '/build/',
// to: __dirname + '/../sandbox-server/target/test1'
// }]),
// Inline custom plugin - will copy to the target web app folder
// 1. Run npm install fs-extra
// 2. Fix the path, so that it copies to the server's build webapp folder
{
apply: (compiler) => {
compiler.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) => {
// Debugging
console.log("########-------------->>>>> Finished Ext JS Compile <<<<<------------#######");
let source = __dirname + '/build/';
// TODO Set the path to your webapp build
let destination = __dirname + '/../sandbox-server/target/sandbox';
let options = {
overwrite: true
};
fs.copy(source, destination, options, err => {
if (err) return console.error(err)
console.log('Copy build success!');
})
});
}
}
Example Source

Using (NEW) Famo.us Engine with RequireJS and EJS Templates

Before Famo.us completely changed their architecture I was developing some Apps using Famo.us, RequireJS, EJS Templates, Node and some other stuff.
But now when I come to replace the old Famo.us architecture with the new Famo.us 'Engine' I am getting errors - which tells me the architecture is wrong for the new approach - so wondered if you guys can help me.
Background
Server is Node.js, Express 4 and some other stuff
Client will be Famo.us, EJS Templates and some other stuff
The current approach is that the '/' Router calls an 'ejs' template.
index.ejs:
<!DOCTYPE HTML>
<html>
<head>
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0, maximum-scale=1.0, minimal-ui" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<link rel="stylesheet" type="text/css" href="/css/famous.css" />
<link rel="stylesheet" type="text/css" href="/css/style.css" />
</head>
<body>
<script data-main="/js/webmain.js" src="/js/vendor/requirejs/require.js"></script>
</body>
</html>
This worked fine with old Famo.us architecture...and would call the webmain.js script using RequireJS.
webmain.js:
/* globals require */
require.config({
baseUrl: "js",
nodeRequire: require,
paths: {
"famous": "vendor/famous",
"famous-flex": "vendor/famous-flex/src",
json2: "vendor/json2",
"requirejs": "vendor/requirejs/require",
"socketcluster": "vendor/socketcluster",
"ua-parser" : "vendor/ua-parser.min",
"uuid": "vendor/uuid"
}
});
require(["platform"]);
The 'platform.js' script would contain the following:
define('platform', function(require, exports, module) {
'use strict';
var Engine = require("famous/core/Engine");
var contentContext = Engine.createContext();
var Widget = require('app/widgets/DefaultWidget');
var mainView = new Widget();
var contextSize = [undefined, undefined];
contentContext.setPerspective(1);
Engine.nextTick(function() {
contextSize = contentContext.getSize();
mainView.setOptions({size: [contextSize[0], contextSize[1]]});
contentContext.add(mainView);
});
contentContext.on('resize', function(e) {
contextSize = contentContext.getSize();
if (mainView) mainView.setOptions({size: [contextSize[0]*1, contextSize[1]*1]});
}.bind(this));
});
But the new version of Famo.us will not work using this approach and I wanted to ask your thoughts as to why, or if there was another way they have not mentioned?
I have updated the Famou.us source code in 'vendor/famous' to use the 'Famo.us Engine' code from github. If I replace the old Famo.us code in the 'platform.js' script with new Famo.us code - like this:
define('platform', function(require, exports, module) {
'use strict';
var FamousEngine = require('famous/core/FamousEngine');
var DOMElement = require('famous/dom-renderables/DOMElement');
FamousEngine.init();
var scene = FamousEngine.createScene();
var node = scene.addChild();
var domEl = new DOMElement(node, {
content: 'Hello World',
properties: {
fontFamily: 'Arial'
}
});
});
I get the following errors:
Uncaught Error: Module name "Clock" has not been loaded yet for context: _. Use require([]) require.js:8
Uncaught Error: Module name "../utilities/CallbackStore" has not been loaded yet for context: _. Use require([]) require.js:8
Uncaught TypeError: Cannot read property 'init' of undefined platform.js:28
I guess I am trying to understand, when the RequireJS skeleton is pretty much the same, why it doesn't work? Why Famo.us is undefined, and why the new Famo.us architecture can break so much - and what the 'new' way of integrating famo.us would be?
I have asked questions on their 'slack' IRC but it doesn't seem to be a way to get answers and a really poor 'help'.
Any help would be greatly appreciated as I am really stuck from moving forward at the moment.
Thanks again.
Famo.us version 0.3.5 and earlier used RequireJS using AMD.
The new version 0.5.0+ uses the node.js flavor of CommonJS and uses Browserify to build a bundle of your javascript application for the browser.
The following from an Answer in this question sums it up. More about their similarities and differences in the answers.
RequireJS implements the AMD API (source).
CommonJS is a way of defining modules with the help of an exports object, that defines the module contents.

Handlebars with Express: different html head for different pages

I am using Handlebars in an Express Node.js app. My layout.html file includes a <head> section. How can I make the <head> section different for different pages? (So that I can, for example, reference a JavaScript file in only one page, and vary the <title> for each page.)
layout.html looks like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src='/public/ajsfile.js'></script>
<link type='text/css' href="/public/style.css" rel="stylesheet">
</head>
<body>
{{{body}}}
</body>
</html>
(I am imagining varying the <head> content with something analogous to {{{body}}} in the above, but with {{{head}}}.)
This is a great question and, in my mind, a glaring weakness in Express's view model. Fortunately, there is a solution: use Handlebars block helpers. Here's the helper I use for this purpose:
helpers: {
section: function(name, options){
if(!this._sections) this._sections = {};
this._sections[name] = options.fn(this);
return null;
}
}
Then, in your layout, you can do the following:
<head>
{{{_sections.head}}}
</head>
<body>
{{{body}}}
</body>
And in your view:
{{#section 'head'}}
<!-- stuff that goes in head...example: -->
<meta name="robots" content="noindex">
{{/section}}
<h1>Body Blah Blah</h1>
<p>This goes in page body.</p>
You can make the follow:
layout.hbs
<head>
<title>{{title}}</title>
{{#each css}}
<link rel="stylesheet" href="/css/{{this}}" />
{{/each}}
</head>
app.js
router.get('/', function (req, res, next) {
res.render('index', { title: 'MyApp', css: ['style.css', 'custom.css'] });
});
Result:
<head>
<title>MyApp</title>
<link rel="stylesheet" href="/css/style.css" />
<link rel="stylesheet" href="/css/custom.css" />
</head>
Maybe, you could use this implementation of the section helper: https://github.com/cyberxander90/express-handlebars-sections
You just need to install it and enable it:
yarn add express-handlebars-sections # or npm
const expressHandlebarsSections = require('express-handlebars-sections');
app.engine('handlebars', expressHandlebars({
section: expressHandlebarsSections()
}));
Hope it helps.
Younes
I know this is an older question but I wanted to point out a clear alternative solution to what you are asking (I'm not entirely sure why nobody else spoke about it over the years). You actually had the answer you were looking for when you bring up placing things in {{{head}}} like you do for {{{body}}}, but I guess you needed help understanding how to make it work.
It seems possible that most of the answers on this page are geared towards Node "Sections" because you speak about the different sections of HTML you've included in your layout file that you want to change. The "Sections" everyone is speaking about in this thread seems to be a technique, although I may be mistaken, originating from Microsoft's Razor Template Engine. More info: https://mobile.codeguru.com/columns/dotnet/using-sections-and-partials-to-manage-razor-views.htm
Anyway Sections work for your question, and so could "Partials" theoretically (although it may not actually be the best option for this). More info on Partials:
https://www.npmjs.com/package/express-partial
However, you simply asked for a way to alter the HTML tag content of your template layout in Handlebars, and assuming we are talking about HTML head tags, all you need to do is replace the content you have in your template layout HTML head tags with one of these (I use 3 brackets because it seems HTML would be included and you don't want it escaped):
<head>
{{{headContent}}}
</head>
Then you just dynamically pass whatever data you want through the route you create in your app.js file to "get" the page like so (I am mostly taking the code #Fabricio already provided so I didn't have to rewrite this):
router.get('/', function (req, res) {
res.render( 'index', { headContent:'I DID IT!' });
});
Now when you load your page, "I DID IT!" will be where you expect it to show up.