{ "id": "133363", "key": "ALOY-1118", "fields": { "issuetype": { "id": "2", "description": "A new feature of the product, which has yet to be developed.", "name": "New Feature", "subtask": false }, "project": { "id": "11113", "key": "ALOY", "name": "Alloy", "projectCategory": { "id": "10400", "description": "Tools for developing applications", "name": "Tooling" } }, "fixVersions": [ { "id": "16692", "name": "Alloy 1.7.0", "archived": false, "released": true, "releaseDate": "2015-07-22" } ], "resolution": { "id": "2", "description": "The problem described is an issue which will never be fixed.", "name": "Won't Fix" }, "resolutiondate": "2015-02-04T14:39:51.000+0000", "created": "2014-07-18T06:57:23.000+0000", "priority": { "name": "Medium", "id": "3" }, "labels": [ "themes", "tiapp.xml" ], "versions": [], "issuelinks": [ { "id": "40210", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "outwardIssue": { "id": "121538", "key": "ALOY-858", "fields": { "summary": "Alloy: Theme \"i18n\" and \"platform\" folders", "status": { "description": "A resolution has been taken, and it is awaiting verification by reporter. From here issues are either reopened, or are closed.", "name": "Resolved", "id": "5", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "priority": { "name": "Medium", "id": "3" }, "issuetype": { "id": "2", "description": "A new feature of the product, which has yet to be developed.", "name": "New Feature", "subtask": false } } } } ], "assignee": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "updated": "2015-02-04T14:39:52.000+0000", "status": { "description": "A resolution has been taken, and it is awaiting verification by reporter. From here issues are either reopened, or are closed.", "name": "Resolved", "id": "5", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "13603", "name": "Styling", "description": "TSS, dynamic styling, styling API" } ], "description": "Now Alloy supports theming of {{app/config.json}} and {{i18n}} and {{platforms}} on their way, the last thing to tackle for easily building branded apps of a white label codebase is \"theming\" {{tiapp.xml}}.\r\n\r\nThis might me the most challenging one, since I guess the CLI already reads some information from {{tiapp.xml}} before the first hook that Alloy uses is triggered. Also, it will require some serious smarts to know when to overwrite and when to append XML tags and attributes.", "attachment": [], "flagged": false, "summary": "Allow theming of tiapp.xml e.g. through Alloy themes", "creator": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "subtasks": [], "reporter": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "environment": null, "closedSprints": [ { "id": 319, "state": "closed", "name": "2015 Sprint 03 Tooling", "startDate": "2015-01-31T03:56:17.033Z", "endDate": "2015-02-14T02:30:00.000Z", "completeDate": "2015-02-14T02:18:47.439Z", "originBoardId": 121 } ], "comment": { "comments": [ { "id": "320279", "author": { "name": "mpmiranda", "key": "mpmiranda", "displayName": "Mauro Parra-Miranda", "active": true, "timeZone": "America/Mexico_City" }, "body": "Thanks for your report [~fokke]! [~tlukasavage]: can you please set [~fokke] as the reporter? The system still switches it to mover. ", "updateAuthor": { "name": "mpmiranda", "key": "mpmiranda", "displayName": "Mauro Parra-Miranda", "active": true, "timeZone": "America/Mexico_City" }, "created": "2014-08-26T04:59:27.000+0000", "updated": "2014-08-26T04:59:27.000+0000" }, { "id": "340748", "author": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "body": "This should be easily possible through the use of an Alloy JMK file. First-attempt resolution of this ticket should be the creation of a demonstration project using a JMK file to \"theme\" the tiapp.xml. Values to be changed per theme could be appid, guid, android map keys, and custom properties.\r\n\r\n(Incidentally, a grunt or gulp script could also easily accomplish the sorts of tiapp.xml customizations requested. As would https://github.com/jasonkneen/tich)", "updateAuthor": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "created": "2015-01-27T14:05:18.000+0000", "updated": "2015-01-27T14:05:18.000+0000" }, { "id": "341883", "author": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "body": "After playing with this for a bit, I've determined that neither the Alloy JMK or CLI hook is the solution to this. \r\n\r\nAlloy JMK files hook into the build process too late. By the time they run, the CLI has read and cached the tiapp.xml. Swapping out the file at that point has no effect on the resulting build process.\r\n\r\nThe CLI hooks don't have access to the necessary Alloy configuration information. (Such as the active theme.) While I could probably create a hook that reads in the config.json file, parses it, determines the theme, environment, etc. I think the resulting script would be a bit fragile.\r\n\r\nA reasonably simple solution is to use a grunt script.\r\n\r\nh3. Step 1: Install grunt-cli\r\n\r\n{{npm install -g grunt-cli}}\r\n\r\nh3. Step 2: In your project's directory, create a package.json file with contents like this:\r\n\r\n{code:title=package.json}\r\n{\r\n \"name\": \"YourAppName\",\r\n \"version\": \"1.0.0\",\r\n \"devDependencies\": {\r\n \"grunt\": \"~0.4.5\"\r\n }\r\n}\r\n{code}\r\n\r\nh3. Step 3: In your project's directory, run:\r\n\r\n{{npm install}}\r\n\r\nh3. Step 4: Create a file named Gruntfile.js in your project's directory. Copy the code below into it.\r\n\r\nh3. Step 5: Use the grunt script:\r\n\r\nFirst, put a copy of tiapp.xml into the app/themes/yourtheme folder and customize that copy as necessary. Then:\r\n\r\n{noformat}\r\n> grunt theme:active_theme_name // to swap in the theme's tiapp.xml\r\n> ti build -p ios ... // as needed to build your app\r\n> grunt reset // to restore the original tiapp.xml\r\n{noformat}\r\n\r\nAn exercise left to the reader is to implement the grunt-titanium plug-in to automate the building of the app.\r\n\r\n{code}\r\nvar fs = require('fs'),\r\n path = require('path');\r\n\r\nmodule.exports = function(grunt) {\r\n grunt.registerTask('theme', 'Swaps in a theme tiapp.xml', function(arg1) {\r\n if (arguments.length === 0) {\r\n grunt.log.writeln(\"You must pass the name of the theme in the form:\");\r\n grunt.log.writeln(\" grunt theme:foo\")\r\n } else {\r\n grunt.log.writeln(\"Applying theme \" + arg1);\r\n var projectDir = path.resolve('.');\r\n var themedir = path.join(projectDir, 'app', 'themes', arg1);\r\n if(fs.existsSync(path.join(themedir, 'tiapp.xml'))) {\r\n // And the active theme has a tiapp.xml, so we'll back up the original\r\n // and copy the theme's tiapp.xml over the original\r\n var tiappxml = path.join(projectDir, 'tiapp.xml');\r\n var origTiappxml = path.join(projectDir, 'tiapp_original.xml');\r\n if(!fs.existsSync(origTiappxml)) {\r\n // don't re-back up the original\r\n fs.renameSync(tiappxml, origTiappxml);\r\n }\r\n fs.writeFileSync(tiappxml, fs.readFileSync(path.join(themedir, 'tiapp.xml')));\r\n }\r\n }\r\n });\r\n\r\n grunt.registerTask('reset', 'Resets the original tiapp.xml', function() {\r\n grunt.log.writeln(\"Restoring original tiapp.xml\");\r\n var projectDir = path.resolve('.');\r\n // remove themed tiapp.xml\r\n fs.unlinkSync(path.join(projectDir, 'tiapp.xml'));\r\n // rename the backup\r\n fs.renameSync(path.join(projectDir, 'tiapp_original.xml'), path.join(projectDir, 'tiapp.xml'))\r\n });\r\n\r\n grunt.registerTask('default', ['theme']);\r\n};\r\n{code}", "updateAuthor": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "created": "2015-02-03T19:32:00.000+0000", "updated": "2015-02-03T19:48:00.000+0000" }, { "id": "342012", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "[~skypanther] As I wrote in the original ticket description, I was expecting this to be a chicken-egg problem already and I agree it should be handled via Grunt or alike. Instead of your solution to replace the {{tiapp.xml}} I would rather read the theme's {{config.json}} and then use Tony's {{tiapp.xml}} module to make specific changes, but that's just details. It might be a good subject for a blog post.", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2015-02-04T09:23:12.000+0000", "updated": "2015-02-04T09:23:12.000+0000" }, { "id": "342033", "author": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "body": "Resolving as Won't Fix because we'll resolve this through a blog post describing how to use a build automation tool to accomplish the goal.", "updateAuthor": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "created": "2015-02-04T14:39:52.000+0000", "updated": "2015-02-04T14:39:52.000+0000" } ], "maxResults": 5, "total": 5, "startAt": 0 } } }