ima-claude 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +463 -0
- package/dist/cli.js +1064 -0
- package/package.json +49 -0
- package/platforms/claude/adapter.ts +115 -0
- package/platforms/junie/adapter.ts +254 -0
- package/platforms/junie/agents-template.md +113 -0
- package/platforms/junie/hook-translations.md +84 -0
- package/platforms/shared/detector.ts +27 -0
- package/platforms/shared/installer.ts +202 -0
- package/platforms/shared/types.ts +78 -0
- package/plugins/ima-claude/.claude-plugin/plugin.json +25 -0
- package/plugins/ima-claude/agents/explorer.md +30 -0
- package/plugins/ima-claude/agents/implementer.md +30 -0
- package/plugins/ima-claude/agents/memory.md +42 -0
- package/plugins/ima-claude/agents/reviewer.md +53 -0
- package/plugins/ima-claude/agents/tester.md +33 -0
- package/plugins/ima-claude/agents/wp-developer.md +46 -0
- package/plugins/ima-claude/hooks/README.md +145 -0
- package/plugins/ima-claude/hooks/atlassian_prereqs.py +112 -0
- package/plugins/ima-claude/hooks/block_sed_edits.py +59 -0
- package/plugins/ima-claude/hooks/bootstrap.sh +90 -0
- package/plugins/ima-claude/hooks/bootstrap_utility_check.py +94 -0
- package/plugins/ima-claude/hooks/composer_autoload_check.py +70 -0
- package/plugins/ima-claude/hooks/docs_organization.py +104 -0
- package/plugins/ima-claude/hooks/enforce_rg_over_grep.py +56 -0
- package/plugins/ima-claude/hooks/fp_utility_check.py +90 -0
- package/plugins/ima-claude/hooks/hook_logger.py +69 -0
- package/plugins/ima-claude/hooks/hooks.json +239 -0
- package/plugins/ima-claude/hooks/jira_issue_fetch.py +79 -0
- package/plugins/ima-claude/hooks/jquery_in_wordpress.py +92 -0
- package/plugins/ima-claude/hooks/memory_bootstrap.py +79 -0
- package/plugins/ima-claude/hooks/memory_store_reminder.py +75 -0
- package/plugins/ima-claude/hooks/prompt_coach.py +125 -0
- package/plugins/ima-claude/hooks/prompt_coach_digest.md +48 -0
- package/plugins/ima-claude/hooks/prompt_coach_system.md +30 -0
- package/plugins/ima-claude/hooks/sequential_thinking_check.py +81 -0
- package/plugins/ima-claude/hooks/serena_over_grep.py +96 -0
- package/plugins/ima-claude/hooks/serena_over_read.py +66 -0
- package/plugins/ima-claude/hooks/serena_project_check.py +133 -0
- package/plugins/ima-claude/hooks/sql_injection_check.py +73 -0
- package/plugins/ima-claude/hooks/task_master_after_plan.py +31 -0
- package/plugins/ima-claude/hooks/task_master_before_impl.py +93 -0
- package/plugins/ima-claude/hooks/tavily_extract_advanced.py +48 -0
- package/plugins/ima-claude/hooks/vestige_before_external.py +86 -0
- package/plugins/ima-claude/hooks/webfetch_to_tavily.py +42 -0
- package/plugins/ima-claude/hooks/websearch_to_tavily.py +41 -0
- package/plugins/ima-claude/hooks/wp_security_check.py +150 -0
- package/plugins/ima-claude/personalities/README.md +45 -0
- package/plugins/ima-claude/personalities/enable-40k.md +69 -0
- package/plugins/ima-claude/personalities/enable-templars.md +69 -0
- package/plugins/ima-claude/skills/.research-summary.md +340 -0
- package/plugins/ima-claude/skills/architect/SKILL.md +304 -0
- package/plugins/ima-claude/skills/compound-bridge/SKILL.md +200 -0
- package/plugins/ima-claude/skills/discourse/SKILL.md +440 -0
- package/plugins/ima-claude/skills/discourse-admin/SKILL.md +192 -0
- package/plugins/ima-claude/skills/discourse-admin/references/api-endpoints.md +441 -0
- package/plugins/ima-claude/skills/discourse-admin/references/gotchas.md +107 -0
- package/plugins/ima-claude/skills/discourse-admin/references/staging-defaults.md +98 -0
- package/plugins/ima-claude/skills/discourse-admin/scripts/discourse-admin.py +319 -0
- package/plugins/ima-claude/skills/docs-organize/SKILL.md +254 -0
- package/plugins/ima-claude/skills/docs-organize/templates/active-README.md +50 -0
- package/plugins/ima-claude/skills/docs-organize/templates/archive-README.md +57 -0
- package/plugins/ima-claude/skills/docs-organize/templates/docs-README.md +43 -0
- package/plugins/ima-claude/skills/docs-organize/templates/phase-archive-README.md +83 -0
- package/plugins/ima-claude/skills/docs-organize/templates/section-README.md +48 -0
- package/plugins/ima-claude/skills/docs-organize/templates/transient-README.md +79 -0
- package/plugins/ima-claude/skills/docs-organize/templates/transient-gitignore +9 -0
- package/plugins/ima-claude/skills/ember-discourse/SKILL.md +496 -0
- package/plugins/ima-claude/skills/functional-programmer/SKILL.md +258 -0
- package/plugins/ima-claude/skills/ima-bootstrap/SKILL.md +278 -0
- package/plugins/ima-claude/skills/ima-bootstrap/references/bootstrap-patterns.md +356 -0
- package/plugins/ima-claude/skills/ima-bootstrap/references/ima-brand.md +273 -0
- package/plugins/ima-claude/skills/ima-bootstrap/references/theme-integration.md +212 -0
- package/plugins/ima-claude/skills/ima-brand/SKILL.md +108 -0
- package/plugins/ima-claude/skills/ima-brand/references/brand-identity.md +140 -0
- package/plugins/ima-claude/skills/ima-brand/references/digital-standards.md +180 -0
- package/plugins/ima-claude/skills/ima-brand/references/visual-system.md +173 -0
- package/plugins/ima-claude/skills/ima-forms-expert/SKILL.md +175 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/container-components.md +154 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/examples.md +328 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/field-components.md +298 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/form-factory.md +193 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/quick-reference.md +153 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/validation-engine.md +336 -0
- package/plugins/ima-claude/skills/jira-checkpoint/SKILL.md +178 -0
- package/plugins/ima-claude/skills/jquery/SKILL.md +413 -0
- package/plugins/ima-claude/skills/js-fp/SKILL.md +463 -0
- package/plugins/ima-claude/skills/js-fp/core-principles.md +487 -0
- package/plugins/ima-claude/skills/js-fp/examples/pure-functions.js +260 -0
- package/plugins/ima-claude/skills/js-fp/examples/tests/pure-functions.test.js +262 -0
- package/plugins/ima-claude/skills/js-fp/references/anti-patterns.md +120 -0
- package/plugins/ima-claude/skills/js-fp/references/performance-patterns.md +116 -0
- package/plugins/ima-claude/skills/js-fp/references/testing-patterns.md +134 -0
- package/plugins/ima-claude/skills/js-fp-api/SKILL.md +280 -0
- package/plugins/ima-claude/skills/js-fp-api/examples/crud-endpoint.js +258 -0
- package/plugins/ima-claude/skills/js-fp-api/references/middleware-patterns.md +134 -0
- package/plugins/ima-claude/skills/js-fp-api/references/security-sql.md +110 -0
- package/plugins/ima-claude/skills/js-fp-api/references/validation-patterns.md +165 -0
- package/plugins/ima-claude/skills/js-fp-react/SKILL.md +447 -0
- package/plugins/ima-claude/skills/js-fp-react/examples/ProductCard.tsx +65 -0
- package/plugins/ima-claude/skills/js-fp-react/references/hooks-advanced.md +136 -0
- package/plugins/ima-claude/skills/js-fp-react/references/performance-patterns.md +175 -0
- package/plugins/ima-claude/skills/js-fp-vue/SKILL.md +322 -0
- package/plugins/ima-claude/skills/js-fp-vue/references/complete-examples.md +397 -0
- package/plugins/ima-claude/skills/js-fp-vue/references/composables-advanced.md +282 -0
- package/plugins/ima-claude/skills/js-fp-vue/references/reactivity-patterns.md +348 -0
- package/plugins/ima-claude/skills/js-fp-vue/references/testing.md +314 -0
- package/plugins/ima-claude/skills/js-fp-wordpress/SKILL.md +301 -0
- package/plugins/ima-claude/skills/js-fp-wordpress/references/ajax-patterns.md +192 -0
- package/plugins/ima-claude/skills/js-fp-wordpress/references/event-patterns.md +136 -0
- package/plugins/ima-claude/skills/js-fp-wordpress/references/wp-integration.md +248 -0
- package/plugins/ima-claude/skills/livecanvas/SKILL.md +209 -0
- package/plugins/ima-claude/skills/livecanvas/references/livecanvas-features.md +311 -0
- package/plugins/ima-claude/skills/livecanvas/references/loops-and-logic.md +730 -0
- package/plugins/ima-claude/skills/livecanvas/references/picostrap.md +227 -0
- package/plugins/ima-claude/skills/mcp-atlassian/SKILL.md +339 -0
- package/plugins/ima-claude/skills/mcp-context7/SKILL.md +109 -0
- package/plugins/ima-claude/skills/mcp-memory/SKILL.md +182 -0
- package/plugins/ima-claude/skills/mcp-qdrant/SKILL.md +233 -0
- package/plugins/ima-claude/skills/mcp-sequential/SKILL.md +149 -0
- package/plugins/ima-claude/skills/mcp-serena/SKILL.md +174 -0
- package/plugins/ima-claude/skills/mcp-tavily/SKILL.md +118 -0
- package/plugins/ima-claude/skills/mcp-vestige/SKILL.md +259 -0
- package/plugins/ima-claude/skills/php-authnet/SKILL.md +275 -0
- package/plugins/ima-claude/skills/php-authnet/references/api-reference.md +624 -0
- package/plugins/ima-claude/skills/php-authnet/references/sandbox-testing.md +424 -0
- package/plugins/ima-claude/skills/php-fp/SKILL.md +333 -0
- package/plugins/ima-claude/skills/php-fp/examples/pure-functions.php +403 -0
- package/plugins/ima-claude/skills/php-fp/examples/tests/PureFunctionsTest.php +515 -0
- package/plugins/ima-claude/skills/php-fp/references/core-principles.md +277 -0
- package/plugins/ima-claude/skills/php-fp/references/testing-patterns.md +374 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/SKILL.md +216 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/references/fp-patterns.md +275 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/references/plugin-architecture.md +295 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/references/security-examples.md +203 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/references/testing-strategy.md +259 -0
- package/plugins/ima-claude/skills/phpunit-wp/SKILL.md +716 -0
- package/plugins/ima-claude/skills/playwright/SKILL.md +434 -0
- package/plugins/ima-claude/skills/playwright/references/accessibility-testing.md +153 -0
- package/plugins/ima-claude/skills/playwright/references/ci-cd.md +268 -0
- package/plugins/ima-claude/skills/playwright/references/network-mocking.md +270 -0
- package/plugins/ima-claude/skills/playwright/references/visual-regression.md +215 -0
- package/plugins/ima-claude/skills/py-fp/SKILL.md +663 -0
- package/plugins/ima-claude/skills/py-fp/examples/pure-functions.py +185 -0
- package/plugins/ima-claude/skills/py-fp/examples/tests/test_pure_functions.py +244 -0
- package/plugins/ima-claude/skills/py-fp/references/core-principles.md +381 -0
- package/plugins/ima-claude/skills/py-fp/references/testing-patterns.md +283 -0
- package/plugins/ima-claude/skills/quasar-fp/SKILL.md +327 -0
- package/plugins/ima-claude/skills/quasar-fp/metadata.json +85 -0
- package/plugins/ima-claude/skills/quasar-fp/references/component-patterns.md +257 -0
- package/plugins/ima-claude/skills/quasar-fp/references/theme-integration.md +233 -0
- package/plugins/ima-claude/skills/quasar-fp/references/utility-classes.md +237 -0
- package/plugins/ima-claude/skills/quickstart/SKILL.md +129 -0
- package/plugins/ima-claude/skills/rails/SKILL.md +359 -0
- package/plugins/ima-claude/skills/resume-session/SKILL.md +68 -0
- package/plugins/ima-claude/skills/rg/SKILL.md +205 -0
- package/plugins/ima-claude/skills/ruby-fp/SKILL.md +336 -0
- package/plugins/ima-claude/skills/save-session/SKILL.md +81 -0
- package/plugins/ima-claude/skills/scorecard/SKILL.md +96 -0
- package/plugins/ima-claude/skills/skill-analyzer/SKILL.md +127 -0
- package/plugins/ima-claude/skills/skill-analyzer/references/advanced-checklist.md +44 -0
- package/plugins/ima-claude/skills/skill-analyzer/references/core-checklist.md +60 -0
- package/plugins/ima-claude/skills/skill-analyzer/scripts/analyze_skill.py +418 -0
- package/plugins/ima-claude/skills/skill-creator/LICENSE.txt +202 -0
- package/plugins/ima-claude/skills/skill-creator/SKILL.md +343 -0
- package/plugins/ima-claude/skills/skill-creator/references/output-patterns.md +82 -0
- package/plugins/ima-claude/skills/skill-creator/references/workflows.md +28 -0
- package/plugins/ima-claude/skills/skill-creator/scripts/init_skill.py +303 -0
- package/plugins/ima-claude/skills/skill-creator/scripts/package_skill.py +110 -0
- package/plugins/ima-claude/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/plugins/ima-claude/skills/task-master/SKILL.md +51 -0
- package/plugins/ima-claude/skills/task-planner/SKILL.md +228 -0
- package/plugins/ima-claude/skills/task-runner/SKILL.md +192 -0
- package/plugins/ima-claude/skills/unit-testing/SKILL.md +198 -0
- package/plugins/ima-claude/skills/unit-testing/references/mock-patterns.md +181 -0
- package/plugins/ima-claude/skills/unit-testing/references/tdd-workflow.md +177 -0
- package/plugins/ima-claude/skills/unit-testing/references/test-strategy.md +126 -0
- package/plugins/ima-claude/skills/wp-local/SKILL.md +246 -0
- package/plugins/ima-claude/skills/wp-local/references/configuration.md +198 -0
- package/plugins/ima-claude/skills/wp-local/references/wp-cli-reference.md +406 -0
- package/plugins/ima-claude/skills/wp-local/scripts/wp-local.sh +61 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
# WordPress Hooks Integration
|
|
2
|
+
|
|
3
|
+
Patterns for integrating with WordPress plugins and admin.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
1. [Gravity Forms Integration](#gravity-forms-integration)
|
|
8
|
+
2. [ACF Integration](#acf-integration)
|
|
9
|
+
3. [WordPress Admin Integration](#wordpress-admin-integration)
|
|
10
|
+
4. [Pure Business Logic Pattern](#pure-business-logic-pattern)
|
|
11
|
+
5. [Testing Strategy](#testing-strategy)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Gravity Forms Integration
|
|
16
|
+
|
|
17
|
+
**MUST use jQuery** - GF events are jQuery-based:
|
|
18
|
+
|
|
19
|
+
```javascript
|
|
20
|
+
(function($) {
|
|
21
|
+
'use strict';
|
|
22
|
+
|
|
23
|
+
// Form render event
|
|
24
|
+
$(document).on('gform_post_render', function(event, formId) {
|
|
25
|
+
var $form = $('#gform_' + formId);
|
|
26
|
+
|
|
27
|
+
// Initialize custom fields
|
|
28
|
+
initConsentFields($form);
|
|
29
|
+
initRepeaterFields($form);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Form confirmation event
|
|
33
|
+
$(document).on('gform_confirmation_loaded', function(event, formId) {
|
|
34
|
+
// Track form completion
|
|
35
|
+
if (typeof gtag === 'function') {
|
|
36
|
+
gtag('event', 'form_submit', {
|
|
37
|
+
'form_id': formId
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
})(jQuery);
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## ACF Integration
|
|
48
|
+
|
|
49
|
+
ACF uses jQuery events:
|
|
50
|
+
|
|
51
|
+
```javascript
|
|
52
|
+
(function($) {
|
|
53
|
+
'use strict';
|
|
54
|
+
|
|
55
|
+
if (typeof acf !== 'undefined') {
|
|
56
|
+
// ACF fields are ready
|
|
57
|
+
acf.addAction('ready', function($el) {
|
|
58
|
+
initAcfEnhancements($el);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// New ACF repeater row added
|
|
62
|
+
acf.addAction('append', function($el) {
|
|
63
|
+
initAcfEnhancements($el);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ACF field interaction - matches ecosystem
|
|
68
|
+
acf.addAction('ready', function() {
|
|
69
|
+
$('.acf-field-type-repeater').each(function() {
|
|
70
|
+
setupRepeaterEnhancements($(this));
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
})(jQuery);
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## WordPress Admin Integration
|
|
80
|
+
|
|
81
|
+
```javascript
|
|
82
|
+
(function($) {
|
|
83
|
+
'use strict';
|
|
84
|
+
|
|
85
|
+
$(document).ready(function() {
|
|
86
|
+
// Admin-specific enhancements
|
|
87
|
+
if (typeof pagenow !== 'undefined' && pagenow === 'edit-listing') {
|
|
88
|
+
initListingAdminEnhancements();
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
})(jQuery);
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Pure Business Logic Pattern
|
|
98
|
+
|
|
99
|
+
**Rule**: Extract pure JavaScript functions from DOM-dependent code.
|
|
100
|
+
|
|
101
|
+
### Bad: Mixed Business Logic and DOM
|
|
102
|
+
|
|
103
|
+
```javascript
|
|
104
|
+
(function($) {
|
|
105
|
+
$('.price-calculator').on('change', 'input', function() {
|
|
106
|
+
var quantity = parseInt($('#quantity').val()) || 0;
|
|
107
|
+
var price = parseFloat($('#unit-price').val()) || 0;
|
|
108
|
+
var discount = parseFloat($('#discount').val()) || 0;
|
|
109
|
+
|
|
110
|
+
// Business logic mixed with DOM operations
|
|
111
|
+
var subtotal = quantity * price;
|
|
112
|
+
var discountAmount = subtotal * (discount / 100);
|
|
113
|
+
var total = subtotal - discountAmount;
|
|
114
|
+
|
|
115
|
+
$('#subtotal').text('$' + subtotal.toFixed(2));
|
|
116
|
+
$('#discount-amount').text('-$' + discountAmount.toFixed(2));
|
|
117
|
+
$('#total').text('$' + total.toFixed(2));
|
|
118
|
+
});
|
|
119
|
+
})(jQuery);
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Good: Separated Pure Logic + DOM Wrapper
|
|
123
|
+
|
|
124
|
+
```javascript
|
|
125
|
+
(function($) {
|
|
126
|
+
'use strict';
|
|
127
|
+
|
|
128
|
+
// ===== Pure business logic (testable without DOM) =====
|
|
129
|
+
function calculatePricing(quantity, unitPrice, discountPercent) {
|
|
130
|
+
var subtotal = Math.max(0, quantity) * Math.max(0, unitPrice);
|
|
131
|
+
var discountAmount = subtotal * (Math.min(100, Math.max(0, discountPercent)) / 100);
|
|
132
|
+
var total = subtotal - discountAmount;
|
|
133
|
+
|
|
134
|
+
return {
|
|
135
|
+
subtotal: subtotal,
|
|
136
|
+
discountAmount: discountAmount,
|
|
137
|
+
total: total
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function formatCurrency(amount) {
|
|
142
|
+
return '$' + amount.toFixed(2);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// ===== DOM wrapper (side effects isolated here) =====
|
|
146
|
+
function PriceCalculator($container) {
|
|
147
|
+
this.$container = $container;
|
|
148
|
+
this.$quantity = $container.find('#quantity');
|
|
149
|
+
this.$unitPrice = $container.find('#unit-price');
|
|
150
|
+
this.$discount = $container.find('#discount');
|
|
151
|
+
this.$subtotal = $container.find('#subtotal');
|
|
152
|
+
this.$discountAmount = $container.find('#discount-amount');
|
|
153
|
+
this.$total = $container.find('#total');
|
|
154
|
+
|
|
155
|
+
this.init();
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
PriceCalculator.prototype.init = function() {
|
|
159
|
+
this.$container.on('change', 'input', this.update.bind(this));
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
PriceCalculator.prototype.getInputValues = function() {
|
|
163
|
+
return {
|
|
164
|
+
quantity: parseInt(this.$quantity.val()) || 0,
|
|
165
|
+
unitPrice: parseFloat(this.$unitPrice.val()) || 0,
|
|
166
|
+
discount: parseFloat(this.$discount.val()) || 0
|
|
167
|
+
};
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
PriceCalculator.prototype.update = function() {
|
|
171
|
+
var values = this.getInputValues();
|
|
172
|
+
var pricing = calculatePricing(values.quantity, values.unitPrice, values.discount);
|
|
173
|
+
|
|
174
|
+
this.$subtotal.text(formatCurrency(pricing.subtotal));
|
|
175
|
+
this.$discountAmount.text('-' + formatCurrency(pricing.discountAmount));
|
|
176
|
+
this.$total.text(formatCurrency(pricing.total));
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// ===== Initialization =====
|
|
180
|
+
$('.price-calculator').each(function() {
|
|
181
|
+
new PriceCalculator($(this));
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// ===== Export for testing (optional) =====
|
|
185
|
+
if (typeof module !== 'undefined' && module.exports) {
|
|
186
|
+
module.exports = { calculatePricing: calculatePricing, formatCurrency: formatCurrency };
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
})(jQuery);
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Testing Strategy
|
|
195
|
+
|
|
196
|
+
### Pure Functions (Jest/Node)
|
|
197
|
+
|
|
198
|
+
```javascript
|
|
199
|
+
// pure/calculations.js
|
|
200
|
+
function calculatePricing(quantity, unitPrice, discountPercent) {
|
|
201
|
+
var subtotal = Math.max(0, quantity) * Math.max(0, unitPrice);
|
|
202
|
+
var discountAmount = subtotal * (Math.min(100, Math.max(0, discountPercent)) / 100);
|
|
203
|
+
var total = subtotal - discountAmount;
|
|
204
|
+
|
|
205
|
+
return { subtotal: subtotal, discountAmount: discountAmount, total: total };
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
module.exports = { calculatePricing: calculatePricing };
|
|
209
|
+
|
|
210
|
+
// pure/calculations.test.js
|
|
211
|
+
var calculatePricing = require('./calculations').calculatePricing;
|
|
212
|
+
|
|
213
|
+
describe('calculatePricing', function() {
|
|
214
|
+
it('calculates correct pricing', function() {
|
|
215
|
+
var result = calculatePricing(10, 25, 10);
|
|
216
|
+
expect(result.subtotal).toBe(250);
|
|
217
|
+
expect(result.discountAmount).toBe(25);
|
|
218
|
+
expect(result.total).toBe(225);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it('handles zero quantity', function() {
|
|
222
|
+
var result = calculatePricing(0, 25, 10);
|
|
223
|
+
expect(result.total).toBe(0);
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it('handles negative values gracefully', function() {
|
|
227
|
+
var result = calculatePricing(-5, 25, 10);
|
|
228
|
+
expect(result.total).toBe(0);
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## File Organization
|
|
236
|
+
|
|
237
|
+
```
|
|
238
|
+
plugin-name/
|
|
239
|
+
└── assets/
|
|
240
|
+
└── js/
|
|
241
|
+
├── plugin-base.js # jQuery - AJAX, GF integration
|
|
242
|
+
├── plugin-admin.js # jQuery - Admin UI interactions
|
|
243
|
+
├── plugin-repeater.js # Vanilla - Isolated component
|
|
244
|
+
├── plugin-validation.js # Vanilla - Pure validation logic
|
|
245
|
+
└── pure/
|
|
246
|
+
├── formatting.js # Pure functions (testable)
|
|
247
|
+
└── calculations.js # Pure functions (testable)
|
|
248
|
+
```
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: livecanvas
|
|
3
|
+
description: >-
|
|
4
|
+
LiveCanvas WordPress page builder with Bootstrap 5, Loops & Logic (Tangible) templating,
|
|
5
|
+
and PicoStrap theme integration. Use when: building LiveCanvas pages, creating dynamic
|
|
6
|
+
content with L&L/Tangible tags, designing Bootstrap layouts in LiveCanvas editor, working
|
|
7
|
+
with LiveCanvas shortcodes, WooCommerce templates in LiveCanvas, ACF dynamic blocks,
|
|
8
|
+
PicoStrap theme customization, or any visual page building that stores content in the
|
|
9
|
+
WordPress database rather than PHP files. Triggers on: livecanvas, live canvas, tangible,
|
|
10
|
+
loops and logic, L&L, picostrap, lc_get_posts, lc-block, tangible tag.
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# LiveCanvas
|
|
14
|
+
|
|
15
|
+
Visual page builder for WordPress. Pure HTML/Bootstrap — no proprietary markup, no vendor lock-in.
|
|
16
|
+
Content lives in the WordPress database (`wp_posts`), not PHP template files.
|
|
17
|
+
|
|
18
|
+
**Cross-reference**: Use `ima-bootstrap` skill for Bootstrap 5.3 utilities, grid, components, and IMA brand integration. LiveCanvas uses your theme's Bootstrap — everything in `ima-bootstrap` applies directly.
|
|
19
|
+
|
|
20
|
+
## Mental Model
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
LiveCanvas Page = HTML + Bootstrap classes + <tangible> blocks for dynamic data
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
- **Static content**: Write Bootstrap HTML directly (cards, grids, heroes, etc.)
|
|
27
|
+
- **Dynamic content**: Wrap Loops & Logic tags in `<tangible>` blocks
|
|
28
|
+
- **Logic/conditions**: L&L replaces PHP — think Handlebars/Twig, not `<?php ?>`
|
|
29
|
+
- **No custom CSS framework**: LiveCanvas adds zero CSS. Your theme's Bootstrap is the only framework.
|
|
30
|
+
|
|
31
|
+
## Page Structure
|
|
32
|
+
|
|
33
|
+
Every LiveCanvas page follows this hierarchy:
|
|
34
|
+
|
|
35
|
+
```html
|
|
36
|
+
<main>
|
|
37
|
+
<section> <!-- Full-width, not nestable -->
|
|
38
|
+
<div class="container"> <!-- or container-fluid -->
|
|
39
|
+
<div class="row">
|
|
40
|
+
<div class="col-lg-6">
|
|
41
|
+
<div class="lc-block"> <!-- Smallest editable unit -->
|
|
42
|
+
<h2 editable="inline">Heading</h2>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
<div class="col-lg-6">
|
|
46
|
+
<div class="lc-block">
|
|
47
|
+
<p editable="rich">Content here</p>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
</section>
|
|
53
|
+
</main>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Rules**:
|
|
57
|
+
- `<section>` elements are always direct children of `<main>`, edge-to-edge
|
|
58
|
+
- Standard Bootstrap grid inside: `.container` > `.row` > `.col-*`
|
|
59
|
+
- `lc-block` divs are the smallest building blocks
|
|
60
|
+
- `editable="inline"` for single-line text, `editable="rich"` for rich text
|
|
61
|
+
|
|
62
|
+
## Dynamic Content with Loops & Logic
|
|
63
|
+
|
|
64
|
+
Wrap L&L markup in `<tangible>` tags. Add `class="live-refresh"` for real-time preview in the editor.
|
|
65
|
+
|
|
66
|
+
```html
|
|
67
|
+
<tangible class="live-refresh">
|
|
68
|
+
<Loop type="post" count="3" orderby="date" order="desc">
|
|
69
|
+
<div class="card mb-3">
|
|
70
|
+
<div class="card-body">
|
|
71
|
+
<h5 class="card-title"><Field title /></h5>
|
|
72
|
+
<p class="card-text"><Field excerpt /></p>
|
|
73
|
+
<a href="{Field url}" class="btn btn-primary">Read More</a>
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
</Loop>
|
|
77
|
+
</tangible>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### L&L Quick Reference
|
|
81
|
+
|
|
82
|
+
| Tag | Purpose | Example |
|
|
83
|
+
|-----|---------|---------|
|
|
84
|
+
| `<Loop>` | Query & iterate | `<Loop type="post" count="5">` |
|
|
85
|
+
| `<Field>` | Output a value | `<Field title />` |
|
|
86
|
+
| `<If>` / `<Else />` | Conditions | `<If field="image" exists>` |
|
|
87
|
+
| `<Set>` / `<Get>` | Variables | `<Set name="total">0</Set>` |
|
|
88
|
+
| `<Date>` | Date formatting | `<Date format="F j, Y" />` |
|
|
89
|
+
| `<Format>` | String ops | `<Format case="upper">text</Format>` |
|
|
90
|
+
| `<Math>` | Arithmetic | `<Math>price * 1.1</Math>` |
|
|
91
|
+
| `<Template>` | Reuse saved template | `<Template name="card" />` |
|
|
92
|
+
|
|
93
|
+
**Tags inside attributes** — use `{}` instead of `<>`:
|
|
94
|
+
```html
|
|
95
|
+
<a href="{Field url}"><Field title /></a>
|
|
96
|
+
<img src="{Field image_url}" alt="{Field title}" />
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Common Patterns
|
|
100
|
+
|
|
101
|
+
**Posts grid with fallback**:
|
|
102
|
+
```html
|
|
103
|
+
<tangible class="live-refresh">
|
|
104
|
+
<If loop exists type="post" category="news">
|
|
105
|
+
<div class="row g-4">
|
|
106
|
+
<Loop type="post" category="news" count="6">
|
|
107
|
+
<div class="col-md-4">
|
|
108
|
+
<div class="card h-100">
|
|
109
|
+
<If field="image">
|
|
110
|
+
<img src="{Field image_url}" class="card-img-top" alt="{Field title}" />
|
|
111
|
+
</If>
|
|
112
|
+
<div class="card-body">
|
|
113
|
+
<h5 class="card-title"><Field title /></h5>
|
|
114
|
+
<p class="card-text"><Field excerpt /></p>
|
|
115
|
+
</div>
|
|
116
|
+
<div class="card-footer">
|
|
117
|
+
<a href="{Field url}" class="btn btn-outline-primary btn-sm">Read More</a>
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
</Loop>
|
|
122
|
+
</div>
|
|
123
|
+
<Else />
|
|
124
|
+
<p class="text-muted">No news posts found.</p>
|
|
125
|
+
</If>
|
|
126
|
+
</tangible>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**ACF fields**:
|
|
130
|
+
```html
|
|
131
|
+
<tangible class="live-refresh">
|
|
132
|
+
<Field acf_text="subtitle" />
|
|
133
|
+
<img src="{Field acf_image=hero_image field=url}" alt="" />
|
|
134
|
+
<If acf_true_false="show_cta">
|
|
135
|
+
<a href="{Field acf_text=cta_url}" class="btn btn-primary">
|
|
136
|
+
<Field acf_text="cta_label" />
|
|
137
|
+
</a>
|
|
138
|
+
</If>
|
|
139
|
+
</tangible>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**ACF Repeater**:
|
|
143
|
+
```html
|
|
144
|
+
<tangible class="live-refresh">
|
|
145
|
+
<Loop acf_repeater="team_members">
|
|
146
|
+
<div class="col-md-4 text-center">
|
|
147
|
+
<img src="{Field acf_image=photo field=url}" class="rounded-circle mb-3" width="150" />
|
|
148
|
+
<h5><Field name /></h5>
|
|
149
|
+
<p class="text-muted"><Field role /></p>
|
|
150
|
+
</div>
|
|
151
|
+
</Loop>
|
|
152
|
+
</tangible>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Custom post type with taxonomy filter**:
|
|
156
|
+
```html
|
|
157
|
+
<tangible class="live-refresh">
|
|
158
|
+
<Loop type="post" post_type="portfolio" taxonomy="project_type" terms="web-design" count="9">
|
|
159
|
+
<Field title />
|
|
160
|
+
</Loop>
|
|
161
|
+
</tangible>
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Reusable Sections
|
|
165
|
+
|
|
166
|
+
Save any section to a library. Recall on other pages:
|
|
167
|
+
```
|
|
168
|
+
[lc_html_section id="123"]
|
|
169
|
+
```
|
|
170
|
+
Edits propagate everywhere the section is used.
|
|
171
|
+
|
|
172
|
+
## LiveCanvas Shortcodes (Legacy)
|
|
173
|
+
|
|
174
|
+
Still supported alongside L&L. Use for simple field output without `<tangible>` wrapper:
|
|
175
|
+
|
|
176
|
+
| Shortcode | Purpose |
|
|
177
|
+
|-----------|---------|
|
|
178
|
+
| `[lc_the_title]` | Post title |
|
|
179
|
+
| `[lc_the_content]` | Post content |
|
|
180
|
+
| `[lc_the_date]` | Post date |
|
|
181
|
+
| `[lc_the_thumbnail]` | Featured image |
|
|
182
|
+
| `[lc_the_excerpt]` | Excerpt |
|
|
183
|
+
| `[lc_the_permalink]` | URL |
|
|
184
|
+
| `[lc_the_cf]` | Custom field |
|
|
185
|
+
| `[lc_the_terms]` | Taxonomy terms |
|
|
186
|
+
| `[lc_if]` | Conditional |
|
|
187
|
+
| `[lc_get_posts]` | Post query loop |
|
|
188
|
+
|
|
189
|
+
**Prefer L&L for new work** — shortcodes are maintained for backward compatibility.
|
|
190
|
+
|
|
191
|
+
## When to Use What
|
|
192
|
+
|
|
193
|
+
| Need | Use |
|
|
194
|
+
|------|-----|
|
|
195
|
+
| Static layout, typography, spacing | Bootstrap classes directly (see `ima-bootstrap`) |
|
|
196
|
+
| Dynamic post loops, conditions | L&L `<tangible>` blocks |
|
|
197
|
+
| Simple single-field output | L&L `<Field>` or legacy shortcode |
|
|
198
|
+
| ACF field display | L&L ACF tags |
|
|
199
|
+
| WooCommerce templates | LiveCanvas WooCommerce shortcodes |
|
|
200
|
+
| SCSS/theme customization | PicoStrap child theme |
|
|
201
|
+
| Complex component patterns | Bootstrap components (see `ima-bootstrap`) |
|
|
202
|
+
|
|
203
|
+
## Reference Files
|
|
204
|
+
|
|
205
|
+
Load these as needed for deeper information:
|
|
206
|
+
|
|
207
|
+
- **[Loops & Logic Reference](references/loops-and-logic.md)** — Complete L&L syntax: all tags, Loop query parameters, Field types, If conditions, ACF integration, variables, Date/Format/Math, List/Map, WooCommerce
|
|
208
|
+
- **[LiveCanvas Features](references/livecanvas-features.md)** — Editor workflow, all shortcodes with parameters, WooCommerce shortcodes, Forms API, reusable sections, keyboard shortcuts, template assignment
|
|
209
|
+
- **[PicoStrap Integration](references/picostrap.md)** — Theme architecture, SCSS pipeline, NinjaBootstrap utilities, child theme setup, dark mode, customizer options
|