Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save jlcarvalho/22402d013bc72f795d45a01836ce735c to your computer and use it in GitHub Desktop.
Save jlcarvalho/22402d013bc72f795d45a01836ce735c to your computer and use it in GitHub Desktop.
<div class="post" id="post-main-6385">
<div class="entry">
<h1 class="post-title single"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/" rel="bookmark" title="Permanent Link to Three hooks your Cordova/PhoneGap project needs">Three hooks your Cordova/PhoneGap project needs</a></h1>
<div class="meta single">
<span class="meta-date">November 12, 2013</span><span class="meta-author">By <a href="https://web.archive.org/web/20180803132745/http://devgirl.org/author/danmoore/" title="Posts by Dan Moore" rel="author">Dan Moore</a></span><span class="meta-comments"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comments" rel="bookmark" title="Comments for Three hooks your Cordova/PhoneGap project needs">55 Comments</a></span>
</div>
<p>Hooks are pieces of code that Cordova CLI executes at certain points in your Cordova or PhoneGap application build. (Remember, PhoneGap and Cordova both use the Cordova CLI unless you are using <a href="https://web.archive.org/web/20180803132745/https://build.phonegap.com/">PhoneGap Build</a>.) They allow you to extend the Cordova CLI framework to suite your needs. While you can use hooks to integrate the Cordova CLI into a larger framework, like <a href="https://web.archive.org/web/20180803132745/https://npmjs.org/package/grunt-cordovacli">grunt</a>, typically you’ll be writing project level hooks to manipulate files in your project.</p>
<p>Hooks live in the <code>rootProject/hooks/</code> folder, in a subdirectory named after project command: <code>before_xxx</code> or <code>after_xxx</code>, where <code>xxx</code> is the project command (<code>prepare</code>, <code>build</code>, etc). The supported project commands are <a href="https://web.archive.org/web/20180803132745/https://github.com/apache/cordova-cli#project_commands">listed here</a>.</p>
<p>Hooks can be written in any programming language, but they are executed whenever you build your project, on whatever computer you are building your project. So I’d stay away from writing hooks in C#, unless you are only developing on Windows. I have written hooks in shell script and in Node.js. Node.js is server side JavaScript, and since Cordova CLI is written in Node.js, it is a safe choice because it is guaranteed to be present.</p>
<p>Hooks do tie your build process to the Cordova CLI, and require your developers to have the entire CLI toolchain on their computers, so they might not be a good fit for every shop.</p>
<p>Below are three hooks that every project using Cordova CLI should use. All code was tested on using <code>cordova 3.1.0-0.2.0</code> on a CentOS 6 virtual machine. These hooks are all available for download at <a href="https://web.archive.org/web/20180803132745/http://www.mooreds.com/sample-hooks.tar.gz">http://www.mooreds.com/sample-hooks.tar.gz</a>.</p>
<p><strong>Add Plugins</strong></p>
<p>With the new modular architecture of Cordova 3.x, every app needs plugins, even to use basic functionality such as logging or geolocation. Rather than document which plugins/features your project needs and ask each new developer to install them, download and install them automatically with a hook in the <code>after_platform_add</code> step. Using this plugin, every time a developer checks out the project and adds a platform, they automatically have the required plugins. </p>
<pre class="brush: jscript; title: ; notranslate" title="">#!/usr/bin/env node
//this hook installs all your plugins
// add your plugins to this list--either
// the identifier, the filesystem location
// or the URL
var pluginlist = [
"org.apache.cordova.device",
"org.apache.cordova.device-motion",
"org.apache.cordova.device-orientation",
"org.apache.cordova.geolocation",
"https://github.com/chrisekelley/AppPreferences/"
];
// no need to configure below
var fs = require('fs');
var path = require('path');
var sys = require('sys')
var exec = require('child_process').exec;
function puts(error, stdout, stderr) {
sys.puts(stdout)
}
pluginlist.forEach(function(plug) {
exec("cordova plugin add " + plug, puts);
});
</pre>
<p>(This hook is the <code>010_install_plugins.js</code> file in the download.)</p>
<h3>Replace Text Depending on Environment</h3>
<p>You will often have development, staging and production environments for your Cordova application. Each of these environments can vary–they could depend on data from different servers, need different API keys, or even just have a different splash screen to help when testing (“STAGE app” vs “app”). While you could change each file in your app that had deployment specific information each time you want to build for a different environment, this is error prone and tedious. Such a wide ranging modification is better to automate.</p>
<p>To do so, start by creating a configuration file that has an object for each deployment environment, like this one: </p>
<pre class="brush: jscript; title: ; notranslate" title="">{
"stage":
{
"datahostname" : "'qa-api.mydomain.com'"
},
"prod":
{
"datahostname" : "'api.mydomain.com'"
}
}
</pre>
<p>(There is a sample file <code>project.json</code> configuration file in the download as well.)</p>
<p>In each object, create key value pairs where the key is the type of item to be configured (like “datahostname” or “apikey”), and the value is the correct value for that particular environment (like “api.mydomain.com” or “AA3ACF”). Add tokens to files in your <code>www</code> directory for each environment dependent variable. Determine which environment you are building for with one master variable. Use a hook script to replace the variables in the files. This hook script should be added to the <code>after_prepare</code> hook directory so that it is run every time you build.</p>
<pre class="brush: jscript; title: ; notranslate" title="">#!/usr/bin/env node
// this plugin replaces arbitrary text in arbitrary files
//
// Look for the string CONFIGURE HERE for areas that need configuration
//
var fs = require('fs');
var path = require('path');
var rootdir = process.argv[2];
function replace_string_in_file(filename, to_replace, replace_with) {
var data = fs.readFileSync(filename, 'utf8');
var result = data.replace(new RegExp(to_replace, "g"), replace_with);
fs.writeFileSync(filename, result, 'utf8');
}
var target = "stage";
if (process.env.TARGET) {
target = process.env.TARGET;
}
if (rootdir) {
var ourconfigfile = path.join(rootdir, "config", "project.json");
var configobj = JSON.parse(fs.readFileSync(ourconfigfile, 'utf8'));
// CONFIGURE HERE
// with the names of the files that contain tokens you want
// replaced. Replace files that have been copied via the prepare step.
var filestoreplace = [
// android
"platforms/android/assets/www/index.html",
// ios
"platforms/ios/www/index.html",
];
filestoreplace.forEach(function(val, index, array) {
var fullfilename = path.join(rootdir, val);
if (fs.existsSync(fullfilename)) {
// CONFIGURE HERE
// with the names of the token values. For example,
// below we are looking for the token
// /*REP*/ 'api.example.com' /*REP*/ and will replace
// that token
replace_string_in_file(fullfilename,
"/\\*REP\\*/ 'api.example.com' /\\*REP\\*/",
configobj[target].datahostname);
// ... any other configuration options
} else {
//console.log("missing: "+fullfilename);
}
});
}</pre>
<p>(This hook is the <code>020_replace_text.js</code> file in the download.)</p>
<p>This hook makes building for production as easy as <code>TARGET=prod cordova build ios</code>.</p>
<h3>Copy Icons and Splashscreens</h3>
<p>Having custom icons and splashscreens is required for a professional mobile app. Unfortunately, Cordova CLI doesn’t support this key functionality yet. (Don’t be deceived by the icon images under <code>www</code>–they don’t do anything except increase the size of the final app and confuse newcomers). You can manually move of copy the icon and splash screen files to the proper directories each time you build. But if you want to version control your icons and splashscreens, or make the build replicable across machines, you need to automatically put the image resource files where the platform specific build processes expect them.</p>
<p>I like to store my icon/splash screen files under a top level directory (a peer to the <code>www</code> directory) and use an <code>after_prepare</code> hook to copy the files to their correct directories under <code>platforms</code>. It’s a bit tedious to figure out, but once you’ve done it once and written the hook, you are done (at least until Google, Apple, or another vendor introduces another size of icon you need to handle). </p>
<pre class="brush: jscript; title: ; notranslate" title="">#!/usr/bin/env node
//
// This hook copies various resource files
// from our version control system directories
// into the appropriate platform specific location
//
// configure all the files to copy.
// Key of object is the source file,
// value is the destination location.
// It's fine to put all platforms' icons
// and splash screen files here, even if
// we don't build for all platforms
// on each developer's box.
var filestocopy = [{
"config/android/res/drawable/icon.png":
"platforms/android/res/drawable/icon.png"
}, {
"config/android/res/drawable-hdpi/icon.png":
"platforms/android/res/drawable-hdpi/icon.png"
}, {
"config/android/res/drawable-ldpi/icon.png":
"platforms/android/res/drawable-ldpi/icon.png"
}, {
"config/android/res/drawable-mdpi/icon.png":
"platforms/android/res/drawable-mdpi/icon.png"
}, {
"config/android/res/drawable-xhdpi/icon.png":
"platforms/android/res/drawable-xhdpi/icon.png"
}, {
"config/android/res/drawable/splash.png":
"platforms/android/res/drawable/splash.png"
}, {
"config/android/res/drawable-hdpi/splash.png":
"platforms/android/res/drawable-hdpi/splash.png"
}, {
"config/android/res/drawable-ldpi/splash.png":
"platforms/android/res/drawable-ldpi/splash.png"
}, {
"config/android/res/drawable-mdpi/splash.png":
"platforms/android/res/drawable-mdpi/splash.png"
}, {
"config/android/res/drawable-xhdpi/splash.png":
"platforms/android/res/drawable-xhdpi/splash.png"
}, {
"config/ios/Resources/icons/icon-72.png":
"platforms/ios/YourAppName/Resources/icons/icon-72.png"
}, {
"config/ios/Resources/icons/icon.png":
"platforms/ios/YourAppName/Resources/icons/icon.png"
}, {
"config/ios/Resources/icons/icon@2x.png":
"platforms/ios/YourAppName/Resources/icons/icon@2x.png"
}, {
"config/ios/Resources/icons/icon-72@2x.png":
"platforms/ios/YourAppName/Resources/icons/icon-72@2x.png"
}, {
"config/ios/Resources/splash/Default@2x~iphone.png":
"platforms/ios/YourAppName/Resources/splash/Default@2x~iphone.png"
}, {
"config/ios/Resources/splash/Default-568h@2x~iphone.png":
"platforms/ios/YourAppName/Resources/splash/Default-568h@2x~iphone.png"
}, {
"config/ios/Resources/splash/Default~iphone.png":
"platforms/ios/YourAppName/Resources/splash/Default~iphone.png"
}, {
"config/ios/Resources/splash/Default-Portrait~ipad.png":
"platforms/ios/YourAppName/Resources/splash/Default-Portrait~ipad.png"
}, {
"config/ios/Resources/splash/Default-Portrait@2x~ipad.png":
"platforms/ios/YourAppName/Resources/splash/Default-Portrait@2x~ipad.png
}, ];
var fs = require('fs');
var path = require('path');
// no need to configure below
var rootdir = process.argv[2];
filestocopy.forEach(function(obj) {
Object.keys(obj).forEach(function(key) {
var val = obj[key];
var srcfile = path.join(rootdir, key);
var destfile = path.join(rootdir, val);
//console.log("copying "+srcfile+" to "+destfile);
var destdir = path.dirname(destfile);
if (fs.existsSync(srcfile) &amp;amp;&amp;amp; fs.existsSync(destdir)) {
fs.createReadStream(srcfile).pipe(
fs.createWriteStream(destfile));
}
});
});</pre>
<p>Here’s another open source <a href="https://web.archive.org/web/20180803132745/https://github.com/cdibened/cordova-hooks">hook script to handle moving resource files</a>, though I haven’t tested it. My sample hook is the <code>030_resource_files.js</code> file in the download.</p>
<h3>Conclusion</h3>
<p>These hooks automate three common scenarios that will take place in almost any Cordova application–adding plugins to an app, switching between deployment environments, and adding custom icons and splash screens. </p>
<p>Write a hook anytime you have a build process that is tedious, repetitive, or required to build your app. Look carefully at any documented manual build processes. If you need to perform steps to build your app (copying icon files to various directories under <code>platforms</code>, for example), see if you can automate them in a hook script to make your build process quicker, easier, and more repeatable.</p>
<hr>
Dan Moore is Director of Technology for <a href="https://web.archive.org/web/20180803132745/http://8z.com/">8z Real Estate</a>, a Colorado and California real estate brokerage, and the author of <a href="https://web.archive.org/web/20180803132745/https://leanpub.com/developingwithcordovacli/">“Developing Cross Platform Mobile Applications with Cordova CLI”</a>.<p></p>
<div class="addtoany_share_save_container addtoany_content_bottom"><div class="a2a_kit a2a_kit_size_32 addtoany_list" data-a2a-url="http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/" data-a2a-title="Three hooks your Cordova/PhoneGap project needs" style="line-height: 32px;"><a class="a2a_button_twitter" href="/#twitter" title="Twitter" rel="nofollow noopener" target="_blank"><span class="a2a_svg a2a_s__default a2a_s_twitter" style="background-color: rgb(85, 172, 238);"><svg focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#FFF" d="M28 8.557a9.913 9.913 0 0 1-2.828.775 4.93 4.93 0 0 0 2.166-2.725 9.738 9.738 0 0 1-3.13 1.194 4.92 4.92 0 0 0-3.593-1.55 4.924 4.924 0 0 0-4.794 6.049c-4.09-.21-7.72-2.17-10.15-5.15a4.942 4.942 0 0 0-.665 2.477c0 1.71.87 3.214 2.19 4.1a4.968 4.968 0 0 1-2.23-.616v.06c0 2.39 1.7 4.38 3.952 4.83-.414.115-.85.174-1.297.174-.318 0-.626-.03-.928-.086a4.935 4.935 0 0 0 4.6 3.42 9.893 9.893 0 0 1-6.114 2.107c-.398 0-.79-.023-1.175-.068a13.953 13.953 0 0 0 7.55 2.213c9.056 0 14.01-7.507 14.01-14.013 0-.213-.005-.426-.015-.637.96-.695 1.795-1.56 2.455-2.55z"></path></svg></span><span class="a2a_label">Twitter</span></a><a class="a2a_button_google_plus" href="/#google_plus" title="Google+" rel="nofollow noopener" target="_blank"><span class="a2a_svg a2a_s__default a2a_s_google_plus" style="background-color: rgb(221, 75, 57);"><svg focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M27 15h-2v-2h-2v2h-2v2h2v2h2v-2h2m-15-2v2.4h3.97c-.16 1.03-1.2 3.02-3.97 3.02-2.39 0-4.34-1.98-4.34-4.42s1.95-4.42 4.34-4.42c1.36 0 2.27.58 2.79 1.08l1.9-1.83C15.47 9.69 13.89 9 12 9c-3.87 0-7 3.13-7 7s3.13 7 7 7c4.04 0 6.72-2.84 6.72-6.84 0-.46-.05-.81-.11-1.16H12z" fill="#FFF"></path></svg></span><span class="a2a_label">Google+</span></a><a class="a2a_button_facebook" href="/#facebook" title="Facebook" rel="nofollow noopener" target="_blank"><span class="a2a_svg a2a_s__default a2a_s_facebook" style="background-color: rgb(59, 89, 152);"><svg focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#FFF" d="M17.78 27.5V17.008h3.522l.527-4.09h-4.05v-2.61c0-1.182.33-1.99 2.023-1.99h2.166V4.66c-.375-.05-1.66-.16-3.155-.16-3.123 0-5.26 1.905-5.26 5.405v3.016h-3.53v4.09h3.53V27.5h4.223z"></path></svg></span><span class="a2a_label">Facebook</span></a><a class="a2a_button_twitter_tweet addtoany_special_service" data-url="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/" data-text="Three hooks your Cordova/PhoneGap project needs"><iframe id="twitter-widget-0" scrolling="no" frameborder="0" allowtransparency="true" class="twitter-share-button twitter-share-button-rendered twitter-tweet-button" style="position: absolute; visibility: hidden; width: 0px; height: 0px;" title="Twitter Tweet Button" src="https://web.archive.org/web/20180803132817/https://platform.twitter.com//widgets/tweet_button.cb6df5c11eb74c4885e17101a777cb60.en.html#dnt=false&amp;id=twitter-widget-0&amp;lang=en&amp;original_referer=https%3A%2F%2Fweb.archive.org%2Fweb%2F20180803132745%2Fhttp%3A%2F%2Fdevgirl.org%2F2013%2F11%2F12%2Fthree-hooks-your-cordovaphonegap-project-needs%2F&amp;related=AddToAny%2Cmicropat&amp;size=m&amp;text=Three%20hooks%20your%20Cordova%2FPhoneGap%20project%20needs&amp;time=1557758638666&amp;type=share&amp;url=https%3A%2F%2Fweb.archive.org%2Fweb%2F20180803132745%2Fhttp%3A%2F%2Fdevgirl.org%2F2013%2F11%2F12%2Fthree-hooks-your-cordovaphonegap-project-needs%2F"></iframe><a class="twitter-share-button" data-url="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/" data-lang="en" data-related="AddToAny,micropat" data-text="Three hooks your Cordova/PhoneGap project needs" data-twitter-extracted-i1557758636297896488="true"></a></a><a class="a2a_dd addtoany_share_save" href="https://web.archive.org/web/20180803132804/https://www.addtoany.com/share#url=http%3A%2F%2Fdevgirl.org%2F2013%2F11%2F12%2Fthree-hooks-your-cordovaphonegap-project-needs%2F&amp;title=Three%20hooks%20your%20Cordova%2FPhoneGap%20project%20needs"><span class="a2a_svg a2a_s__default a2a_s_a2a" style="background-color: rgb(1, 102, 255);"><svg focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><g fill="#FFF"><path d="M14 7h4v18h-4z"></path><path d="M7 14h18v4H7z"></path></g></svg></span><span class="a2a_label a2a_localize" data-a2a-localize="inner,Share">Share</span></a></div></div>
<div style="clear:both;"></div>
<p class="cats">
<span class="cat">Filed in: <a href="https://web.archive.org/web/20180803132745/http://devgirl.org/category/cordova/" rel="category tag">Cordova</a> • <a href="https://web.archive.org/web/20180803132745/http://devgirl.org/category/phonegap-3-0-2/" rel="category tag">PhoneGap 3.0</a></span>
<span class="tags">Tags: <a href="https://web.archive.org/web/20180803132745/http://devgirl.org/tag/cordova-hooks/" rel="tag">cordova hooks</a> • <a href="https://web.archive.org/web/20180803132745/http://devgirl.org/tag/cordova-scripts/" rel="tag">cordova scripts</a> • <a href="https://web.archive.org/web/20180803132745/http://devgirl.org/tag/cordova-splash-screens/" rel="tag">cordova splash screens</a> • <a href="https://web.archive.org/web/20180803132745/http://devgirl.org/tag/phonegap-hooks/" rel="tag">phonegap hooks</a></span> </p>
</div>
<div class="auth-bio clearfix">
<div class="bio">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <h3>About the Author <span class="profile">(<a rel="author" href="https://web.archive.org/web/20180803132745/http://devgirl.org/?author=5">Author Profile</a>)</span></h3>
Dan Moore is Director of Technology for 8z Real Estate, a Colorado and California real estate brokerage, and the author of “Developing Cross Platform Mobile Applications with Cordova CLI” </div>
</div>
<div id="related" class="clearfix">
<div class="subscribe">
<h3>Subscribe</h3>
<p>If you enjoyed this article, subscribe to receive more just like it.</p>
<div class="sub-icons clearfix">
<a title="Subscribe via RSS Feed" href="https://web.archive.org/web/20180803132745/http://devgirl.org/feed/"><img class="rss-sub" src="https://web.archive.org/web/20180803132745im_/http://devgirl.org/wp-content/themes/wp-venus104/images/feed.png" alt="Subscribe via RSS Feed" align="top"></a>
<a rel="external" title="Follow Me on Twitter" href="https://web.archive.org/web/20180803132745/http://www.twitter.com/devgirlfl"><img class="twitter-sub" src="https://web.archive.org/web/20180803132745im_/http://devgirl.org/wp-content/themes/wp-venus104/images/twitter.png" alt="Follow Me on Twitter" align="top"></a>
</div>
</div>
</div>
<!-- You can start editing here. -->
<div class="allcomments">
<h3 id="comments">Comments (55)</h3>
<p class="comments-number"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/trackback/" title="Trackback URL">Trackback URL</a> | <a title="Comments RSS Feed for This Entry" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/feed">Comments RSS Feed</a></p>
<div class="comments-navigation clearfix">
<div class="alignleft"></div>
<div class="alignright"></div>
</div>
<div class="pings">
<h3>Sites That Link to this Post</h3>
<ol class="pinglist">
<li id="comment-28488"><a href="https://web.archive.org/web/20180803132745/http://www.mooreds.com/wordpress/archives/1419" rel="external nofollow" class="url">How to use platform specific configuration in your Cordova app | Dan Moore!</a> | February 7, 2014</li><!-- #comment-## -->
<li id="comment-28768"><a href="https://web.archive.org/web/20180803132745/http://www.mooreds.com/wordpress/archives/1425" rel="external nofollow" class="url">Dan Moore!</a> | February 17, 2014</li><!-- #comment-## -->
<li id="comment-119118"><a href="https://web.archive.org/web/20180803132745/http://robandlauren.com/2014/05/30/two-phonegap-hooks-make-life-better/" rel="external nofollow" class="url">Two PhoneGap Hooks That Make Life Better - Rob and Lauren</a> | May 30, 2014</li><!-- #comment-## -->
<li id="comment-320145"><a href="https://web.archive.org/web/20180803132745/http://www.zescience.com/clarification-around-icon-and-splashscreen-with-phonegap-95534" rel="external nofollow" class="url">Clarification around icon and splashscreen with phonegap</a> | August 18, 2014</li><!-- #comment-## -->
</ol>
</div>
<ol class="commentlist">
<li class="comment even thread-even depth-1" id="comment-25972">
<div id="div-comment-25972" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/52b6da8c6a817bf4e293f03470379c78?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/52b6da8c6a817bf4e293f03470379c78?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/http://siebmanb.com/" rel="external nofollow" class="url">Siebmanb</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-25972">
November 13, 2013 at 4:11 am</a> </div>
<p>Hello,</p>
<p>Thanks for this article.</p>
<p>When using your code, I have the following error on the json : (replaced my path with XXX)<br>
[error] Script “XXX/.cordova/hooks/after_prepare/project.json” exited with non-zero status code. Aborting. Output: XXX/.cordova/hooks/after_prepare/project.json: line 12: syntax error: unexpected end of file</p>
<p>Any idea from where it comes from ?</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=25972#respond" onclick="return addComment.moveForm( &quot;div-comment-25972&quot;, &quot;25972&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Siebmanb">Reply</a></div>
</div>
</li><!-- #comment-## -->
<li class="comment odd alt thread-odd thread-alt depth-1 parent" id="comment-25973">
<div id="div-comment-25973" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/52b6da8c6a817bf4e293f03470379c78?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/52b6da8c6a817bf4e293f03470379c78?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/http://siebmanb.com/" rel="external nofollow" class="url">Siebmanb</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-25973">
November 13, 2013 at 4:26 am</a> </div>
<p>I found the solution to my problem. I did not realize that the script to replace text was looking for project.json into the config directory. I put the json in the hooks directory, and CLI was trying to execute it as a script, and obviously failed to do so.</p>
<p>Thanks again for that nice article. Why does nobody talks about hooks on the web ? It is awesome !!!</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=25973#respond" onclick="return addComment.moveForm( &quot;div-comment-25973&quot;, &quot;25973&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Siebmanb">Reply</a></div>
</div>
<ul class="children">
<li class="comment byuser comment-author-danmoore bypostauthor even depth-2 parent" id="comment-25976">
<div id="div-comment-25976" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">Dan Moore</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-25976">
November 13, 2013 at 10:25 am</a> </div>
<p>Hi,</p>
<p>I’m glad you figured it out. I’m sorry that I neglected to mention that the project.json file needs to be placed outside of the .cordova/hooks directory. But I’m glad you figured that out. (As an aside, you’ll get the same error message if you have a hook script in the .cordova/hooks directory, but the script isn’t executable or has a syntax error.)</p>
<p>I think hooks are awesome too! Please let me know of any interesting use cases you think of.</p>
<p>Cheers.<br>
Dan</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=25976#respond" onclick="return addComment.moveForm( &quot;div-comment-25976&quot;, &quot;25976&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Dan Moore">Reply</a></div>
</div>
<ul class="children">
<li class="comment odd alt depth-3" id="comment-25977">
<div id="div-comment-25977" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/52b6da8c6a817bf4e293f03470379c78?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/52b6da8c6a817bf4e293f03470379c78?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/http://siebmanb.com/" rel="external nofollow" class="url">Siebmanb</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-25977">
November 13, 2013 at 10:32 am</a> </div>
<p>Will do. I am thinking about publishing some on my Github, will keep you posted.</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=25977#respond" onclick="return addComment.moveForm( &quot;div-comment-25977&quot;, &quot;25977&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Siebmanb">Reply</a></div>
</div>
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
<li class="comment even thread-even depth-1 parent" id="comment-25981">
<div id="div-comment-25981" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/ef3cd3a0bdb2e04da1c7f63118064b47?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/ef3cd3a0bdb2e04da1c7f63118064b47?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">Cesidio DiBenedetto</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-25981">
November 13, 2013 at 3:20 pm</a> </div>
<p>Dan, </p>
<p>Thanks for the mention. Your scripts are looking nice. </p>
<p>I have to go back and update my scripts to add support for the other platforms, plus incorporate the recommendations you sent by email.</p>
<p>Keep up the great work.</p>
<p>Cesidio</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=25981#respond" onclick="return addComment.moveForm( &quot;div-comment-25981&quot;, &quot;25981&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Cesidio DiBenedetto">Reply</a></div>
</div>
<ul class="children">
<li class="comment odd alt depth-2" id="comment-25982">
<div id="div-comment-25982" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/2f988fcd35f269c0400e8909e4089b6d?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/2f988fcd35f269c0400e8909e4089b6d?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/http://leanpub.com/developingwithcordovacli/" rel="external nofollow" class="url">Dan Moore</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-25982">
November 13, 2013 at 5:07 pm</a> </div>
<p>Thanks Cesidio. Looking forward to seeing how your scripts evolve. One downside to my scripts is they aren’t exactly ‘drop in’–they require some editing.</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=25982#respond" onclick="return addComment.moveForm( &quot;div-comment-25982&quot;, &quot;25982&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Dan Moore">Reply</a></div>
</div>
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
<li class="comment even thread-odd thread-alt depth-1 parent" id="comment-25988">
<div id="div-comment-25988" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://1.gravatar.com/avatar/4ccbf04a5924cbacd9814ce74e9ad684?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://1.gravatar.com/avatar/4ccbf04a5924cbacd9814ce74e9ad684?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/http://www.adamwadeharris.com/" rel="external nofollow" class="url">Adam</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-25988">
November 14, 2013 at 2:25 pm</a> </div>
<p>I can’t get the this to work. I tried the one to copy the icons, but it does nothing. First I tried with phonegap cli, then I switched to cordova cli, when I noticed that the phonegap cli github says nothing about hooks. So I’m not sure if phonegap supports it, especially since phonegap doesn’t have a prepare command. But anyway, I couldn’t get it to work with corodova either. If I run cordova prepare android –verbose, I can see that the last thing it does is run the hook file, but it says “output to follow…”, followed by a blank line. I tried putting some lines of console.log in the file, but they don’t output. Do I have to edit anything in the js file besides the paths in filestocopy?</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=25988#respond" onclick="return addComment.moveForm( &quot;div-comment-25988&quot;, &quot;25988&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Adam">Reply</a></div>
</div>
<ul class="children">
<li class="comment byuser comment-author-danmoore bypostauthor odd alt depth-2" id="comment-25989">
<div id="div-comment-25989" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">Dan Moore</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-25989">
November 14, 2013 at 3:20 pm</a> </div>
<p>Hi Adam,</p>
<p>Thanks for letting me know.</p>
<p>A couple of things to troubleshoot:</p>
<p>1. Did you create all the [projectroot]/config/android/res directories? (It sounds like you did.)</p>
<p>2. Did you make sure the node script is executable? </p>
<p>3. What directory did you put the script in?</p>
<p>4. What version of cordova are you running (cordova -v)</p>
<p>5. If you comment everything out, except the #!/ line and a ‘console.log(“here I am”);’ line, and run cordova prepare android, what do you see?</p>
<p>Note that these scripts should work with phonegap cli as well as cordova cli, since phonegap cli just defers to cordova cli.</p>
<p>Cheers.</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=25989#respond" onclick="return addComment.moveForm( &quot;div-comment-25989&quot;, &quot;25989&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Dan Moore">Reply</a></div>
</div>
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
<li class="comment even thread-even depth-1 parent" id="comment-25990">
<div id="div-comment-25990" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://1.gravatar.com/avatar/4ccbf04a5924cbacd9814ce74e9ad684?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://1.gravatar.com/avatar/4ccbf04a5924cbacd9814ce74e9ad684?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/http://www.adamwadeharris.com/" rel="external nofollow" class="url">Adam</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-25990">
November 14, 2013 at 4:13 pm</a> </div>
<p>1. Yes, I actually put it in [projectroot]/res/icon/android, but I updated the paths in filestocopy accordingly.</p>
<p>2. Not sure what this means. I guess you mean running a chmod command? I have it set to 755 (rwxr-xr-x).</p>
<p>3. [projectroot]/.cordova/hooks/after_prepare/move_icons.js</p>
<p>4. I was running 3.1.0-0.1.0, but when I updated to 3.1.0-0.2.0, it started working!</p>
<p>5. That helped troubleshoot. Thanks!</p>
<p>Thanks so much!</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=25990#respond" onclick="return addComment.moveForm( &quot;div-comment-25990&quot;, &quot;25990&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Adam">Reply</a></div>
</div>
<ul class="children">
<li class="comment byuser comment-author-danmoore bypostauthor odd alt depth-2" id="comment-25991">
<div id="div-comment-25991" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">Dan Moore</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-25991">
November 14, 2013 at 10:10 pm</a> </div>
<p>Great, thanks for letting me know. Please let me know if you come up with any great uses for hooks.</p>
<p>Cheers.</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=25991#respond" onclick="return addComment.moveForm( &quot;div-comment-25991&quot;, &quot;25991&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Dan Moore">Reply</a></div>
</div>
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
<li class="comment even thread-odd thread-alt depth-1 parent" id="comment-27232">
<div id="div-comment-27232" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://1.gravatar.com/avatar/a80ff35da226548293fa800b67e96be9?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://1.gravatar.com/avatar/a80ff35da226548293fa800b67e96be9?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">duc</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-27232">
December 24, 2013 at 7:25 am</a> </div>
<p>since these hooks use shebang which is unix based only. Is it possible to create similar hooks on windows? Thanks</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=27232#respond" onclick="return addComment.moveForm( &quot;div-comment-27232&quot;, &quot;27232&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to duc">Reply</a></div>
</div>
<ul class="children">
<li class="comment odd alt depth-2 parent" id="comment-27233">
<div id="div-comment-27233" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/0e871cc2352a9433ea5507005c88a484?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/0e871cc2352a9433ea5507005c88a484?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/https://leanpub.com/developingwithcordovacli/" rel="external nofollow" class="url">Dan Moore</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-27233">
December 24, 2013 at 9:27 am</a> </div>
<p>Hi Duc,</p>
<p>Yes, as long as the node scripts are valid, hooks should work. I didn’t even have to make the script executable.</p>
<p>I just installed cordova 3.3.1 on my windows7 box, and created a before_platform_ls hook that was a console.log statement. (Sorry for the formatting.)</p>
<p>Here’s what the hook script looked like:</p>
<p>C:\path\to\project\testapp\.cordova\hooks\before_platform_ls&gt;type hello.js<br>
console.log(“Hello World”);</p>
<p>Here’s what the output from running ‘cordova platform ls’ looked like:</p>
<p>C:\path\to\project\testapp&gt;..\..\node_modules\cordova\bin\cordova -d platform ls<br>
Executing hook “”C:\path\to\project\testapp\.cordova\hooks\before_platform_ls\hello.js” “C:\path\to\project\testapp””<br>
Hello World</p>
<p>Installed platforms:<br>
Available platforms: android, blackberry10, firefoxos, wp7, wp8, windows8</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=27233#respond" onclick="return addComment.moveForm( &quot;div-comment-27233&quot;, &quot;27233&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Dan Moore">Reply</a></div>
</div>
<ul class="children">
<li class="comment even depth-3 parent" id="comment-27478">
<div id="div-comment-27478" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://1.gravatar.com/avatar/a80ff35da226548293fa800b67e96be9?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://1.gravatar.com/avatar/a80ff35da226548293fa800b67e96be9?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">duc</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-27478">
December 30, 2013 at 7:25 am</a> </div>
<p>Hi Dan,</p>
<p>Thank you for your reply, looks like mine is working as well but I’m currently having a problem with the copy icons hook. I get this error:</p>
<p>[Error: Script “C:\Git\Mobile\Cordova\.cordova\hooks\after_prepare\resou<br>
rce_files.js” exited with non-zero status code. Aborting. Output:<br>
path.js:204<br>
throw new TypeError(‘Arguments to path.join must be strings’);<br>
^<br>
TypeError: Arguments to path.join must be strings<br>
at f (path.js:204:15)<br>
at Object.filter (native)<br>
at Object.exports.join (path.js:209:40)<br>
at C:\Git\Mobile\Cordova\.cordova\hooks\after_prepare\resource_files<br>
.js:59:28<br>
at Array.forEach (native)<br>
at C:\Git\Mobile\Cordova\.cordova\hooks\after_prepare\resource_files<br>
.js:57:22<br>
at Array.forEach (native)<br>
at Object. (C:\Git\Mobile\Cordova\.cordova\hooks\after_pr<br>
epare\resource_files.js:56:13)<br>
at Module._compile (module.js:456:26)<br>
at Object.Module._extensions..js (module.js:474:10)<br>
]</p>
<p>I think it is because my rootdir is null. From the tutorial code: var rootdir = process.argv[2]; I’m not quite sure where process variable comes from. Do you know how to solve this? Thanks</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=27478#respond" onclick="return addComment.moveForm( &quot;div-comment-27478&quot;, &quot;27478&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to duc">Reply</a></div>
</div>
<ul class="children">
<li class="comment odd alt depth-4 parent" id="comment-27481">
<div id="div-comment-27481" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/https://leanpub.com/developingwithcordovacli/" rel="external nofollow" class="url">Dan Moore</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-27481">
December 30, 2013 at 8:45 am</a> </div>
<p>Hmmm. process is a node thing: <a href="https://web.archive.org/web/20180803132745/http://nodejs.org/api/process.html#process_process_argv" rel="nofollow">http://nodejs.org/api/process.html#process_process_argv</a></p>
<p>If you have console.log statements that show your rootdir is null, that sounds like a bug in the CLI.</p>
<p>Can you show us the line that is failing in the script (based on your line numbers, line 57)? That might help debug the issue.</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=27481#respond" onclick="return addComment.moveForm( &quot;div-comment-27481&quot;, &quot;27481&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Dan Moore">Reply</a></div>
</div>
<ul class="children">
<li class="comment even depth-5" id="comment-27530">
<div id="div-comment-27530" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://1.gravatar.com/avatar/a80ff35da226548293fa800b67e96be9?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://1.gravatar.com/avatar/a80ff35da226548293fa800b67e96be9?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">duc</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-27530">
December 31, 2013 at 5:12 am</a> </div>
<p>Hi Dan, line 57 is: Object.keys(obj).forEach(function(key) {<br>
(line 84 in this tutorial)</p>
</div>
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
<li class="comment odd alt thread-even depth-1" id="comment-27539">
<div id="div-comment-27539" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/https://leanpub.com/developingwithcordovacli" rel="external nofollow" class="url">Dan Moore</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-27539">
December 31, 2013 at 6:20 am</a> </div>
<p>Looks like there is a formatting bug on line 74 of the copy resources script. The iPad image string is not properly closed. Just an FYI to anyone reading this.</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=27539#respond" onclick="return addComment.moveForm( &quot;div-comment-27539&quot;, &quot;27539&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Dan Moore">Reply</a></div>
</div>
</li><!-- #comment-## -->
<li class="comment even thread-odd thread-alt depth-1 parent" id="comment-27541">
<div id="div-comment-27541" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/https://leanpub.com/developingwithcordovacli" rel="external nofollow" class="url">Dan Moore</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-27541">
December 31, 2013 at 6:24 am</a> </div>
<p>Hi Duc, </p>
<p>Have you verified that your json array is correct? The line that is causing an issue is merely iterating over that array, so I don’t know if a null root dir variable would cause that issue.</p>
<p>Can you post your whole hook script?</p>
<p>(I like to use jsonlint.com to validate my json data structures.)</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=27541#respond" onclick="return addComment.moveForm( &quot;div-comment-27541&quot;, &quot;27541&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Dan Moore">Reply</a></div>
</div>
<ul class="children">
<li class="comment odd alt depth-2 parent" id="comment-27543">
<div id="div-comment-27543" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://1.gravatar.com/avatar/a80ff35da226548293fa800b67e96be9?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://1.gravatar.com/avatar/a80ff35da226548293fa800b67e96be9?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">duc</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-27543">
December 31, 2013 at 6:44 am</a> </div>
<p>Thank you so much for your help, I used jsonlint to validate my JSON and it is valid, here is my hook:</p>
<p>#!/usr/bin/env node</p>
<p>//<br>
// This hook copies various resource files<br>
// from our version control system directories<br>
// into the appropriate platform specific location<br>
//</p>
<p>// configure all the files to copy.<br>
// Key of object is the source file,<br>
// value is the destination location.<br>
// It’s fine to put all platforms’ icons<br>
// and splash screen files here, even if<br>
// we don’t build for all platforms<br>
// on each developer’s box.</p>
<p>var filestocopy = [{<br>
“config/android/res/drawable/icon.png”:<br>
“platforms/android/res/drawable/icon.png”<br>
}, {<br>
“config/android/res/drawable-hdpi/icon.png”:<br>
“platforms/android/res/drawable-hdpi/icon.png”<br>
}, {<br>
“config/android/res/drawable-ldpi/icon.png”:<br>
“platforms/android/res/drawable-ldpi/icon.png”<br>
}, {<br>
“config/android/res/drawable-mdpi/icon.png”:<br>
“platforms/android/res/drawable-mdpi/icon.png”<br>
}, {<br>
“config/android/res/drawable-xhdpi/icon.png”:<br>
“platforms/android/res/drawable-xhdpi/icon.png”<br>
}, {<br>
“config/android/res/drawable/splash.png”:<br>
“platforms/android/res/drawable/splash.png”<br>
}, {<br>
“config/android/res/drawable-hdpi/splash.png”:<br>
“platforms/android/res/drawable-hdpi/splash.png”<br>
}, {<br>
“config/android/res/drawable-ldpi/splash.png”:<br>
“platforms/android/res/drawable-ldpi/splash.png”<br>
}, {<br>
“config/android/res/drawable-mdpi/splash.png”:<br>
“platforms/android/res/drawable-mdpi/splash.png”<br>
}, {<br>
“config/android/res/drawable-xhdpi/splash.png”:<br>
“platforms/android/res/drawable-xhdpi/splash.png”<br>
}];</p>
<p>var fs = require(‘fs’);<br>
var path = require(‘path’);</p>
<p>// no need to configure below<br>
var rootdir = process.argv[2];</p>
<p>filestocopy.forEach(function(obj) {<br>
Object.keys(obj).forEach(function(key) {<br>
var val = obj[key];<br>
var srcfile = path.join(rootdir, key);<br>
var destfile = path.join(rootdir, val);<br>
console.log(“copying “+srcfile+” to “+destfile);<br>
var destdir = path.dirname(destfile);<br>
if (fs.existsSync(srcfile) &amp;&amp; fs.existsSync(destdir)) {<br>
fs.createReadStream(srcfile).pipe(<br>
fs.createWriteStream(destfile));<br>
}<br>
});<br>
});</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=27543#respond" onclick="return addComment.moveForm( &quot;div-comment-27543&quot;, &quot;27543&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to duc">Reply</a></div>
</div>
<ul class="children">
<li class="comment even depth-3" id="comment-27659">
<div id="div-comment-27659" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/https://leanpub.com/developingwithcordovacli/" rel="external nofollow" class="url">Dan Moore</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-27659">
January 1, 2014 at 10:02 pm</a> </div>
<p>Hmmm… I tried to recreate your issue. I’m on windows 7, with cordova installed locally.</p>
<p>Here’s my version:<br>
C:\node\project\testapp&gt;..\..\node_modules\cordova\bin\cordova -v<br>
3.3.1-0.1.2</p>
<p>I put the hook in the before_platform_ls directory and was unable to replicate your issue.</p>
<p>Here’s the output:</p>
<p>C:\node\project\testapp&gt;..\..\node_modules\cordova\bin\cordova -d platforms ls</p>
<p>Executing hook “”node” “C:\node\project\testapp\.cordova\hooks\before_platform_ls\hook” “C:\node\project\testapp””<br>
rootdir C:\node\project\testapp<br>
copyingC:\node\project\testapp\config\android\res\drawable\icon.png to C:\node\project\testapp\platforms\android\res\drawable\icon.png</p>
<p>Installed platforms: android<br>
Available platforms: blackberry10, firefoxos, wp7, wp8, windows8</p>
<p>And here’s my script (‘hook’):</p>
<p>#!/usr/bin/env node</p>
<p>var fs = require(‘fs’);<br>
var path = require(‘path’);</p>
<p>var filestocopy = [{<br>
“config/android/res/drawable/icon.png”:<br>
“platforms/android/res/drawable/icon.png”<br>
}];</p>
<p>// no need to configure below<br>
var rootdir = process.argv[2];</p>
<p>filestocopy.forEach(function(obj) {<br>
Object.keys(obj).forEach(function(key) {<br>
var val = obj[key];<br>
var srcfile = path.join(rootdir, key);<br>
var destfile = path.join(rootdir, val);<br>
console.log(‘rootdir ‘ +rootdir);<br>
console.log(‘copying’ +srcfile+’ to ‘+destfile);<br>
var destdir = path.dirname(destfile);<br>
if (fs.existsSync(srcfile) &amp;&amp; fs.existsSync(destdir)) {<br>
fs.createReadStream(srcfile).pipe(<br>
fs.createWriteStream(destfile));<br>
}<br>
});<br>
});</p>
<p>Can you try my script and see if it works for you? What version of cordova are you using?</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=27659#respond" onclick="return addComment.moveForm( &quot;div-comment-27659&quot;, &quot;27659&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Dan Moore">Reply</a></div>
</div>
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
<li class="comment odd alt thread-even depth-1 parent" id="comment-28057">
<div id="div-comment-28057" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/304f37eac42ed74cc916004e7e4cbc90?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/304f37eac42ed74cc916004e7e4cbc90?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">ben funnell</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-28057">
January 15, 2014 at 12:39 am</a> </div>
<p>Great article, very useful. May I suggest an update to the replace text hook?</p>
<p>Instead of hard coding the replace lines, loop through the items in project.json like so:</p>
<p>for (var i in configobj[target]) {<br>
replace_string_in_file(fullfilename, “/\\*REP\\*/ ‘”+i+”‘ /\\*REP\\*/”, configobj[target][i]);<br>
}</p>
<p>that way only project.json needs to be updated to add new strings to be replaced.</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=28057#respond" onclick="return addComment.moveForm( &quot;div-comment-28057&quot;, &quot;28057&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to ben funnell">Reply</a></div>
</div>
<ul class="children">
<li class="comment even depth-2 parent" id="comment-28115">
<div id="div-comment-28115" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/http://leanpub.com/developingwithcordovacli/" rel="external nofollow" class="url">Dan Moore</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-28115">
January 18, 2014 at 1:14 pm</a> </div>
<p>Ben,</p>
<p>I think that’s a great shorthand, but then the default string serves two purposes. It is the key in the .json file, so it needs to document what is doing (especially since you can’t have comments in json files), and it has to be a valid value for browser tests or any other situation where you want to run right out of the www directory without doing any hook processing. So, this is the project.json file for my example that would work with your code:</p>
<p>{<br>
“stage”:<br>
{<br>
“‘api.example.com'” : “‘qa-api.mydomain.com'”<br>
},<br>
“prod”:<br>
{<br>
“‘api.example.com'” : “‘api.mydomain.com'”<br>
}<br>
}</p>
<p>As a developer, it isn’t clear what api.example.com is–and this would be more confusing if you pulled data from multiple hosts.</p>
<p>But it’s a tradeoff–I definitely appreciate that one wouldn’t have to update the hook to add new replace tokens.</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=28115#respond" onclick="return addComment.moveForm( &quot;div-comment-28115&quot;, &quot;28115&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Dan Moore">Reply</a></div>
</div>
<ul class="children">
<li class="comment odd alt depth-3 parent" id="comment-28145">
<div id="div-comment-28145" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/304f37eac42ed74cc916004e7e4cbc90?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/304f37eac42ed74cc916004e7e4cbc90?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">ben funnell</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-28145">
January 20, 2014 at 7:55 pm</a> </div>
<p>If you use a different key, replace ‘api.example.com’ with a more descriptive key like ‘authentication.api.url’ then comments get built into the json file.</p>
<p>This is the naming convention i have used in my build. This change came up when I added a new entry to project.json but had forgotten that I needed to touch the hook code and was wondering why it wasn’t working.</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=28145#respond" onclick="return addComment.moveForm( &quot;div-comment-28145&quot;, &quot;28145&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to ben funnell">Reply</a></div>
</div>
<ul class="children">
<li class="comment even depth-4 parent" id="comment-28157">
<div id="div-comment-28157" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/http://leanpub.com/developingwithcordovacli/" rel="external nofollow" class="url">Dan Moore</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-28157">
January 21, 2014 at 8:21 am</a> </div>
<p>Hmmm… Do you ever do development against the code in project/www, like a browser or ripple? If you did, you’d have an issue with trying to reach a server with an address of ‘authentication.api.url’, no?</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=28157#respond" onclick="return addComment.moveForm( &quot;div-comment-28157&quot;, &quot;28157&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Dan Moore">Reply</a></div>
</div>
<ul class="children">
<li class="comment odd alt depth-5" id="comment-28168">
<div id="div-comment-28168" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/304f37eac42ed74cc916004e7e4cbc90?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/304f37eac42ed74cc916004e7e4cbc90?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">ben funnell</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-28168">
January 21, 2014 at 11:59 pm</a> </div>
<p>no that’s not part of my (current) workflow, I tend to build straight to a phone for testing. I see your point though… keen to look at ripple now.</p>
</div>
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
<li class="comment even thread-odd thread-alt depth-1 parent" id="comment-28169">
<div id="div-comment-28169" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/304f37eac42ed74cc916004e7e4cbc90?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/304f37eac42ed74cc916004e7e4cbc90?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">ben funnell</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-28169">
January 22, 2014 at 12:01 am</a> </div>
<p>or I would if it ran in windows…</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=28169#respond" onclick="return addComment.moveForm( &quot;div-comment-28169&quot;, &quot;28169&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to ben funnell">Reply</a></div>
</div>
<ul class="children">
<li class="comment odd alt depth-2" id="comment-28177">
<div id="div-comment-28177" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/http://leanpub.com/developingwithcordovacli/" rel="external nofollow" class="url">Dan</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-28177">
January 22, 2014 at 6:08 am</a> </div>
<p>Hi Ben,</p>
<p>I thought it did run on Windows, though I haven’t used it there.</p>
<p>Here is a video that may be useful: <a href="https://web.archive.org/web/20180803132745/http://www.raymondcamden.com/index.cfm/2014/1/17/Installing-and-Using-Ripple-for-Cordova-Development-A-Video" rel="nofollow">http://www.raymondcamden.com/index.cfm/2014/1/17/Installing-and-Using-Ripple-for-Cordova-Development-A-Video</a></p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=28177#respond" onclick="return addComment.moveForm( &quot;div-comment-28177&quot;, &quot;28177&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Dan">Reply</a></div>
</div>
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
<li class="comment even thread-even depth-1" id="comment-28222">
<div id="div-comment-28222" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/5a4fba0742311451f464ac1acf1556e1?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/5a4fba0742311451f464ac1acf1556e1?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">Jon</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-28222">
January 24, 2014 at 12:58 pm</a> </div>
<p>I took the bottom hook script which copies resources hard coded in a list and changed it to copy everything in your config file. Hope it helps someone:</p>
<p>#!/usr/bin/env node</p>
<p>/**<br>
* COPIED FROM <a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/" rel="nofollow">http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/</a><br>
*/</p>
<p>/**<br>
* This hook copies all files in the config folder into the similar<br>
* file structure in the appropriate platform resources folder.<br>
*<br>
* eg. All folders/files from /config/ios/Resources/*<br>
* are moved to /platforms/ios/YourApp/Resources/*<br>
*/</p>
<p>var fs = require(‘fs’);<br>
var path = require(‘path’);</p>
<p>var appName = “YourApp”;</p>
<p>// no need to configure below<br>
var rootdir = process.argv[2];</p>
<p>//loop through all files in the config directory<br>
var platformConfigs = fs.readdirSync(rootdir+”/config”);</p>
<p>platformConfigs.forEach(function(platformName) {<br>
//ignore hidden files<br>
if(platformName[0] != “.”) {<br>
//look copy all files from this config/Resources folds into the appropriate platform<br>
var resourcePath = path.join(rootdir+”/config”, platformName+”/Resources”);<br>
fs.readdirSync(resourcePath).forEach(function(resourceType){<br>
//again ignore hidden files<br>
if(resourceType[0] != “.”) {<br>
var resourceTypePath = path.join(resourcePath, resourceType);<br>
fs.readdirSync(resourceTypePath).forEach(function(fileName){<br>
var srcfile = path.join(resourceTypePath, fileName);<br>
//determine destination location<br>
var destLocation = “platforms/”+platformName+”/”+appName+”/Resources/”+resourceType+”/”+fileName;<br>
var destfile = path.join(rootdir, destLocation);</p>
<p> //console.log(“copying “+srcfile+” to “+destfile);</p>
<p> if (fs.existsSync(srcfile) &amp;&amp; fs.existsSync(destfile)) {<br>
fs.createReadStream(srcfile).pipe(<br>
fs.createWriteStream(destfile));<br>
}</p>
<p> });<br>
}<br>
});<br>
}<br>
});</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=28222#respond" onclick="return addComment.moveForm( &quot;div-comment-28222&quot;, &quot;28222&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Jon">Reply</a></div>
</div>
</li><!-- #comment-## -->
<li class="comment odd alt thread-odd thread-alt depth-1 parent" id="comment-28228">
<div id="div-comment-28228" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/0a3a8fadc33d2d4cc2489ef0bb9f793b?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/0a3a8fadc33d2d4cc2489ef0bb9f793b?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">Mobile Girl</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-28228">
January 24, 2014 at 5:29 pm</a> </div>
<p>Great Post!</p>
<p>I have a question. If I run “Cordova platform rm iOS” command through terminal, Cordova CLI is also removing iOS folder from merges directory. Phonegap’s documentation says that Platform-specific web assets (HTML, CSS and JavaScript files) are contained within appropriate subfolders in merges directory. What am I doing wrong?</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=28228#respond" onclick="return addComment.moveForm( &quot;div-comment-28228&quot;, &quot;28228&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Mobile Girl">Reply</a></div>
</div>
<ul class="children">
<li class="comment even depth-2 parent" id="comment-28296">
<div id="div-comment-28296" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/https://leanpub.com/developingwithcordovacli/" rel="external nofollow" class="url">Dan Moore</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-28296">
January 26, 2014 at 8:41 pm</a> </div>
<p>Hi,</p>
<p>I’m not familiar with that behavior. I’ve never seen it. I would probably look through the apache jira: <a href="https://web.archive.org/web/20180803132745/https://issues.apache.org/jira/browse/CB&lrm;" rel="nofollow">https://issues.apache.org/jira/browse/CB&lrm;</a><br>
or stack overflow and see if anyone else is having these issues for the version of cordova cli that you have.</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=28296#respond" onclick="return addComment.moveForm( &quot;div-comment-28296&quot;, &quot;28296&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Dan Moore">Reply</a></div>
</div>
<ul class="children">
<li class="comment odd alt depth-3" id="comment-28321">
<div id="div-comment-28321" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/0a3a8fadc33d2d4cc2489ef0bb9f793b?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/0a3a8fadc33d2d4cc2489ef0bb9f793b?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">Mobile Girl</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-28321">
January 27, 2014 at 6:13 pm</a> </div>
<p>This issue has been fixed as part of 3.3.1-0.2.0 merge to master branch Cordova CLI:</p>
<p><a href="https://web.archive.org/web/20180803132745/https://github.com/apache/cordova-cli/pull/118" rel="nofollow">https://github.com/apache/cordova-cli/pull/118</a></p>
<p>In order to get latest version of cordova CLI , please follow “Installing from Master” instructions on following URL:</p>
<p><a href="https://web.archive.org/web/20180803132745/https://github.com/apache/cordova-cli" rel="nofollow">https://github.com/apache/cordova-cli</a></p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=28321#respond" onclick="return addComment.moveForm( &quot;div-comment-28321&quot;, &quot;28321&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Mobile Girl">Reply</a></div>
</div>
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
<li class="comment even thread-even depth-1" id="comment-28283">
<div id="div-comment-28283" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/bdb6c69bfe51b66861faefba2309a262?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/bdb6c69bfe51b66861faefba2309a262?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/http://www.flywheel.com/" rel="external nofollow" class="url">Rami Hadi</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-28283">
January 26, 2014 at 5:04 am</a> </div>
<p>Amazing ! </p>
<p>I have question , If I need to call cordova module library from node.js app which mean I won’t call it from cmd to build application for me , I need to call it inside my node.js app , how can I do it . </p>
<p>everyone post how to build phonegap using CLI but no one mention how we can call these function in Node.js</p>
<p>Thank you .</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=28283#respond" onclick="return addComment.moveForm( &quot;div-comment-28283&quot;, &quot;28283&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Rami Hadi">Reply</a></div>
</div>
</li><!-- #comment-## -->
<li class="comment odd alt thread-odd thread-alt depth-1" id="comment-28309">
<div id="div-comment-28309" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/674939b8eca811fe24855663f2f23a3e?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/674939b8eca811fe24855663f2f23a3e?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/http://www.eekay.nl/" rel="external nofollow" class="url">Edwin Klesman</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-28309">
January 27, 2014 at 8:05 am</a> </div>
<p>Hey Holly,</p>
<p>Thanks for the splash/icon hookup script. Also, for making clear that these aren’t going to be copied automagically with the current Cordova CLI implementation!</p>
<p>Only thing I can add is that I needed to make the hookup script executable using chmod +x 010_resource_files.js and that this runs my file like a puppy on fire!</p>
<p>No more custom copying each time. </p>
<p>Btw: if you like Flipboard to keep up to date; I have a (Cross Platform) Mobile App Developer magazine called “EeKay’s Mobile App Developer Magazine” which has lots of mobile content for mobile devs (either native, Xamarin or Phonegap for iOS, Android and W(P)8 apps) cheers!</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=28309#respond" onclick="return addComment.moveForm( &quot;div-comment-28309&quot;, &quot;28309&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Edwin Klesman">Reply</a></div>
</div>
</li><!-- #comment-## -->
<li class="comment even thread-even depth-1 parent" id="comment-28459">
<div id="div-comment-28459" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://1.gravatar.com/avatar/d2444ce0b7492b2b0402fd6e15787b4d?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://1.gravatar.com/avatar/d2444ce0b7492b2b0402fd6e15787b4d?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">supertramp</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-28459">
February 5, 2014 at 12:25 pm</a> </div>
<p>Thanks for the amazing article !</p>
<p>I have question. . How can i get command arguments in hook script?<br>
If i execute “cordova prepare ios” command then how can i get “ios” parameter in “before_prepare” hook ?</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=28459#respond" onclick="return addComment.moveForm( &quot;div-comment-28459&quot;, &quot;28459&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to supertramp">Reply</a></div>
</div>
<ul class="children">
<li class="comment odd alt depth-2 parent" id="comment-28460">
<div id="div-comment-28460" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/http://leanpub.com/developingwithcordovacli/" rel="external nofollow" class="url">Dan Moore</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-28460">
February 5, 2014 at 12:56 pm</a> </div>
<p>Hi supertramp,</p>
<p>At this time it is not possible. </p>
<p>Looks like it is an existing enhancement request which will be released soon:</p>
<p><a href="https://web.archive.org/web/20180803132745/https://issues.apache.org/jira/browse/CB-4382" rel="nofollow">https://issues.apache.org/jira/browse/CB-4382</a></p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=28460#respond" onclick="return addComment.moveForm( &quot;div-comment-28460&quot;, &quot;28460&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Dan Moore">Reply</a></div>
</div>
<ul class="children">
<li class="comment even depth-3" id="comment-28470">
<div id="div-comment-28470" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://1.gravatar.com/avatar/d2444ce0b7492b2b0402fd6e15787b4d?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://1.gravatar.com/avatar/d2444ce0b7492b2b0402fd6e15787b4d?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">supertramp</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-28470">
February 6, 2014 at 12:07 am</a> </div>
<p>Hi Dan,</p>
<p>I think i got it.<br>
As per <a href="https://web.archive.org/web/20180803132745/https://issues.apache.org/jira/browse/CB-4382" rel="nofollow">https://issues.apache.org/jira/browse/CB-4382</a>,<br>
After cordova cli 3.3.0-rc.1, you will able to get platform information using “Environment Variables”<br>
ex: process.env.CORDOVA_PLATFORMS</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=28470#respond" onclick="return addComment.moveForm( &quot;div-comment-28470&quot;, &quot;28470&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to supertramp">Reply</a></div>
</div>
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
<li class="comment odd alt thread-odd thread-alt depth-1 parent" id="comment-28478">
<div id="div-comment-28478" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/0a3a8fadc33d2d4cc2489ef0bb9f793b?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/0a3a8fadc33d2d4cc2489ef0bb9f793b?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">MobileDev</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-28478">
February 6, 2014 at 3:35 pm</a> </div>
<p>How do you retain the project level settings for cordova Android projects? Platforms folder removes project level setting when you run ‘cordova platform rm android’</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=28478#respond" onclick="return addComment.moveForm( &quot;div-comment-28478&quot;, &quot;28478&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to MobileDev">Reply</a></div>
</div>
<ul class="children">
<li class="comment even depth-2 parent" id="comment-28479">
<div id="div-comment-28479" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/http://leanpub.com/developingwithcordovacli/" rel="external nofollow" class="url">Dan Moore</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-28479">
February 6, 2014 at 4:59 pm</a> </div>
<p>It depends on what ‘project level settings’ you are talking about. There are a couple of different ways.</p>
<p>You need to either:<br>
* only modify your project in ways that can be expressed in config.xml<br>
or<br>
* write an after_platform_add hook which copies your changes over (if you have a modified .java file for example)<br>
or<br>
* write a plugin which modifies any XML files (AndroidManifest.xml) to insert your needed project level config, and add that plugin to your project every time.</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=28479#respond" onclick="return addComment.moveForm( &quot;div-comment-28479&quot;, &quot;28479&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Dan Moore">Reply</a></div>
</div>
<ul class="children">
<li class="comment odd alt depth-3" id="comment-28480">
<div id="div-comment-28480" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/http://leanpub.com/developingwithcordovacli/" rel="external nofollow" class="url">Dan Moore</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-28480">
February 6, 2014 at 5:52 pm</a> </div>
<p>Or, I suppose you could version control the platforms/android directory, but in this case I wouldn’t use cordova cli.</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=28480#respond" onclick="return addComment.moveForm( &quot;div-comment-28480&quot;, &quot;28480&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Dan Moore">Reply</a></div>
</div>
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
<li class="comment even thread-even depth-1" id="comment-29787">
<div id="div-comment-29787" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://1.gravatar.com/avatar/1363c0a6234431c91937ff2a5e804cf0?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://1.gravatar.com/avatar/1363c0a6234431c91937ff2a5e804cf0?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/http://gethiyu.com/" rel="external nofollow" class="url">Daniel Roizman</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-29787">
March 12, 2014 at 3:11 am</a> </div>
<p>I ran into an issue with the plug-ins hook running after_platform_add . For IOS, it seems like there might be some race conditions because each time I would create my project, I would get a random subset of the plug-ins getting initialized properly in the xcode project. Some were there, others were not. The src code was installed, but just not added to the project file.</p>
<p>So, simple solution was to use the hook before_platform_add . </p>
<p>Also, I needed to build the project via cordova build ios BEFORE I could open it in XCode and compile. Otherwise XCode had a ton of linker errors.</p>
<p>End of the day, these scripts are amazing helpers and a big thank you for putting them out there and explaining the hook system.</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=29787#respond" onclick="return addComment.moveForm( &quot;div-comment-29787&quot;, &quot;29787&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Daniel Roizman">Reply</a></div>
</div>
</li><!-- #comment-## -->
<li class="comment odd alt thread-odd thread-alt depth-1" id="comment-31182">
<div id="div-comment-31182" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/24397eb2d98e0275df4dd53f34d4935a?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/24397eb2d98e0275df4dd53f34d4935a?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">Anthony</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-31182">
April 2, 2014 at 1:55 pm</a> </div>
<p>Sweet! Auto add splash and icons hook for the win!</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=31182#respond" onclick="return addComment.moveForm( &quot;div-comment-31182&quot;, &quot;31182&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Anthony">Reply</a></div>
</div>
</li><!-- #comment-## -->
<li class="comment even thread-even depth-1" id="comment-31473">
<div id="div-comment-31473" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/24397eb2d98e0275df4dd53f34d4935a?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/24397eb2d98e0275df4dd53f34d4935a?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">Anthony</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-31473">
April 4, 2014 at 10:42 pm</a> </div>
<p>Hey Dan,</p>
<p>I was looking for a way to add platform specific xml to the platform specific config.xml from my top-level config.xml. </p>
<p>If I am getting this correct, my platform specific config.xml files are re-generated at build-time. </p>
<p>Is this possible? That is, say to add a preference to the iOS config but not the Android config file.</p>
<p>Thanks! Awesome blogs!</p>
<p>~Anthony</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=31473#respond" onclick="return addComment.moveForm( &quot;div-comment-31473&quot;, &quot;31473&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Anthony">Reply</a></div>
</div>
</li><!-- #comment-## -->
<li class="comment odd alt thread-odd thread-alt depth-1 parent" id="comment-31853">
<div id="div-comment-31853" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/31ba4e8d2b8d9c4e39d009efe6b83f86?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/31ba4e8d2b8d9c4e39d009efe6b83f86?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">Sean McAuliffe</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-31853">
April 8, 2014 at 3:31 pm</a> </div>
<p>Thanks for these. The plugins install is problematic when adding more than one platform. Works the first time, then sees them as already installed. Unless there’s a way to add multiple platforms at once – not sure. Maybe installing via plugman is better? Not sure how that works but will look into and update if I get anywhere. Thanks again.</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=31853#respond" onclick="return addComment.moveForm( &quot;div-comment-31853&quot;, &quot;31853&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Sean McAuliffe">Reply</a></div>
</div>
<ul class="children">
<li class="comment even depth-2" id="comment-31855">
<div id="div-comment-31855" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/c9e7a8e73cd575adbd87a6d6d18505b9?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/http://leanpub.com/developingwithcordovacli/" rel="external nofollow" class="url">Dan</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-31855">
April 8, 2014 at 3:43 pm</a> </div>
<p>Hi Sean,</p>
<p>Hmmm… I’m not sure I ever tested this code on one machine with two different cordova supported cordova platforms. </p>
<p>Hooks (as of 3.3.1-0.4.2) now send you the platform the command is being executed for: <a href="https://web.archive.org/web/20180803132745/http://www.mooreds.com/wordpress/archives/1425" rel="nofollow">http://www.mooreds.com/wordpress/archives/1425</a> </p>
<p>But I’m not sure how that helps you. Please let us know if you come up with a solution.</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=31855#respond" onclick="return addComment.moveForm( &quot;div-comment-31855&quot;, &quot;31855&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Dan">Reply</a></div>
</div>
</li><!-- #comment-## -->
<li class="comment odd alt depth-2" id="comment-31856">
<div id="div-comment-31856" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://1.gravatar.com/avatar/1363c0a6234431c91937ff2a5e804cf0?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://1.gravatar.com/avatar/1363c0a6234431c91937ff2a5e804cf0?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/http://gethiyu.com/" rel="external nofollow" class="url">Daniel Roizman</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-31856">
April 8, 2014 at 3:53 pm</a> </div>
<p>When you install a plugin, it copies all the source code over for all platforms and sticks it in the plugins folder. So it is correct that it is already there. When you add the platform, it copies over the src files for just that platform. It also leaves behind a platform.json file in the plugins folder that keeps a record of what was installed. So you would have android.json and ios.json. </p>
<p>I think my experience says that if you add plugins after you’ve created your platform, they don’t install. I usually delete the platform.json file and then run the add platform again.</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=31856#respond" onclick="return addComment.moveForm( &quot;div-comment-31856&quot;, &quot;31856&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Daniel Roizman">Reply</a></div>
</div>
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
<li class="comment even thread-even depth-1" id="comment-80936">
<div id="div-comment-80936" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://1.gravatar.com/avatar/d1c7a8deaa1b9d3c45dcbec5a764880c?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://1.gravatar.com/avatar/d1c7a8deaa1b9d3c45dcbec5a764880c?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/http://intown.biz/" rel="external nofollow" class="url">Michael Mendelson</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-80936">
May 13, 2014 at 8:16 am</a> </div>
<p>Dan, thanks for this excellent blog post. I documented an additional hook (for configuration settings) that might be useful to somebody: <a href="https://web.archive.org/web/20180803132745/http://intown.biz/2014/05/13/build-configurations-in-cordova-using-hooks/" rel="nofollow">http://intown.biz/2014/05/13/build-configurations-in-cordova-using-hooks/</a></p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=80936#respond" onclick="return addComment.moveForm( &quot;div-comment-80936&quot;, &quot;80936&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Michael Mendelson">Reply</a></div>
</div>
</li><!-- #comment-## -->
<li class="comment odd alt thread-odd thread-alt depth-1" id="comment-296997">
<div id="div-comment-296997" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/ee060db7e04e5f29a8a98a8ab91ed6cd?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/ee060db7e04e5f29a8a98a8ab91ed6cd?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">Gordon Sun</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-296997">
August 12, 2014 at 3:36 am</a> </div>
<p>For me, the after_platform_add script in this post does not work 100% correctly.<br>
It will install plugins in parallel and break plugin/ios.json or plugin/android.json<br>
Resulting in these files missing plugins and makes the project broke.<br>
I had to write a thing like this in the for loop<br>
var newTime = new Date().getTime();<br>
while(true) {<br>
var newTime2 = new Date().getTime();<br>
if (newTime2 – newTime &gt; 3000) {<br>
break;<br>
}<br>
} </p>
<p>To break for 3 seconds between each install.<br>
This is not ideal. A bash script would be much better</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=296997#respond" onclick="return addComment.moveForm( &quot;div-comment-296997&quot;, &quot;296997&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Gordon Sun">Reply</a></div>
</div>
</li><!-- #comment-## -->
<li class="comment even thread-even depth-1" id="comment-332073">
<div id="div-comment-332073" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/bf18de6b505f57b47b069870be3464c9?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/bf18de6b505f57b47b069870be3464c9?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/http://luke.sno.wden.co.uk/" rel="external nofollow" class="url">Luke Snowden</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-332073">
August 21, 2014 at 2:41 am</a> </div>
<p>Currently getting error execvp(): Permission denied any help?</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=332073#respond" onclick="return addComment.moveForm( &quot;div-comment-332073&quot;, &quot;332073&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Luke Snowden">Reply</a></div>
</div>
</li><!-- #comment-## -->
<li class="comment odd alt thread-odd thread-alt depth-1" id="comment-336278">
<div id="div-comment-336278" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/bf18de6b505f57b47b069870be3464c9?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/bf18de6b505f57b47b069870be3464c9?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn"><a href="https://web.archive.org/web/20180803132745/http://luke.sno.wden.co.uk/" rel="external nofollow" class="url">Luke Snowden</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-336278">
August 22, 2014 at 6:25 am</a> </div>
<p>chmod -R 777 before_prepare<br>
if anyone else has this issue</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=336278#respond" onclick="return addComment.moveForm( &quot;div-comment-336278&quot;, &quot;336278&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Luke Snowden">Reply</a></div>
</div>
</li><!-- #comment-## -->
<li class="comment even thread-even depth-1" id="comment-463869">
<div id="div-comment-463869" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/ce9b5cb13d1b0870d71629d2135ccb2b?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://0.gravatar.com/avatar/ce9b5cb13d1b0870d71629d2135ccb2b?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">Ivan</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-463869">
September 22, 2014 at 2:49 am</a> </div>
<p>Hi Devgirl,</p>
<p>Thanks for your hooks – especially copying icon files .<br>
But i dislike path “”platforms/ios/YourAppName/Resources/icons/icon-72.png””<br>
Your AppName – why my application name is present in file system?</p>
<p>How can i unlink application name from directory name?<br>
I didn’t found separate attribute in config.xml . and maybe there is some hook.<br>
Thanks</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=463869#respond" onclick="return addComment.moveForm( &quot;div-comment-463869&quot;, &quot;463869&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Ivan">Reply</a></div>
</div>
</li><!-- #comment-## -->
<li class="comment odd alt thread-odd thread-alt depth-1" id="comment-508640">
<div id="div-comment-508640" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://1.gravatar.com/avatar/7dd635b50403fb40499f2001b85deb57?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://1.gravatar.com/avatar/7dd635b50403fb40499f2001b85deb57?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">Felipe</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-508640">
September 29, 2014 at 9:05 am</a> </div>
<p>Muchas gracias por los hooks, sobretodo por el “Copy Icons and Splashscreens”, me facilitó mucho las cosas.<br>
Gracias</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=508640#respond" onclick="return addComment.moveForm( &quot;div-comment-508640&quot;, &quot;508640&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Felipe">Reply</a></div>
</div>
</li><!-- #comment-## -->
<li class="comment even thread-even depth-1" id="comment-1217030">
<div id="div-comment-1217030" class="comment-body">
<div class="comment-author vcard">
<img alt="" src="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/81bd99ddcee0d8eb04a2decb8e447af1?s=60&amp;d=mm&amp;r=g" srcset="https://web.archive.org/web/20180803132745im_/http://2.gravatar.com/avatar/81bd99ddcee0d8eb04a2decb8e447af1?s=120&amp;d=mm&amp;r=g 2x" class="avatar avatar-60 photo" height="60" width="60"> <cite class="fn">Ike</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#comment-1217030">
February 3, 2015 at 2:18 pm</a> </div>
<p>Replace Text depending on Envioronment. If I can get this working this would save me tons of time, but I am not sure of this part “Add tokens to files in your www directory for each environment dependent variable” Where am I adding the tokens? </p>
<p>I am new to phonegap so excuse my ignorance.</p>
<p>Ike</p>
<div class="reply"><a rel="nofollow" class="comment-reply-link" href="https://web.archive.org/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/?replytocom=1217030#respond" onclick="return addComment.moveForm( &quot;div-comment-1217030&quot;, &quot;1217030&quot;, &quot;respond&quot;, &quot;6385&quot; )" aria-label="Reply to Ike">Reply</a></div>
</div>
</li><!-- #comment-## -->
</ol>
</div>
<div id="respond">
<form action="https://web.archive.org/web/20180803132745/http://devgirl.org/wp-comments-post.php" method="post" id="commentform">
<h3>Leave a Reply</h3>
<div class="cancel-comment-reply">
<a rel="nofollow" id="cancel-comment-reply-link" href="/web/20180803132745/http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/#respond" style="display:none;">Click here to cancel reply.</a> </div>
<p><input type="text" name="author" id="author" value="" size="40" tabindex="1">
<label for="author">Name ( required )</label></p>
<p><input type="text" name="email" id="email" value="" size="40" tabindex="2">
<label for="email">Email ( required )</label></p>
<p><input type="text" name="url" id="url" value="" size="40" tabindex="3">
<label for="url">Website</label></p>
<!--<p><small><strong>XHTML:</strong> You can use these tags: <code>&lt;a href=&quot;&quot; title=&quot;&quot;&gt; &lt;abbr title=&quot;&quot;&gt; &lt;acronym title=&quot;&quot;&gt; &lt;b&gt; &lt;blockquote cite=&quot;&quot;&gt; &lt;cite&gt; &lt;code&gt; &lt;del datetime=&quot;&quot;&gt; &lt;em&gt; &lt;i&gt; &lt;q cite=&quot;&quot;&gt; &lt;s&gt; &lt;strike&gt; &lt;strong&gt; </code></small></p>-->
<p><textarea name="comment" id="comment" cols="100%" rows="10" tabindex="4"></textarea></p>
<p class="button-submit"><input name="submit" type="submit" id="submit" tabindex="5" value="Submit Comment">
<input type="hidden" name="comment_post_ID" value="6385" id="comment_post_ID">
<input type="hidden" name="comment_parent" id="comment_parent" value="0">
</p>
<p style="display: none;"><input type="hidden" id="akismet_comment_nonce" name="akismet_comment_nonce" value="2ffbab5d3f"></p><p style="clear: both;" class="subscribe-to-comments">
<input type="checkbox" name="subscribe" id="subscribe" value="subscribe" style="width: auto;">
<label for="subscribe">Notify me of followup comments via e-mail</label>
</p><p style="display: none;"></p>
<input type="hidden" id="ak_js" name="ak_js" value="1557758627510"></form>
</div>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment