Question on using mustache partials with couchapp and evently - couchdb

I have been evaluating couchdb for a project and am using couchapp to develop the prototype. So far all I can only say it that it is an awesome tool. I have however run across a problem (which is surely caused by ignorance of the tool) that I cannot seem to get mustache partials to work and the reason for that I believe is that evently can't find the definitions of the partials I am using.
example out of a message queue evently template (evently/queues/_change/mustache.html)
<div class="queue">{{>queue_info}}</div>
...
and I have a queue_info.html with something like
<h2>{{name}}</h2>
where do I place the "queue_info.html" so that evently would find it and insert it properly? If I put it in the same directory as mustache.html it doesn't work.
Best regards,
Vukasin

ok i have figured this out so I am writing to help anyone who might run into the same issue in the future:
if you have data:
{ "queue_info": { "name": "queuename", "owner": "user1" }, "messages": [...] }
and you want to render the "queue_info" part using a partial you will need to create the partial called "queue_info" (it is important that the partial is called the same as the field) and place it in a file "queue_info.html" located in the subdirectory "partials" of the evently directory you are working in).
so we have evently/queues/_change/mustache.html
<div class="queue">
{{>queue_info}}
{{#messages}}
<div class="message">
author: {{author}}
message: {{text}}
</div>
{{/messages}}
</div>
and evently/queues/_change/partials/queue_info.html
Queue: {{name}}
Owner: {{owner}}
when we push this couchapp to the server we get a result which cascades as expected.
Hope this helps someone :-)

Related

How to invoke groovy templates in the Jenkins email-ext plugin

I want to use the Groovy scripting feature in the email-ext plugin for Jenkins, but I'm new to this and there seems to be a lot of assumed knowledge. Like how one goes about invoking one of these templates in the first place.
The answer to this is probably quite obvious, but I'm feeling a bit lost and would appreciate being pointed in the right direction.
This example is based on the official email-ext documentation, which unfortunately does not provide any concrete examples on how to use the $SCRIPT line of code in Pipeline. If you wish to use an HTML template as the body for your email then you need to:
Create a template file called my-email.template or whatever you like - you can find some template examples here
<body>
<h3>Using "build" environment variables:</h3>
<p>
<%= build.fullDisplayName %>
</p>
<h3>List of all available "build" environment variables:</h3>
<div>
<% println build.properties.collect{it}.join('<br />') %>
</div>
</body>
Have your Jenkins administrator place the my-email.template file inside $JENKINS_HOME\email-templates directory on Jenkins machine - make sure that user jenkins owns this directory as well as its content (i.e. template files)
In Pipeline load my-email.template as body content:
stage('Send email') {
def mailRecipients = "jenkins-user#example.com"
def jobName = currentBuild.fullDisplayName
emailext body: '''${SCRIPT, template="my-email.template"}''',
subject: "[Jenkins] ${jobName}",
to: "${mailRecipients}",
replyTo: "${mailRecipients}",
recipientProviders: [[$class: 'CulpritsRecipientProvider']]
}
It's a pretty old thread but here's what I did to make use of the built in template do this
stage('Send Email')
{
steps
{
emailext body: '${JELLY_SCRIPT,template="html"}',recipientProviders: [[$class: 'DevelopersRecipientProvider'], [$class: 'RequesterRecipientProvider']], subject: 'Build Successful ${JOB_NAME}',mimeType: 'text/html'
}
}
The Plugin Documentation states that the html Jelly script is built in so you can easily make use of it.
https://plugins.jenkins.io/email-ext/
The answer is, in fact, blatantly obvious, and included in the email-ext documentation:
${SCRIPT, template="groovy-text.template"}

fixed urls on polymer

I'm working with polymer and I'm testing all in my local environment and all is working as expected, but the problem is when I'll move it into production, where the url shouldn't be the same as in my local. In node.js I can set it via the config.json file and catch it with app.get('config') or something like that, but in polymer I cant get it, and the only chance I have is to create another endpoint with all the config.json config file, but, and here is the best part, I should hardcode this url in polymer!! (so annoying). There is some way or library or component or something that I'm missing ?
Thanks in advance guys! StackOverflow and the users helped my a lot!
UPDATE
The thing is that I'm using custom elements (because I had handlebars too and there is a little problem with the {{}}) so, in the custom elements that I created I have this (for example in the core-ajax call):
<core-ajax id="login" auto="false" method="POST" contentType="application/json" url="/app/middle/login" ....></core-ajax>
as you can see the url is a little bit hardcoded, I want to use something like this (this is what I have on the node.js endpoint application):
router.post(endpoint.login, function (req, res) {
and I want to got something like that over polymer
<core-ajax id="login" auto="false" method="POST" contentType="application/json" url="{{login}}" ... ></core-ajax>
<script>
Polymer('log-form', {
login: endpoint.login,
ready: function () {
....
})
});
</script>
I'ts more clear now? I'm not so strong on english language.
Thanks Guys, for all!

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/'
}

How do I render partials with jade without express.js?

Only info I found was this:
http://forrst.com/posts/Node_js_Jade_Import_Jade_File-CZW
I replicated the suggested folder structure (views/partials) But it didn't work, as soon as I put
!=partial('header', {})
!=partial('menu', {})
into index.jade, I get a blank screen, the error message I receive from jade is:
ReferenceError: ./views/index.jade:3
1. 'p index'
2. ''
3. '!=partial(\'header', {})'
partial is not defined
I'd be very grateful for any help ! (I strongly prefer not to use express.js)
Jade has a command called include. Just use
include _form
given that the filename of the partial is *_form.jade*, and is in the same directory
As of August 2012 (possibly earlier) Partials have been removed from Express.
A lot of tutorials are now out of date. It seems that you can replicate much of the partial functionality with include.
Eg.
movies.jade
div(id='movies')
- each movie in movies
include movie
movie.jade
h2= movie.title
.description= movie.description
HTH
With the latest node/express I get the following movies.jade template to call partials:
div(id='movies')
- each movie in movies
!=partial('movie', movie)
where I have movie.jade in the views directory alongside movies.jade.
movies.jade is called from app.js with:
res.render('movies', { movies: [{ title: 'Jaws' }, { title: 'Un Chien Andalou' }] });
I think partial rendering is done in express, so you will have to snag that code or write your own.
I have my own helper class for jade rendering with partials that you can use or get some ideas from here, (it's using Joose and Cactus)

Problem listing documents in a CouchApp

I am in a bit of trouble as I am not able to find resources and/or tutorials that give me enough knowledge how to do this properly:
I am building a Couchapp uppon a contact database. For this I need to have a unordered list of the contacts(only the names) on the landing page. After examining this now for quite a time and examining the http://kansojs.org framework, I think I might have to ask here at Stackoverflow how this is done properly...
Here is what I ended up with (not working):
I started to setup a view (file 'views/contactslist/map.js ):
function(doc) {
if (doc.displayName) {
emit(doc.displayName, {displayname: doc.displayName});
}
};
... which basically gives me back this response:
{"total_rows":606,"offset":0,"rows":[
{{"id":"478d86edbbd94bbe627f3ebda309db7c","key":"Al Yankovic","value":{"displayname":"Al Yankovic"}},
{"id":"478d86edbbd94bbe627f3ebda30bb5cb","key":"Al-Qaeda","value":{"displayname":"Al-Qaeda"}}
]}
Afterwards, I created a new directory in the evently directory, 'contacts' and created the files "mustache.html", "data.js" and "query.json":
mustache.html:
<ul>
{{#contacts}}
<li>
<div class="name">
{{displayname}}
</div>
<div style="clear:left;"></div>
</li>
{{/contacts}}
</ul>
data.js:
function(data) {
$.log(data)
var p;
return {contacts : data.rows};
};
query.json:
{
"view" : "contactslist",
"descending" : "true"
}
Then I added
and
$("#contacts").evently("contacts", app);
to the index.html in the _attachments directory.
Watching the console in Firebug I can not see any Request/Response from CouchDB returning my vie's results, so I think it is not even requested. Where did I take the wrong turn?
data.js, query.json and mustache.html need to be in evently/contacts/_init/
_init means that this gets executed on widget initialization.
Going over this Tutorial helped a lot.

Resources