Internationalize nodejs jade templates - node.js

I'm trying to internationalize my nodejs express app using i18n-2 module. All is working but I have a question. Is there a way to translate string from my jade templates. Imagine I have 100 strings in my website. Do I have to send 100 translations to the template through the res.render invocation?
res.render('profile', {
title: 'My cool title',
user: req.user,
hello1: req.i18n.__("hello1"),
hello2: req.i18n.__("hello2"),
hello3: req.i18n.__("hello3"),
...
helloN: req.i18n.__("helloN")
});
Is there another way to do this? Somethin like the next code:
res.render('profile', {
title: 'My cool title',
user: req.user,
i18n: req.i18n // to be used inside jade
});

i18n-2 already registers helper objects in your Express locals, which are accessible form your Jade template. These helper methods are registered automatically: "__", "__n", "getLocale", and "isPreferredLocale". Without any additional configuration, should be able to do the following in your Jade template:
a(href="/") #{ __('home') }

Related

Return the value from a mongoose find

I'm trying to render a template when i check the link for view a profile (for example going to http://localhost:3000/user/testuser`), all ok going to the routes but the values don't being showed on the page. This is my code:
Account.find({ username: req.params.username }, function(err, userWatch){
res.render('account/profile',{
title : userWatch.username,
user : req.user,
watchUser : userWatch,
});
You are using Account.find() that returns the array of objects. You should use Account.findOne() to fetch data, if you want either one or none objects.

Display data in Jade with Mongoose

I've been trying to grab my data that's stored in mongodb and display it with a simple Jade template. I'm kinda new to this and I'm totally lost at this point.
Here's my output when I render my collection on /yfirlit
The express router for /yfirlit looks like this
apiRouter.get('/yfirlit', function(req, res){
apiUser.find(function(err, users) {
if(err) res.send(err);
res.render('yfirlit', {title: 'Yfirlit', users: users});
});
});
My simple Jade Template
html
head
title!= title
body
div #{users}
p
| API
When I run the test the whole mongodb collection is displayed on the site. What I'm looking for is to be able to display only a portion of the documents in the collections. For example: I tried to display only the name property in the Jade template but was unable to get it right.
html
head
title!= title
body
div #{users.name}
p
| API
Any help would be greatly appreciated, I'm so lost and I would love to be able to render out only the properties that I wanted instead of the whole thing like in the picture.
Cheers!
As Sgnl said, within the route you'll need to render the Jade view and include the data just like you have, but by using res.render:
apiRouter.get('/yfirlit', function(req, res){
apiUser.find(function(err, users) {
if (err) return next(err);
res.render('index', {
title: 'yfirlit',
users: users
})
});
});
...And I think you'll also need a loop to display the data from within your Jade view, because it contains multiple values:
if users
each user in users
div #{user.name}

How to retrieve model data for use inside of another model?

I'm working with an Ember app that ties into a Rails backend through a Sails.js API, and ran into an issue I can't find any similar examples for.
My Messages model has a sender_id column, which corresponds with the id column in my Users model. There is also a Profile model (belongs to User through user_id) that contains the username column, which is what I'd like to be able to access through the Messages model as 'senderName' (i.e., message.senderName). My models and routes are all hooked up, so I have access to all the data I need and everything displays correctly in the browser aside from my senderName function.
The plan was to look up the Profile object through its user_id (using sender_id) inside of Messages, then pull the username field from there. I've been able to receive Promises back from my Profile query, but from there I'm not sure how/if I can access the actual username field. Is there a way to do this, or am I trying to fit a square peg into a round hole?
I also tried accessing username by looking up the User object first (this.store.find('user'), etc.) and using my Rails associations for user.profile.username, but that didn't work either.
Models:
App.Message = DS.Model.extend({
sender_id : DS.attr('number'),
content : DS.attr('string'),
senderName: function() {
var id = this.get('sender_id');
var profile = this.store.find('profile', {user_id: id}).then(function() {
console.log(profile);
// What next? profile.username doesn't work
})
}.property('sender_id')
});
App.Profile = DS.Model.extend({
user: DS.belongsTo('user', { async: true }),
username : DS.attr('string'),
user_id : DS.attr('number')
});
App.User = DS.Model.extend({
profile: DS.belongsTo('profile', { async: true }),
email: DS.attr('string'),
name: DS.attr('string')
});
Template:
<script type="text/x-handlebars" data-template-name="messages/index">
<div class="small-12 column">
{{#each message in model}}
<p>From: {{message.senderName}}</p>
<p>Content: {{message.content}}</p>
{{/each}}
</div>
</script>
Here's an example of the promises I'm receiving back in the browser console:
Promise {_id: 93, _label: undefined, _state: undefined, _result: undefined, _subscribers: Array[0]…}
Thanks for your help!
If I'm getting the question correct, you are having trouble accessing the fields in the model? If so, try:
profile.get('username')
You're really overcomplicating this :-)
Message also belongs to sender, why did you define sender_id as a number?
If you delete senderName and change the sender_id property to:
sender: DS.belongsTo('user', { async: true }),
You can use message.get('sender.profile.username'). I think your main issue here is that you're trying to do an async operation in the computed property, which is a no-no. You can alias the senderName if you like, via senderName: Ember.computed.alias('sender.profile.username') if you end up using it a lot.

NodeJS: Dynamic form

How do I create a dynamic form with NodeJS, Express and Mongoose?
Right now my contents are hardcoded for the sake of the question.
This is how my page creation looks like:
app.post('/create', function(req, res) {
var page;
var b = req.body;
page = new Page({
title: b.title,
url: '/' + Func.stringToUrlSlug(b.title) + '/',
headline: b.headline,
contents: [{
body: b.content1_body,
class: 'CLASS1'
},{
body: b.content2_body,
class: 'CLASS2'
},{
body: b.content3_body,
class: 'CLASS3'
}],
border: b.border,
target: b.target,
hidden: b.hidden,
externUrl: b.externUrl,
order: 700
});
page.save(function(err, page) {
if (!err)
res.send(page);
else
res.send(err);
});
});
And my Jade frontend creation:
....
div
label Content
textarea(name='content1_body')
div
label Content
textarea(name='content2_body')
div
label Content
textarea(name='content3_body')
....
And my mongoose schema contents are of Array type.
My question here is: How can I have these documents to being dynamic in my route depending on how many extra content fields I add?
Do I need to push these extra fields inside my page array somehow?
Say if something is unclear. Thanks in advance.
There are multiple approaches how to implement "dynamic forms". The easiest would be using the single page application features that you do not load the page at all when you move between the forms. The result could be stored in document.localStorage and when the user has finished send the results to server.
When you do not use the client side possibilities, you have to store the each form results in temporary database "table/document", also you have to keep track on what form the user is. When user reaches end, insert all the data from previous steps to table/document.
Alright after aaaaa lot of trying I solved it myself.
I ended up creating my form elements that should be dynamic this way:
div
label Class
input(name='content[1][class]')
label Content
textarea(name='content[1][body]')
div
label Class
input(name='content[2][class]')
label Content
textarea(name='content[2][body]')
....
That way I could reach the content fields, wether it was the class or the body field. And I ended up pushing these into my page array:
b.content.forEach(function(item) {
page.contents.push({ class: item.class, body: item.body });
});
I end up adding more form fields with jQuery.
If you enable the extended parsing of the Express body-parser
var app = express();
...
app.use(bodyParser.urlencoded({ extended: true }));
Express will use the qs library. This library has automated parsing for converting query parameters to array or objects.
Example (source: qs docs)
var withIndexes = qs.parse('a[1]=c&a[0]=b');
assert.deepEqual(withIndexes, { a: ['b', 'c'] });
After correctly parsing your inputs, it's a matter of sending this info to mongoose.

Variables not showing content on Jade template

I am learning Node.js using a book. There was an example that as a learning experience I converted from what it was to a SQL version of it.
This single page is only intended to display user information. I load the user information on a middleware then pass it to the Jade template. Everything working up to this point.
When I want to render the template below, wherever I user content from the user object, it renders nothing.
h1= user.Name
h2 Bio
p= user.Bio
form(action="/users/" + encodeURIComponent(user.User), method="POST")
input(name="_method", type="hidden", value="DELETE")
input(type="submit", value="Delete")
To check if the object was without content, I added this 2 lines on the front
-console.log ( 'Inside Jade' )
-console.log ( user )
and the result in the console is:
Inside Jade
[ { Name: 'Jennifer Lopes',
User: 'jenny',
Password: 'asd',
Bio: 'Actress and singer' } ]
So this tells me that the information is there, but is not being rendered.
The code used to render the template is:
app.get ('/users/:name', loadUser, function ( req, res, next ) {
res.render ( 'users/profile', { title: 'User profile', user: req.user });
});
Can you please help me to understand what am I doing wrong? Thanks in advance.
A little hard to tell without seeing all your code, but per the output of your console it looks like user is actually an array of objects based upon the brackets, if you change your jade template to output something like user[0].Name does it give you your expected values?

Resources