wordpress json api phonegap handlebars custom_fields - wordpress

I am using the "json-API" plugin for wordpress and I am trying to call that info into a phonegap app.
I am following a post on http://alexbachuk.com/wordpress-and-phonegap-part3/ and I am trying to find out how to call custom_fields in my content.
I have included the custom field like so:
'http://www.example.com/?json=get_recent_posts&custom_fields=store-icon' in the ajax request.
the ajax request looks like this:
product: function(){
function getProducts() {
var dfd = $.Deferred();
$.ajax({
url: 'http://delectable.site40.net/blog/?json=get_recent_posts&custom_fields=store-icon',
type: 'GET',
dataType: 'json',
success: function(data){
var source = $("#product-template").html();
var template = Handlebars.compile(source);
var blogData = template(data);
$('#product-data').html(blogData);
$('#product-data').trigger('create');
dfd.resolve(data);
},
error: function(data){
console.log(data);
}
});
return dfd.promise();
};
getProducts().then(function(data){
$('#all-posts').on('click','li', function(e){
localStorage.setItem('postData', JSON.stringify(data.posts[$(this).index()]));
});
});
}
and the template currently looks like this:
<script id="product-template" type="text/x-handlebars-template">
<ul data-role="listview" data-icon="false" class="mainContent" data-theme="a" id="all-posts">
{{#each posts}}
<li class="center productss"><p class="photo circle center" style="margin-left: 31%;"><img src="{{thumbnail}}" width="85" height="57" /></ br><a data-ajax="false" data-transition="slide" href="single.html?{{#index}}"><h3 class="main_product">{{title}}</h3></a></ br><h5 class="left">R4200-00</h5><h5 class="right"><img src="{{custom_fields[0].url}}" width="150" height="20" /></h5></p></li>
{{/each}}
</ul>
</script>
how would I go about inserting that into my html. The alexbachuk.com post uses handlebars to parse the json so the post title is output as {{title}} and thumbnail as {{thumbnail}}. Is there a way to output custom_fields in a similar manner?

Yes there is.
Use:
{{custom_fields.fieldname}}

Related

Is there a way to access Iron Router parameter from template in Meteor

I have a route that has a parameter in it and I need to access it from many different templates. Below is one example of the route, there are several routes that are very similar just after the _occasionnId parameter it changes:
For example:
Route 1: /occasions/:_occasionId/cards/
Router 2: /occasions/:_occasionId/tables/
Here is my full code for each route, the only thing that really changes is the route path and the template.
Router.route('/occasions/:_occasionId/cards/', {
template: 'cards',
data: function(){
//var currentoccasion = this.params._occasionId;
//console.log(currentoccasion);
},subscriptions : function(){
Meteor.subscribe('cards');
Meteor.subscribe('tables');
}
});
I need to get the _occasionId parameter into a template that has navigation which goes in on all of these pages. My goal is that from Route 1, you can go to Router 2. But I can't figure out how to add the correct URL in the template.
My template is:
<template name="occasionnav">
<nav>
<div class="nav-wrapper">
<ul class="right hide-on-med-and-down">
<li>cards</li>
<li>tables</li>
</ul>
</div>
</nav>
</template>
In the 'occasionnav' template by ":_occasionId" I need that to be the same parameter as the page currently being viewed be stuck into here.
If anyone has any insight or advice on the best way to approach this I would really appreciate it.
I recommend to use {{pathFor}} if you want to render an internal route in your Meteor application.
You just need to set the proper context and name your routes, for example:
<template name="occasionnav">
<nav>
<div class="nav-wrapper">
<ul class="right hide-on-med-and-down">
{{#with occasion}}
<li>cards</li>
<li>tables</li>
{{/with}}
</ul>
</div>
</nav>
</template>
Router.route('/occasions/:_id/cards/', {
template: 'cards',
name: 'occasions.cards',
data: function() {
return Cards.findOne({_id: this.params._id});
},
subscriptions: function() {
return Meteor.subscribe('cards', this.params._id);
}
});
Router.route('/occasions/:_id/tables/', {
template: 'tables',
name: 'occasions.tables',
data: function() {
return Tables.findOne({_id: this.params._id});
},
subscriptions: function() {
return Meteor.subscribe('tables', this.params._id);
}
});
However, you can also get the router parameters in your template via Router.current().params.
You can pass the _occasionId as a template helper and render it in jade like:
<li>cards</li>
You should try :
Router.route('/occasions/:_occasionId/cards/', function() {
this.layout("LayoutName");
this.render("cards", {
data: {
currentoccasion = this.params._occasionId;
}
});
});
When you use Router.map, it's not exactly the same syntax:
Router.map(function() {
this.route('<template name>', {
path: 'path/:_currentoccasion',
data: function () {
return {
currentoccasion: this.params._currentoccasion
}
}
});
And you can access just like that in your template :
Like an helper
{{ currentoccasion }}
Or on the onRendered and onCreated functions
Template.<template name>.onRendered({
this.data.currentoccasion

Why does route to home changes after rendering a template?

I am just getting started using the iron:router package. These are my project files:
router-example.js
if (Meteor.isClient) {
//some code
}
if (Meteor.isServer) {
//some code
}
Router.route('/', function(){
this.render('Home');
});
Router.route('/hello', function(){
this.render('hello');
});
Router.route('/items', function(){
this.render('Items');
});
Router.route('/serverItem', function(){
var req = this.request;
var res = this.response;
res.end('Hello from the server\n');
}, {where: 'server'});
router-example.html
<body>
<h1>Welcome to Meteor!</h1>
<ol>
<li>This routing doesn't work</li>
<li>Hello Template</li>
<li>Items Template</li>
<li>Server Item</li>
<li>Hard link works</li>
</ol>
</body>
templates.html
<template name = "Home">
<h2>Default: '/' brings you here</h2>
<p>This is the home template</p>
</template>
<template name = "Items">
<h2>This is the items template. Items Page linked using pathFor helper</h2>
</template>
<template name="hello">
<button>Click Me</button>
<p>You've pressed the button {{counter}} times.</p>
</template>
So at the home page "localhost:3000", the "Home" template is rendered by default, as expected. Once I click on the other links:
Hello Template,
Items Template etc.
Those are rendered, but home link specified using the {{pathFor '/'}} helper stops working and I have to use a hard link (localhost:3000) to get back to the home page. Hovering the mouse over that link shows that it's pointing to a different route.
So what am I doing wrong here?
You can specify route name in order to use {{pathFor 'routeName'}}:
Router.route('/', {
name: 'home',
template: 'Home'
})
Look here for full example https://github.com/iron-meteor/iron-router/blob/devel/Guide.md#route-specific-options
If no name is provided, the router guesses a name based on the path

MVC4-Refresh Issue:Same partial view called 3 times using foreach..loop

I am in a tricky situation,
Scenario- There are gadgets which are to be shown in mobile site.
2.One of the gadget is RSS which user can add multiple times for different topics like one for security, one for news, one for events.
3. So we have 1 partial view for RSS, but if the user has 2 RSS gadgets then the same partial view should load with different gadget name. Here the functionality is working fine using foreach loop.
#foreach (var rssFeed in Model.RSSFeedList)
{
<article class="bm2014_bigBoxWrap bm2014_bigBoxRSS bm2014_paginate">
<img src="~/Content/images/iconRefresh.png" width="20" height="20" alt="refresh icon" title="refresh icon">
<div class="bm2014_expColCtrl">
<h1 class="bm2014_bigBoxHdr">
<span class="bm2014_hiddenHdr"> </span>
<!-- for markup validation -->
#if (rssFeed.Channel.Name == "xyznews")
{
<span>#Html.Label(Labels.Title_xyz)</span>
}
else if(rssFeed.Channel.Category=="xyzRSSFeed")
{
<!--<span>#Html.Label(Labels.xyz) - #rssFeed.Channel.Title</span>-->
<span>#rssFeed.Channel.Title</span>
}
<span class="bm2014_expColBtn"><img src="~/Content/images/iconPlus.png" width="32" height="32" alt="expand collapse icon" title="expand collapse icon"></span>
</h1>
<div class="bm2014_expColContent bm2014_bellnetRSSWrapper" id="bm2014_divBellnetRSS">
#Html.Partial("~/Views/Shared/_RSS.cshtml", rssFeed)
</div>
</div>
</article>
}
<!-- RSS Panel end here -->
Problem is with refresh issue
if i hit the refresh button for selected gadget, it is by default taking only one RSS name and loading the content irrespective of different gadget selected.
partialview page code-
#model Models.RSSFeed
#{
Layout = null;
}
<script src="~/Scripts/jquery-1.8.2.min.js" type="text/javascript"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js" type="text/javascript"></script>
<script src="~/Scripts/jquery.multilevelpushmenu.js" type="text/javascript"></script>
<script src="~/Scripts/jquery-simple-pagination-plugin.js" type="text/javascript"></script>
<script src="~/Scripts/jquery.dataTables.js" type="text/javascript"></script>
<script type="text/javascript">
/* scripts to load after the DOM gets ready */
$(function () {
offCanvasMenu(); // trigger Javascript controlled OFF canvas menu after AJAX refresh
$.ajaxSetup({ cache: false });
$("article.bm2014_bigBoxRSS #btnRefresh").on('click', function (event) {
var $rssGadgetID = $(this).parents("article.bm2014_paginate").find("div#bm2014_divBellnetRSS");
var $rssGadgetLdr = $rssGadgetID.find("div#bm2014_gadgetLoader");
ajaxLoaderHeightCtrl($rssGadgetID, $rssGadgetLdr);
// AJAX control
$.ajax({
url: '#Url.Action("RefreshBellnetRSS", "Home", new { feedName = Model.Channel.FeedName })',
contentType: 'application/html; charaset=utf-8',
type: 'GET',
dataType: 'html',
success: function (result) {
$rssGadgetLdr.fadeOut(100, function () {
$rssGadgetID.html(result);
var moveRSS = $("article.bm2014_bigBoxWrap").css("float");
if (moveRSS == "left") {
mQueryAJAX("portrait", $rssGadgetID);
}
else if (moveRSS == "none") {
if (window.matchMedia("(orientation: portrait)").matches) {
mQueryAJAX("portrait", $rssGadgetID);
}
if (window.matchMedia("(orientation: landscape)").matches) {
mQueryAJAX("portrait", $rssGadgetID);
}
}
hideTableHeader();
});
},
error: function (xhr, status) {
alert(status);
}
});
});
});
</script>
<div class="bm2014_gadgetLoader" id="bm2014_gadgetLoader" style="display: none;">
<img src='#Url.Content("~/Content/Images/loaderGadget.gif")' width="48" height="48" alt="ajax loader image" title="ajax loader image">
</div>
<div class="bm2014_strategyContent">
#if (Model.url != null)
{
<table>
<thead>
<th>dummy header - to be hidden</th>
</thead>
<tbody>
#foreach (var url in Model.url)
{
<tr>
<td>
#url.Name
</td>
</tr>
}
</tbody>
</table>
}
</div>
need help/suggestions
If I understand correctly, you need to have 3 refresh buttons for 3 RSS gadgets e.g. one for security, one for news, one for events.
In the current example, every time you call the code to apply click event, you replace the earlier event and the 'feedname' parameter in url for ajax call also gets updated.
$("article.bm2014_bigBoxRSS #btnRefresh").on('click', function (event) {
......
}
You need to be able to distinguish between the refresh buttons and pass correct parameters. One way is to use data-feedname attribute on your btnRefresh anchor tag (if using HTML5)

Meteor data-context with iron-router

I am new to Meteor and I'm trying to set the data context in a page that displays one passage. I need to access the data in passage_item.js Template.passageItem.rendered but no context is set at that point. I think I need something like {{#with passage}} but "passage" does not exist in one_passage.html.
Here are some code snippets. Thanks.
router.js
Router.map(function() {
this.route('passagesList', {path: '/'});
this.route('onePassage', {
path: '/passages/:_id',
data: function() { return Passages.findOne(this.params._id); }
});
});
one_passage.html
<template name="onePassage">
{{> passageItem}}
</template>
passage-item.html
<template name="passageItem">
<div class="passage">
<div class="one-passage">
<h4>{{title}}</h4>
<div class="passage-content">
{{content}}
</div>
</div>
</div>
passage_item.js
Template.passageItem.helpers({
});
Template.passageItem.rendered = function() {
Meteor.defer(function() {
$('.passage-content').lettering('words');
//I want to be able to access the data object here. I have a list of words that are highlighted
});
};
Collection
Assuming you created your Passages collection like this and you've got autopublish turned on (which it is by default):
Passages = new Meteor.Collection('passages');
Router Map
And you mapped your router like this:
Router.map(function() {
this.route('onePassage', {
path: '/passages/:_id',
template: 'passageItem' // <-- to be explicit
data: function() {
return Passages.findOne(this.params._id);
}
});
});
Template
And your template looks like the template below:
<template name="passageItem">
<div class="passage">
<div class="one-passage">
<h4>{{title}}</h4>
<div class="passage-content">
{{content}}
</div>
</div>
</div>
</template>
The scope of 'this' in the template will be set to document returned by the Passages.findOne selector.
If the template doesn't render that means you're either searching for passage that doesn't exist, or your passage is missing title or content fields.
Rendered Function
Now for the last part of your question. The scope of 'this' in a rendered function is set to the template instance. So if you need to access the template data try this:
Template.passageItem.rendered = function() {
console.log(this.data); // you should see your passage object in the console
};
As of Meteor 1.0.3.1, the new Iron Router data selector appears to be...
Template.TemplateName.rendered = function() {
console.log(UI.getData());
};
I assume a passage consists of {'title':'', 'content':''}
Then this should work:
in router.js
Router.map(function() {
this.route('passagesList', {path: '/'});
this.route('onePassage', {
path: '/passages/:_id',
data: {
passage: function() { return Passages.findOne(this.params._id); }
}
});
});
in passage-item.html:
<template name="passageItem">
{{#each passage}}
<div class="passage">
<div class="one-passage">
<h4>{{title}}</h4>
<div class="passage-content">
{{content}}
</div>
</div>
</div>
{{/each}}
</template>

KnockoutJS, updating ViewModel after ajax call

I am using Knockout and the Knockout Mapping plugin.
My MVC3 Action returns a View and not JSON directly as such I convert my Model into JSON.
This is a data entry form and due to the nature of the system validation is all done in the Service Layer, with warnings returned in a Response object within the ViewModel.
The initial bindings and updates work correctly its the "post-update" behavior that is causing me a problem.
My problem is after calling the AJAX POST and and receiving my JSON response knockout is not updating all of my bindings... as if the observable/mappings have dropped off
If I include an additional ko.applyBindings(viewModel); in the success things do work... however issues then arise with multiple bindings and am certain this is not the correct solution.
This is the HTML/Template/Bindings
<!-- Start Form -->
<form action="#Url.Action("Edit")" data-bind="submit: save">
<div id="editListing" data-bind="template: 'editListingTemplate'"></div>
<div id="saveListing" class="end-actions">
<button type="submit">Save Listings</button>
</div>
</form>
<!-- End Form -->
<!-- Templates -->
<script type="text/html" id="editListingTemplate">
<div class="warning message error" data-bind="visible: Response.HasWarning">
<span>Correct the Following to Save</span>
<ul>
{{each(i, warning) Response.BusinessWarnings}}
<li data-bind="text: Message"></li>
{{/each}}
</ul>
</div>
<fieldset>
<legend>Key Information</legend>
<div class="editor-label">
<label>Project Name</label>
</div>
<div class="editor-field">
<input data-bind="value: Project_Name" class="title" />
</div>
</fieldset>
</script>
<!-- End templates -->
And this is the Knockout/Script
<script type="text/javascript">
#{ var jsonData = new HtmlString(new JavaScriptSerializer().Serialize(Model)); }
var initialData = #jsonData;
var viewModel = ko.mapping.fromJS(initialData);
viewModel.save = function ()
{
this.Response = null;
var data = ko.toJSON(this);
$.ajax({
url: '#Url.Action("Edit")',
contentType: 'application/json',
type: "POST",
data: data,
dataType: 'json',
success: function (result) {
ko.mapping.updateFromJS(viewModel, result);
}
});
}
$(function() {
ko.applyBindings(viewModel);
});
</script>
And this is the response JSON returned from the successful request including validation messages.
{
"Id": 440,
"Project_Name": "",
"Response": {
"HasWarning": true,
"BusinessWarnings": [
{
"ExceptionType": 2,
"Message": "Project is invalid."
}, {
"ExceptionType": 1,
"Message": "Project_Name may not be null"
}
]
}
}
UPDATE
Fiddler Demo Is a trimmed live example of what I am experiencing. I have the Project_Name updating with the returned JSON but the viewModel.Response object and properties are not being updated through their data bindings. Specifically Response.HasWarning().
I've changed back to ko.mapping.updateFromJS because in my controller I am specifically returning Json(viewModel).
Cleaned up my initial code/question to match the demo.
I guess Response is reserved, when I change "Response" to "resp", everything went fine. See http://jsfiddle.net/BBzVm/
Should't you use ko.mapping.updateFromJSON on your success event? Chapter Working with JSON strings on Knockout Mapping site says:
If your Ajax call returns a JSON string (and does not deserialize it into a JavaScript object), then you can use the functions ko.mapping.fromJSON and ko.mapping.updateFromJSON to create and update your view model instead.

Resources