| name | alloy-howtos |
| description | Use when an Alloy MVC project needs help with the Alloy CLI (`alloy new`, `alloy generate`, `alloy compile`, `alloy extract-i18n`), configuration files (`alloy.jmk` build hooks, `config.json` env/platform precedence, `widget.json`), conditional views (`if=` attribute in XML/TSS), custom XML tags via `app/lib/`, Backbone.Events for cross-controller communication, or debugging Alloy compilation errors. Triggers include `app/views/` + `app/controllers/`, `alloy.jmk`, or `config.json` in the project root. |
alloy-howtos
Overview
Practical reference for Titanium Alloy MVC projects: CLI usage, project configuration, conditional rendering, custom XML tags, cross-controller communication, and common compilation/runtime errors. Reference-style — load the relevant file from references/ for deeper detail.
When to use
Use this skill when:
- The project contains
app/views/ + app/controllers/, alloy.jmk, or config.json
- Running or scripting the Alloy CLI (
alloy new, alloy generate, alloy compile, ...)
- Configuring
alloy.jmk build hooks or config.json environment / platform precedence
- Writing conditional views with
if= in XML or TSS
- Building reusable custom XML tags in
app/lib/
- Wiring cross-controller communication via
Backbone.Events
- Diagnosing Alloy compilation errors or platform-specific runtime issues
Do NOT use for:
- Alloy MVC concepts, controllers, models, or data binding (use
alloy-guides)
- Titanium SDK fundamentals,
tiapp.xml, Hyperloop, or app distribution (use ti-guides)
- Native module dependency updates (use
ti-module-update)
Quick reference
Key practices
Naming conventions
- Never use double underscore prefixes (
__foo) — reserved for Alloy
- Never use JavaScript reserved words as IDs
Global events — use Backbone.Events
Avoid Ti.App.fireEvent / Ti.App.addEventListener. They cross the native-JS bridge and can cause memory leaks and slower execution.
Use the Backbone.Events pattern:
Alloy.Events = _.clone(Backbone.Events);
Alloy.Events.on('updateMainUI', refreshData);
$.controller.addEventListener('close', () => {
Alloy.Events.off('updateMainUI');
});
Alloy.Events.trigger('updateMainUI');
Global variables in non-controller files
Always require Alloy modules:
const Alloy = require('alloy');
const Backbone = require('alloy/backbone');
const _ = require('alloy/underscore')._;
Conditional views
Use if attributes in XML for conditional rendering (evaluated before render):
<Alloy>
<Window>
<View if="Alloy.Globals.isLoggedIn()" id="loggedIn">
<Label text="Logged in" />
</View>
<View if="!Alloy.Globals.isLoggedIn()" id="notLoggedIn">
<Label text="Not logged in" />
</View>
</Window>
</Alloy>
Conditional TSS styles:
"#info[if=Alloy.Globals.isIos7Plus]": {
font: { textStyle: Ti.UI.TEXT_STYLE_FOOTNOTE }
}
Data-binding conditionals:
<TableViewRow if="$model.shouldShowCommentRow()">
Common error solutions
| Error | Solution |
|---|
No app.js found | Run alloy compile --config platform=<platform> |
| Android assets not showing | Use absolute paths (prepend /) |
Alloy is not defined (non-controller) | Add const Alloy = require('alloy'); |
iOS invalid method passed to UIModule | Creating Android-only object — use platform attribute |
CLI quick reference
alloy new [path] [template]
alloy generate controller <name>
alloy generate model <name> <adapter> <schema>
alloy generate style --all
alloy compile [--config platform=android,deploytype=test]
alloy extract-i18n en --apply
alloy copy <old> <new>
alloy move <old> <new>
alloy remove <name>
Configuration files priority
config.json precedence: os:<platform> > env:<environment> > global
Access at runtime: Alloy.CFG.<key>
Custom XML tags
Reusable components without the overhead of widgets. Drop a file in app/lib/:
app/lib/checkbox.js
exports.createCheckBox = args => {
const wrapper = Ti.UI.createView({ layout: 'horizontal', checked: false });
const box = Ti.UI.createView({ width: 15, height: 15, borderWidth: 1 });
return wrapper;
};
view.xml
<CheckBox module="checkbox" id="terms" caption="I agree" onChange="onCheck" />
The module attribute points to the file in app/lib/ (without .js). The function must be create<TagName>.
See custom_tags.md for the complete worked example.
Related skills
| Task | Use this skill |
|---|
| Alloy MVC concepts, controllers, models, data binding | alloy-guides |
| Titanium SDK config, Hyperloop, app distribution | ti-guides |
| Titanium API lookup (Ti.UI, Ti.Network, modules) | ti-api |
| Native module dependency updates | ti-module-update |