AdonisJS single route won't open - node.js

I've made this project with AdonisJS, this is PlaceController file content:
async create({
view
}) {
return view.render('places.new')
}
and this is view file path: views/places/new.edge which is a simple static HTML file.
and the routes.js file content:
Route.get('admin/places/new', 'PlaceController.create')
when I enter the URL in browser, the URL just disappears.the problem solves by removing admin from route. Is there a bug in this framework or am I doing something wrong?

So problem solved. another Route caused this problem.
it was
Route.get('admin/places/:id', 'PlaceController.edit').middleware(['admin'])
Route.get('admin/places/new/', 'PlaceController.create').middleware(['admin'])
changed the order to:
Route.get('admin/places/new/', 'PlaceController.create').middleware(['admin'])
Route.get('admin/places/:id', 'PlaceController.edit').middleware(['admin'])
now it works.

Related

Nested route gives 404 not found on a fastify app with file based routing

I've created an app with fastify generate but nested routes are giving me 404. index.ts works a directory but anything else I add is not found. I have /a/b/index.ts which works but /a/b/c.ts which doesn't. But if i move c.ts to the parent dir, it's detected. And i have fastify.get('/c'... on c.ts. How can I fix this?
Fastify is about security, so you need to check the plugins' documentation you are using under the hood.
In your case, you must change the app.ts file like so:
void fastify.register(AutoLoad, {
dir: join(__dirname, 'routes'),
maxDepth: 4, // default is 2
options: opts
})
by doing this, fastify-autoload will search for nested folders deep to 4 levels.
Then you will be able to call: http://127.0.0.1:3000/a/b/c/c assuming you created src/routes/a/b/c/c.ts

Not found route not found in Sailsjs

Based on Sailsjs documentation, it is possible to add on the routes file a response with a syntax like this:
module.exports.routes = {
'/foo': {response: 'notFound'}
};
This searches for the notFound.js file in the /response directory, which I've in there.
So in my routes.js file I've added this as the end of the other routes in order to catch the not found routes, it is something like this:
module.exports.routes = {
'get /myroute/:myPara/': 'MyController.getAll',
'get /myroute/:myPara/': 'MyController.getOne',
'post /myroute/:myPara/': 'MyController.create',
'/*' : {response: 'notFound'}
};
I've realized that never finds the last route, I've also tried removing the slash ( doing '*' ), but nothing works.
Am I missing something? Thanks!
Sails already take care of the 404 notFound : here
Sails call res.notFound() and you can override the default notFound():
res.notFound() (like other userland response methods) can be overridden or modified. It runs the response method defined in /responses/notFound.js, which is bundled automatically in newly generated Sails apps. If a notFound.js response method does not exist in your app, Sails will implicitly use the default behavior.

How does the text! plugin use the baseUrl?

I'm having an issue getting the text! plugin to work in my requirejs site. It's always including lib/ in the request url, however all of the other files (not using text!) are being successfully found and loaded. Here is my directory structure:
WebContent/
|--backbone/
|--Bunch of folders and files
|--config/
|--config.js
|--lib/
|--jquery.js
|--text.js
|--require.js
|--index.html
my index.html file is:
<body>
<div id="siteLayoutContainer"></div>
<script data-main='config/config' src="lib/require.js"></script>
</body>
The config file is:
requirejs.config({
baseUrl: './',
paths: {
jquery: 'lib/jquery.js',
backbone: 'lib/backbone.js',
text: 'lib/text',
application: 'backbone/application'
},
text: {
env: 'xhr'
}
});
require(['application'], function(App) {
App.start();
});
I'm using the text! plugin like so:
define([
'jquery',
'text!backbone/templates/SomeTemplate.html'
], function(jQuery, NotFoundHtml) {
//Some code here
}
So, in the above script, the url being used for the template is:
http://localhost/lib/backbone/templates/SomeTemplate.html
and I am expecting it to be:
http://localhost/backbone/templates/SomeTemplate.html
I've tried the following:
Moving the text.js and require.js files out into the WebContent
directory but I get the same results. Also something interesting is
if I put a space after text! and then the path, that works fine and
doesn't include the lib/ directory in the request to get the html
template. However the optimizer includes the space and can't find the
template.
Not defining a baseUrl - same results.
Moved the
require config.js content into index.html in it's own script tag that runs
before the require.js script tag - same results.
Getting rid of the the text options in the config file
Oh yeah, forgot I've also tried 'text!../backbone/templates/SomeTemplate.html - same results
So I'm stuck and can't figure out what I'm missing. I'm obviously not understanding how the text! plugin uses the baseUrl or how it determines the url it's going to use to fetch the defined file.
After your edits to your question, it now contains all the information to diagnose the problem. As you guessed in one of your comments, the issue is indeed that this path:
backbone: 'lib/backbone.js',
is throwing off the resolution of the template you give to the text plugin. When the text plugin loads what you give to it, it takes the path after the ! symbol and treats it as if it were a module name, and it goes through the module resolution process. The way module resolution works is that it checks if there is a prefix that matches any of the keys in paths and will change the prefix with the value associated with the key, which gives the result you obtained. One way to fix the issue would be to add this to your paths configuration:
"backbone/templates": "backbone/templates"
This will make it so that anything you request under backbone/templates won't get messed up by the backbone path.
Note: it is preferable to avoid putting extensions in module names so you should remove it from the values you have for jQuery and Backbone.

Is there a way to give Ghost static pages access to the 'posts' variable that index.hbs is passed?

I'm looking to use Ghost to host both a blog and a static website, so the structure might look something like this:
/: the landing page (not the blog landing page, doesn't need access to posts)
/blog/: the blog landing page (needs access to posts that index.hbs typically has access to)
/page1/, etc: static pages which will use page.hbs or page-page1.hbs as needed
/blog-post-whatever/, etc: blog posts which will use post.hbs
The only thing I foresee being an issue is that only index.hbs (as far as I know) is passed the posts template variable (see code on GitHub here).
Before I go submit a pull request, it'd be nice to know whether:
Is there an existing way to get access to the posts variable in page.hbs?
If not, is it worthwhile to submit a pull request for this?
If yes, would we really want to send posts to all the pages? or should the pull request split apart page.hbs and only send it to those? or is there a better way to do this?
If you don't mind hacking the Ghost core files then here is how you can do it for the current version of Ghost (0.7.4). This hack will require recreation if upgrading to a new Ghost version.
First create the template files (that will not change if you upgrade):
Create the home page template in:
contents/themes/theme-name/home.hbs
home.hbs now supersedes index.hbs and will be rendered instead of it.
Also create the blog template file in:
contents/themes/theme-name/blog.hbs
The handlebars element that adds the paged posts is
{{> "loop"}}
so this should be in the blog.hbs file.
Again, the above files do not change if you upgrade to a new version of Ghost.
Now edit the following files in the core/server directory:
I have added a few lines before and after the sections of code that you need to add so that you can more easily find the location of where the new code needs to be added.
/core/server/routes/frontend.js:
Before:
indexRouter.route('/').get(frontend.index);
indexRouter.route('/' + routeKeywords.page + '/:page/').get(frontend.index);
After:
indexRouter.route('/').get(frontend.index);
indexRouter.route('/blog/').get(frontend.blog);
indexRouter.route('/' + routeKeywords.page + '/:page/').get(frontend.index);
This calls the Frontend controller that will render the blog page with the same data level as ‘index’ and ‘home’ (the default is load a the first page of the recent posts) thus enabling us to use the “loop” in the /blog/ page.
/core/server/controllers/frontend/index.js
Before:
frontendControllers = {
index: renderChannel('index'),
tag: renderChannel('tag'),
After:
frontendControllers = {
index: renderChannel('index'),
blog: renderChannel('blog'),
tag: renderChannel('tag'),
/core/server/controllers/frontend/channel-config.js
Before:
getConfig = function getConfig(name) {
var defaults = {
index: {
name: 'index',
route: '/',
frontPageTemplate: 'home'
},
tag: {
After:
getConfig = function getConfig(name) {
var defaults = {
index: {
name: 'index',
route: '/',
frontPageTemplate: 'home'
},
blog: {
name: 'blog',
route: '/blog/',
frontPageTemplate: 'blog'
},
tag: {
/core/server/controllers/frontend/channel-config.js
Before:
indexPattern = new RegExp('^\\/' + config.routeKeywords.page + '\\/'),
rssPattern = new RegExp('^\\/rss\\/'),
homePattern = new RegExp('^\\/$');
After:
indexPattern = new RegExp('^\\/' + config.routeKeywords.page + '\\/'),
rssPattern = new RegExp('^\\/rss\\/'),
blogPattern = new RegExp('^\\/blog\\/'),
homePattern = new RegExp('^\\/$');
and
Before:
if (indexPattern.test(res.locals.relativeUrl)) {
res.locals.context.push('index');
} else if (homePattern.test(res.locals.relativeUrl)) {
res.locals.context.push('home');
res.locals.context.push('index');
} else if (rssPattern.test(res.locals.relativeUrl)) {
res.locals.context.push('rss');
} else if (privatePattern.test(res.locals.relativeUrl)) {
res.locals.context.push('private');
After:
if (indexPattern.test(res.locals.relativeUrl)) {
res.locals.context.push('index');
} else if (homePattern.test(res.locals.relativeUrl)) {
res.locals.context.push('home');
res.locals.context.push('index');
} else if (blogPattern.test(res.locals.relativeUrl)) {
res.locals.context.push('blog');
} else if (rssPattern.test(res.locals.relativeUrl)) {
res.locals.context.push('rss');
} else if (privatePattern.test(res.locals.relativeUrl)) {
res.locals.context.push('private');
Restart the server and you should see the new /blog/ page come up with the list of recent blog posts
Here's a solution that I am currently using. I have an off-canvas nav that I want to use to display links to my latest posts. On the home page, this works great: I iterate over posts and render some links. On the other pages, I don't have the posts variable at my disposal.
My solution is this: wrap the pertinent post links on the homepage in a div with an id of "posts", then I make an ajax request for that specific content (using jQuery's load) and inject it into my nav on all other pages except the home page. Here's a link to jQuery's load docs.
Code:
index.hbs
<div id='posts'>
{{#foreach posts}}
<li>
{{{title}}}
</li>
{{/foreach}}
</div>
app.js
var $latest = $('#posts');
if ( location.pathname !== '/' )
$latest.load('/ #posts li');
There is no way currently (Ghost v0.5.8) to access posts within a page template.
I would think its probably not worth submitting the pull request. The Ghost devs seem to have their own plans for this and keep saying they'll get around to this functionality. Hopefully its soon because it is basic functionality.
The best way to go about this would be to hack the core yourself. Eventually the better way to do this would be with a hook. It looks like the Ghost API will eventually open up to the point where you can hook into core functions for plugins pretty much the same way Wordpress does it. https://github.com/TryGhost/Ghost/wiki/Apps-Getting-Started-for-Ghost-Devs
If this is a theme others will be using I would recommend working within the current limitations of Ghost. It's super annoying, I know, but in the long run its best for your users and your reputation.
If this is only for you, then I would hack the core to expose a list of posts or pages as locals in each route. If you're familiar with Express then this shouldn't be very difficult.
I think the way you've done it is pretty creative and there's a part of me that likes it but it really is a seriously ugly hack. If you find yourself hacking these kinds of solutions together a lot then Ghost might not be the tool you want to be using.
A better solution than briangonzalez one, is to get the posts-info from the RSS-feed, instead of the home page.
See this gist for how it can be done.
Now you can use the ghost-url-api, it's currently in beta but you can activate it in the administration (Settings > labs).
For example the {{#get}} helper can be use like this in a static page:
{{#get "posts" limit="3" include="author,tags"}}
{{#foreach posts}}
... call the loop
{{/foreach}}
{{/get}}
More informations :
http://themes.ghost.org/docs/ghost-url-api
As of Ghost v0.9.0, the Channels API is still under development. However, achieving this is much simpler now. It still requires modification of core files, but I'm planning on submitting some pull requests soon. Currently, one downside of the following method is that your sitemap-pages.xml will not contain the /blog/ URL.
Thanks to #Yuval's answer for kicking this off.
Create a template file for your index page with the path content/themes/theme-name/index.hbs. This can contain whatever you would like for your "static" homepage.
Create a template file for your blog index page with the path content/themes/theme-name/blog.hbs. This simply needs to contain:
{{> "loop"}}
In /core/server/controllers/frontend/channel-config.js:
Edit the var defaults object to include:
blog: {
name: 'blog',
route: '/blog/'
}

Angular Js Unexpected Token error Dynamic Routes

I'm getting getting several "unexpected token <" errors when I try to create a dynamic route.
Normal routes work fine. So if I set the following route:
.when('/user',{
templateUrl: 'views/user/new',
controller: "addUserCtrl"
})
The request goes to the server and gets caught by my express catch all route handler, then angular kicks in and requests express' api route, api/user, binds data, controller and template and I see a nice page. Everything works fine. No errors.
If I try to create a dynamic route or a route with more depth, I get the unexpected token error, when I try to request that route:
.when('/user/:id',{
templateUrl: 'views/user/new',
controller: "addUserCtrl"
})
For example, when I request /user/3, i get the error, and it the addUserCtrl is never called. Any ideas what could be causing this.
.when('/user/show,{
templateUrl: 'views/user/new',
controller: "addUserCtrl"
})
requesting /user/show will also throw the error. In the console the error shows up next to the request for all of angular files (angular.js, App.js, services.js, controllers.js, filters.js, directives.js) that I load in the body of my index.html.
I've noticed that this problem happens whenever I add more than one slash to the route. If I try /user/show, I can see the following requests:
/user/show
syntax errors for the below:
/user/js/App.js
/user/js/lib/angular/angular.js
/user/js/filters.js
/user/js/controllers.js'
/user/js/services.js
/user/js/directives.js
If I try /abc/def, I will get the following request:
/abc/def
syntax errors for the below:
/abc/js/App.js
/abc/js/lib/angular/angular.js
/abc/js/filters.js
/abc/js/controllers.js'
/abc/js/services.js
/abc/js/directives.js
I had the same issue and just as atentaten describes the problem was caused by relative paths to js-files. However, it has nothing to do with Express. It can just as well be caused by relative include paths from script tags in the head of a html file. So, to clarify, I changed my HTML from:
<script src="bower_components/angular/angular.js"></script>
to:
<script src="/bower_components/angular/angular.js"></script>
Apparently this is not really an angular issue, but an express issue.
The problem was that the beginning slashes were missing from my angular js includes in my index.jade:
script(src='js/lib/angular/angular.js')
script(src='js/App.js')
script(src='js/services.js')
script(src='js/controllers.js')
script(src='js/filters.js')
script(src='js/directives.js')
I changed them to this:
script(src='/js/lib/angular/angular.js')
script(src='/js/App.js')
script(src='/js/services.js')
script(src='/js/controllers.js')
script(src='/js/filters.js')
script(src='/js/directives.js')
And the errors went away. Although the js loaded without the starting slash, it was still causing a problem with express, creating the syntax error, which probably broke angular, but I'm not sure exactly why.
The templateUrl needs to be absolute else Express will choke if there is more than one slash/level of depth in the url:
.when('/user/show,{
templateUrl: '/views/user/new', /* add slash */
controller: "addUserCtrl"
})
This happens for ui-router dynamic route in angularJS application. I have the same error. solved by changing the path
<script src="app/components/services/campaign.services.js"></script>
to
<script src="/app/components/services/campaign.services.js"></script>
But in my case index.html file path is generated by gulp task gulp-inject so i changes the config of gulp-inject like
inject: { addRootSlash: true }
and it works for me :)

Resources