@rglabs/butterfly 2.0.1
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/CLAUDE.md +201 -0
- package/README.md +371 -0
- package/dist/commands/add.d.ts +23 -0
- package/dist/commands/add.js +303 -0
- package/dist/commands/code.d.ts +11 -0
- package/dist/commands/code.js +72 -0
- package/dist/commands/create-object.d.ts +6 -0
- package/dist/commands/create-object.js +293 -0
- package/dist/commands/create-report.d.ts +6 -0
- package/dist/commands/create-report.js +154 -0
- package/dist/commands/diff.d.ts +4 -0
- package/dist/commands/diff.js +238 -0
- package/dist/commands/download.d.ts +4 -0
- package/dist/commands/download.js +374 -0
- package/dist/commands/layout.d.ts +12 -0
- package/dist/commands/layout.js +83 -0
- package/dist/commands/record.d.ts +21 -0
- package/dist/commands/record.js +483 -0
- package/dist/commands/run-poc.d.ts +3 -0
- package/dist/commands/run-poc.js +18 -0
- package/dist/commands/setup.d.ts +3 -0
- package/dist/commands/setup.js +66 -0
- package/dist/commands/start-poc.d.ts +3 -0
- package/dist/commands/start-poc.js +55 -0
- package/dist/commands/sync-docs.d.ts +3 -0
- package/dist/commands/sync-docs.js +27 -0
- package/dist/commands/translate.d.ts +13 -0
- package/dist/commands/translate.js +401 -0
- package/dist/commands/upload.d.ts +3 -0
- package/dist/commands/upload.js +150 -0
- package/dist/commands/workflow-info.d.ts +13 -0
- package/dist/commands/workflow-info.js +161 -0
- package/dist/components/ConflictResolver.d.ts +12 -0
- package/dist/components/ConflictResolver.js +77 -0
- package/dist/components/DiffView.d.ts +11 -0
- package/dist/components/DiffView.js +101 -0
- package/dist/components/DownloadProgress.d.ts +11 -0
- package/dist/components/DownloadProgress.js +29 -0
- package/dist/components/RecordPreview.d.ts +11 -0
- package/dist/components/RecordPreview.js +91 -0
- package/dist/components/SetupForm.d.ts +8 -0
- package/dist/components/SetupForm.js +56 -0
- package/dist/components/UploadProgress.d.ts +13 -0
- package/dist/components/UploadProgress.js +42 -0
- package/dist/diff/adapters/index.d.ts +8 -0
- package/dist/diff/adapters/index.js +18 -0
- package/dist/diff/adapters/objectsAdapter.d.ts +13 -0
- package/dist/diff/adapters/objectsAdapter.js +177 -0
- package/dist/diff/adapters/reportsAdapter.d.ts +14 -0
- package/dist/diff/adapters/reportsAdapter.js +212 -0
- package/dist/diff/adapters/types.d.ts +19 -0
- package/dist/diff/adapters/types.js +2 -0
- package/dist/diff/engine.d.ts +19 -0
- package/dist/diff/engine.js +57 -0
- package/dist/diff/types.d.ts +34 -0
- package/dist/diff/types.js +110 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +117 -0
- package/dist/types/index.d.ts +18 -0
- package/dist/types/index.js +2 -0
- package/dist/utils/api.d.ts +85 -0
- package/dist/utils/api.js +1031 -0
- package/dist/utils/auth.d.ts +4 -0
- package/dist/utils/auth.js +22 -0
- package/dist/utils/bfySplitter.d.ts +12 -0
- package/dist/utils/bfySplitter.js +151 -0
- package/dist/utils/docs.d.ts +16 -0
- package/dist/utils/docs.js +186 -0
- package/dist/utils/errorLogger.d.ts +6 -0
- package/dist/utils/errorLogger.js +29 -0
- package/dist/utils/files.d.ts +14 -0
- package/dist/utils/files.js +772 -0
- package/dist/utils/lockManager.d.ts +15 -0
- package/dist/utils/lockManager.js +126 -0
- package/dist/utils/resourceHandlers.d.ts +50 -0
- package/dist/utils/resourceHandlers.js +684 -0
- package/dist/utils/resourceMapping.d.ts +32 -0
- package/dist/utils/resourceMapping.js +210 -0
- package/dist/utils/singleResourceDownload.d.ts +14 -0
- package/dist/utils/singleResourceDownload.js +261 -0
- package/dist/utils/summaryGenerator.d.ts +2 -0
- package/dist/utils/summaryGenerator.js +183 -0
- package/dist/utils/uploadHandler.d.ts +31 -0
- package/dist/utils/uploadHandler.js +263 -0
- package/docs/AI_API.md +93 -0
- package/docs/CLAUDE.md +216 -0
- package/docs/PROJECT_SPECIFIC.md +1 -0
- package/docs/RECORD_COMMAND.md +262 -0
- package/docs/WORKFLOW_API.md +480 -0
- package/docs/bfy-splitting.md +126 -0
- package/docs/cli-commands.md +333 -0
- package/docs/examples/README.md +95 -0
- package/docs/examples/order-system.md +147 -0
- package/docs/examples/product-catalog.md +195 -0
- package/docs/examples/reports.md +187 -0
- package/docs/excel-export.md +216 -0
- package/docs/field-types/README.md +29 -0
- package/docs/field-types/calculated.md +147 -0
- package/docs/field-types/code-mappings.md +84 -0
- package/docs/field-types/custom.md +340 -0
- package/docs/object-specs/README.md +136 -0
- package/docs/object-specs/code-parameters.md +151 -0
- package/docs/object-specs/creating.md +203 -0
- package/docs/object-specs/js-code-examples.md +208 -0
- package/docs/object-specs/js-field-updates.md +168 -0
- package/docs/objects/README.md +89 -0
- package/docs/objects/creating.md +127 -0
- package/docs/page-layout.md +361 -0
- package/docs/permissions.md +260 -0
- package/docs/reports.md +197 -0
- package/docs/state-machines.md +544 -0
- package/docs/tasks/create-object.md +81 -0
- package/docs/translations.md +346 -0
- package/docs/twig-helpers.md +283 -0
- package/docs/webservices.md +159 -0
- package/docs/workspaces.md +176 -0
- package/package.json +59 -0
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
# Translations and Internationalization
|
|
2
|
+
|
|
3
|
+
Butterfly CMS includes a built-in translation system for managing multilingual content in the admin interface. This guide covers how translations work and how to manage them.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The translation system consists of three main tables:
|
|
8
|
+
|
|
9
|
+
| Table | Purpose |
|
|
10
|
+
|-------|---------|
|
|
11
|
+
| `bfy_languages` | Defines available languages (e.g., English, Turkish, German) |
|
|
12
|
+
| `bfy_translation_texts` | Stores source texts (original strings to be translated) |
|
|
13
|
+
| `bfy_translations` | Stores translated texts, linking languages to source texts |
|
|
14
|
+
|
|
15
|
+
## Database Schema
|
|
16
|
+
|
|
17
|
+
### bfy_languages
|
|
18
|
+
|
|
19
|
+
| Column | Type | Description |
|
|
20
|
+
|--------|------|-------------|
|
|
21
|
+
| `id` | int | Primary key |
|
|
22
|
+
| `name` | string | Language name (e.g., "English", "Turkish") |
|
|
23
|
+
| `iso_code` | string | ISO language code (e.g., "en", "tr") |
|
|
24
|
+
| `translations` | custom | Virtual field - renders the Translation Manager UI |
|
|
25
|
+
|
|
26
|
+
### bfy_translation_texts
|
|
27
|
+
|
|
28
|
+
| Column | Type | Description |
|
|
29
|
+
|--------|------|-------------|
|
|
30
|
+
| `id` | int | Primary key |
|
|
31
|
+
| `source` | text | The original text to be translated |
|
|
32
|
+
|
|
33
|
+
### bfy_translations
|
|
34
|
+
|
|
35
|
+
| Column | Type | Description |
|
|
36
|
+
|--------|------|-------------|
|
|
37
|
+
| `id` | int | Primary key |
|
|
38
|
+
| `bfy_language_id` | int | Reference to `bfy_languages` |
|
|
39
|
+
| `bfy_translation_text_id` | int | Reference to `bfy_translation_texts` |
|
|
40
|
+
| `text` | text | The translated text |
|
|
41
|
+
|
|
42
|
+
## How It Works
|
|
43
|
+
|
|
44
|
+
1. **Source texts** are stored in `bfy_translation_texts` - these are the original strings that need translation
|
|
45
|
+
2. **Languages** are defined in `bfy_languages` - each language you want to support
|
|
46
|
+
3. **Translations** link source texts to their translated versions in each language via `bfy_translations`
|
|
47
|
+
|
|
48
|
+
### Translation Manager UI
|
|
49
|
+
|
|
50
|
+
When editing a language in `bfy_languages`, the `translations` custom field displays an interactive Translation Manager with:
|
|
51
|
+
|
|
52
|
+
- **Statistics**: Total strings, translated count, pending count
|
|
53
|
+
- **Search & Filter**: Search translations or filter by status (translated/untranslated)
|
|
54
|
+
- **Manual Entry**: Edit individual translations inline
|
|
55
|
+
|
|
56
|
+
## CLI Translation Command
|
|
57
|
+
|
|
58
|
+
The `butterfly-cli translate` command provides efficient operations for managing translations without needing to read YAML files.
|
|
59
|
+
|
|
60
|
+
### Operations
|
|
61
|
+
|
|
62
|
+
| Operation | Description |
|
|
63
|
+
|-----------|-------------|
|
|
64
|
+
| `languages` | List all languages with translation statistics |
|
|
65
|
+
| `get-untranslated` | Get untranslated texts for a language |
|
|
66
|
+
| `add` | Add or update a single translation |
|
|
67
|
+
| `bulk` | Bulk add/update translations from JSON file |
|
|
68
|
+
|
|
69
|
+
### List Languages
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# List all languages with translation stats (table format)
|
|
73
|
+
butterfly-cli translate languages
|
|
74
|
+
|
|
75
|
+
# Output as JSON
|
|
76
|
+
butterfly-cli translate languages --format json
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Example output:**
|
|
80
|
+
```
|
|
81
|
+
ID | ISO | Name | Translated | Untranslated
|
|
82
|
+
------------------------------------------------------------
|
|
83
|
+
1 | en | English | 450/600 | 150
|
|
84
|
+
2 | tr | Turkish | 580/600 | 20
|
|
85
|
+
3 | de | German | 200/600 | 400
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Get Untranslated Texts
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# Get all untranslated texts for Turkish
|
|
92
|
+
butterfly-cli translate get-untranslated --lang tr
|
|
93
|
+
|
|
94
|
+
# Get first 50 untranslated texts
|
|
95
|
+
butterfly-cli translate get-untranslated --lang tr --limit 50
|
|
96
|
+
|
|
97
|
+
# Get untranslated as JSON (for processing)
|
|
98
|
+
butterfly-cli translate get-untranslated --lang tr --format json
|
|
99
|
+
|
|
100
|
+
# Use language ID instead of ISO code
|
|
101
|
+
butterfly-cli translate get-untranslated --lang-id 2
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Add Single Translation
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Add translation by source text
|
|
108
|
+
butterfly-cli translate add --lang tr --source "Welcome" --text "Hoş geldiniz"
|
|
109
|
+
|
|
110
|
+
# Add translation by source ID
|
|
111
|
+
butterfly-cli translate add --lang tr --source-id 123 --text "Hoş geldiniz"
|
|
112
|
+
|
|
113
|
+
# Using language ID
|
|
114
|
+
butterfly-cli translate add --lang-id 2 --source "Save" --text "Kaydet"
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Note:** The `add` command automatically detects if a translation exists and updates it instead of creating a duplicate.
|
|
118
|
+
|
|
119
|
+
### Bulk Translation
|
|
120
|
+
|
|
121
|
+
Create a CSV file with tab-delimited columns (source and text):
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
source text
|
|
125
|
+
Welcome Hoş geldiniz
|
|
126
|
+
Save Kaydet
|
|
127
|
+
Cancel İptal
|
|
128
|
+
Delete Sil
|
|
129
|
+
Hello, World! Merhaba, Dünya!
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
> **Note:** Use TAB character as delimiter (not comma) to handle text containing commas. The header row is optional.
|
|
133
|
+
|
|
134
|
+
Then run:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
# Bulk translate from file
|
|
138
|
+
butterfly-cli translate bulk --lang tr --file translations.csv
|
|
139
|
+
|
|
140
|
+
# Using language ID
|
|
141
|
+
butterfly-cli translate bulk --lang-id 2 --file translations.csv
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Bulk command behavior:**
|
|
145
|
+
- Creates missing source texts automatically
|
|
146
|
+
- Updates existing translations
|
|
147
|
+
- Creates new translations for untranslated texts
|
|
148
|
+
- Handles quoted fields with embedded tabs or newlines
|
|
149
|
+
- Reports summary with counts of added/updated/skipped/errors
|
|
150
|
+
|
|
151
|
+
### Options Reference
|
|
152
|
+
|
|
153
|
+
| Option | Description |
|
|
154
|
+
|--------|-------------|
|
|
155
|
+
| `--lang <iso_code>` | Language ISO code (e.g., `tr`, `de`, `en`) |
|
|
156
|
+
| `--lang-id <id>` | Language ID (alternative to `--lang`) |
|
|
157
|
+
| `--source <text>` | Source text to translate |
|
|
158
|
+
| `--source-id <id>` | Source text ID (alternative to `--source`) |
|
|
159
|
+
| `--text <translation>` | Translated text (for `add` operation) |
|
|
160
|
+
| `-f, --file <path>` | CSV file path (tab-delimited) for `bulk` operation |
|
|
161
|
+
| `--format <format>` | Output format: `json` or `table` (default: `table`) |
|
|
162
|
+
| `--limit <count>` | Limit number of results |
|
|
163
|
+
|
|
164
|
+
## Claude Code Translation Workflow (Recommended)
|
|
165
|
+
|
|
166
|
+
> **AI INSTRUCTION:** Use the `butterfly-cli translate` command for efficient translation operations. This eliminates the need to read YAML files and handles all edge cases automatically.
|
|
167
|
+
|
|
168
|
+
### Step 1: List Languages and Check Status
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
butterfly-cli translate languages
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Step 2: Get Untranslated Texts
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
# Get untranslated texts as JSON for a language
|
|
178
|
+
butterfly-cli translate get-untranslated --lang tr --format json --limit 100
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Step 3: Add Translations
|
|
182
|
+
|
|
183
|
+
**For single translations:**
|
|
184
|
+
```bash
|
|
185
|
+
butterfly-cli translate add --lang tr --source "Welcome" --text "Hoş geldiniz"
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**For bulk translations:** Create a tab-delimited CSV file and use:
|
|
189
|
+
```bash
|
|
190
|
+
butterfly-cli translate bulk --lang tr --file translations.csv
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Complete Example Workflow
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
# 1. Check which languages need translations
|
|
197
|
+
butterfly-cli translate languages
|
|
198
|
+
|
|
199
|
+
# 2. Get untranslated texts for Turkish (first 20)
|
|
200
|
+
butterfly-cli translate get-untranslated --lang tr --limit 20 --format json > untranslated.json
|
|
201
|
+
|
|
202
|
+
# 3. After translating, create translations.csv (tab-delimited):
|
|
203
|
+
# source text
|
|
204
|
+
# Original Translated
|
|
205
|
+
|
|
206
|
+
# 4. Bulk import translations
|
|
207
|
+
butterfly-cli translate bulk --lang tr --file translations.csv
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Managing Translations (Alternative Methods)
|
|
211
|
+
|
|
212
|
+
### Adding a New Language
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
butterfly-cli record add bfy_languages --data '{
|
|
216
|
+
"name": "German",
|
|
217
|
+
"iso_code": "de"
|
|
218
|
+
}'
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Adding Source Texts Manually
|
|
222
|
+
|
|
223
|
+
Source texts are typically added automatically by the system. To add manually:
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
butterfly-cli record add bfy_translation_texts --data '{
|
|
227
|
+
"source": "Welcome to the application"
|
|
228
|
+
}'
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Using Record Command (Low-Level)
|
|
232
|
+
|
|
233
|
+
For direct database operations when needed:
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
# Add a translation
|
|
237
|
+
butterfly-cli record add bfy_translations --data '{
|
|
238
|
+
"bfy_language_id": 2,
|
|
239
|
+
"bfy_translation_text_id": 1,
|
|
240
|
+
"text": "Willkommen bei der Anwendung"
|
|
241
|
+
}'
|
|
242
|
+
|
|
243
|
+
# Update an existing translation
|
|
244
|
+
butterfly-cli record edit bfy_translations --id 123 --data '{
|
|
245
|
+
"text": "Updated translation text"
|
|
246
|
+
}'
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Using Translations in Twig
|
|
250
|
+
|
|
251
|
+
### Fetching Translations for a Language
|
|
252
|
+
|
|
253
|
+
```twig
|
|
254
|
+
{# Get all translations for a specific language as key-value pairs #}
|
|
255
|
+
{% set translations = db()
|
|
256
|
+
.from('bfy_translations')
|
|
257
|
+
.where('bfy_language_id', languageId)
|
|
258
|
+
.keyToValue('bfy_translation_text_id', 'text')
|
|
259
|
+
%}
|
|
260
|
+
|
|
261
|
+
{# Access: translations[textId] returns the translated text #}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Fetching Source Texts
|
|
265
|
+
|
|
266
|
+
```twig
|
|
267
|
+
{% set sourceTexts = db()
|
|
268
|
+
.from('bfy_translation_texts')
|
|
269
|
+
.get()
|
|
270
|
+
%}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Finding Untranslated Texts
|
|
274
|
+
|
|
275
|
+
```twig
|
|
276
|
+
{% set texts = db().from('bfy_translation_texts').get() %}
|
|
277
|
+
{% set translations = db()
|
|
278
|
+
.from('bfy_translations')
|
|
279
|
+
.where('bfy_language_id', languageId)
|
|
280
|
+
.keyToValue('bfy_translation_text_id', 'text')
|
|
281
|
+
%}
|
|
282
|
+
|
|
283
|
+
{% set untranslated = [] %}
|
|
284
|
+
{% for text in texts %}
|
|
285
|
+
{% if not translations[text.id] %}
|
|
286
|
+
{% set untranslated = untranslated|merge([text]) %}
|
|
287
|
+
{% endif %}
|
|
288
|
+
{% endfor %}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
## Related Tables
|
|
292
|
+
|
|
293
|
+
### language_settings
|
|
294
|
+
|
|
295
|
+
A separate table for frontend/site language configuration:
|
|
296
|
+
|
|
297
|
+
| Column | Type | Description |
|
|
298
|
+
|--------|------|-------------|
|
|
299
|
+
| `lang_key` | string | Language key (e.g., "en", "tr") |
|
|
300
|
+
| `name` | string | Display name |
|
|
301
|
+
| `image` | string | Flag/icon image |
|
|
302
|
+
|
|
303
|
+
> **Note:** `language_settings` is for site/frontend language selection, while `bfy_languages` is for admin interface translations.
|
|
304
|
+
|
|
305
|
+
## Download/Upload (YAML Files)
|
|
306
|
+
|
|
307
|
+
For working with YAML translation files, use the standard `download` and `upload` commands.
|
|
308
|
+
|
|
309
|
+
### Download Translations
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
# Download all resources (includes translations)
|
|
313
|
+
butterfly-cli download
|
|
314
|
+
|
|
315
|
+
# Download only translations
|
|
316
|
+
butterfly-cli download -t translations
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
This creates YAML files in `butterfly-resources/translations/` (one file per language).
|
|
320
|
+
|
|
321
|
+
### Upload Translations
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
# Upload a specific language file
|
|
325
|
+
butterfly-cli upload ./butterfly-resources/translations/tr.yaml
|
|
326
|
+
|
|
327
|
+
# Upload all translation files
|
|
328
|
+
butterfly-cli upload ./butterfly-resources/translations/
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### YAML File Format
|
|
332
|
+
|
|
333
|
+
```yaml
|
|
334
|
+
"Welcome": "Hoş geldiniz"
|
|
335
|
+
"Save": "Kaydet"
|
|
336
|
+
"Cancel": "İptal"
|
|
337
|
+
"Delete": "" # Empty = not yet translated
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
## Best Practices
|
|
341
|
+
|
|
342
|
+
1. **Use `translate` command**: Prefer `butterfly-cli translate` over reading YAML files for AI workflows
|
|
343
|
+
2. **Bulk operations**: Use `translate bulk` for multiple translations in one operation
|
|
344
|
+
3. **Check status first**: Always run `translate languages` to see translation progress
|
|
345
|
+
4. **ISO codes**: Use standard ISO 639-1 codes (e.g., `tr`, `de`, `en`)
|
|
346
|
+
5. **Auto-upsert**: The `translate add` command automatically updates existing translations
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
# Twig Helper Functions Reference
|
|
2
|
+
|
|
3
|
+
Reference for database queries, CRUD operations, and helper functions available in Butterfly Twig code.
|
|
4
|
+
|
|
5
|
+
## Database Queries (db)
|
|
6
|
+
|
|
7
|
+
### Basic Query
|
|
8
|
+
|
|
9
|
+
```twig
|
|
10
|
+
{% set records = db()
|
|
11
|
+
.table('table_name')
|
|
12
|
+
.get()
|
|
13
|
+
%}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### With Different Database
|
|
17
|
+
|
|
18
|
+
```twig
|
|
19
|
+
{% set records = db('database_alias')
|
|
20
|
+
.table('table_name')
|
|
21
|
+
.get()
|
|
22
|
+
%}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Without Authentication (for webservices)
|
|
26
|
+
|
|
27
|
+
```twig
|
|
28
|
+
{% set records = db('default', false)
|
|
29
|
+
.table('table_name')
|
|
30
|
+
.get()
|
|
31
|
+
%}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Query Methods
|
|
35
|
+
|
|
36
|
+
### Select Specific Columns
|
|
37
|
+
|
|
38
|
+
```twig
|
|
39
|
+
{% set records = db()
|
|
40
|
+
.table('users')
|
|
41
|
+
.select('id', 'name', 'email')
|
|
42
|
+
.get()
|
|
43
|
+
%}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Where Conditions
|
|
47
|
+
|
|
48
|
+
```twig
|
|
49
|
+
{# Basic where #}
|
|
50
|
+
.where('status', 'active')
|
|
51
|
+
|
|
52
|
+
{# With operator #}
|
|
53
|
+
.where('price', '>', 100)
|
|
54
|
+
|
|
55
|
+
{# Multiple conditions #}
|
|
56
|
+
.where('status', 'active')
|
|
57
|
+
.where('category_id', 5)
|
|
58
|
+
|
|
59
|
+
{# Or where #}
|
|
60
|
+
.orWhere('status', 'pending')
|
|
61
|
+
|
|
62
|
+
{# Where in array #}
|
|
63
|
+
.whereIn('id', [1, 2, 3])
|
|
64
|
+
|
|
65
|
+
{# Where null #}
|
|
66
|
+
.whereNull('deleted_at')
|
|
67
|
+
|
|
68
|
+
{# Where not null #}
|
|
69
|
+
.whereNotNull('email')
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Joins
|
|
73
|
+
|
|
74
|
+
```twig
|
|
75
|
+
{% set records = db()
|
|
76
|
+
.table('orders')
|
|
77
|
+
.join('users', 'users.id', '=', 'orders.user_id')
|
|
78
|
+
.select('orders.*', 'users.name as user_name')
|
|
79
|
+
.get()
|
|
80
|
+
%}
|
|
81
|
+
|
|
82
|
+
{# Left join #}
|
|
83
|
+
.leftJoin('categories', 'categories.id', '=', 'products.category_id')
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Ordering
|
|
87
|
+
|
|
88
|
+
```twig
|
|
89
|
+
{# Ascending #}
|
|
90
|
+
.orderBy('created_at')
|
|
91
|
+
|
|
92
|
+
{# Descending #}
|
|
93
|
+
.orderByDesc('created_at')
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
> **Note:** Use `orderByDesc('column')` instead of `orderBy('column', 'DESC')`.
|
|
97
|
+
|
|
98
|
+
### Limiting
|
|
99
|
+
|
|
100
|
+
```twig
|
|
101
|
+
.limit(10)
|
|
102
|
+
.offset(20)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Grouping
|
|
106
|
+
|
|
107
|
+
```twig
|
|
108
|
+
.groupBy('category_id')
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Result Methods
|
|
112
|
+
|
|
113
|
+
| Method | Returns | Description |
|
|
114
|
+
|--------|---------|-------------|
|
|
115
|
+
| `.get()` | array | All matching records |
|
|
116
|
+
| `.first()` | object/null | First matching record |
|
|
117
|
+
| `.count()` | integer | Count of matching records |
|
|
118
|
+
| `.sum('column')` | number | Sum of column values |
|
|
119
|
+
| `.avg('column')` | number | Average of column values |
|
|
120
|
+
| `.max('column')` | mixed | Maximum value |
|
|
121
|
+
| `.min('column')` | mixed | Minimum value |
|
|
122
|
+
|
|
123
|
+
### Examples
|
|
124
|
+
|
|
125
|
+
```twig
|
|
126
|
+
{% set users = db().table('users').where('is_active', 1).get() %}
|
|
127
|
+
{% set user = db().table('users').where('id', 5).first() %}
|
|
128
|
+
{% set total = db().table('orders').where('user_id', 5).count() %}
|
|
129
|
+
{% set sum = db().table('order_items').sum('total') %}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Data Extraction Methods
|
|
133
|
+
|
|
134
|
+
| Method | Description | Example |
|
|
135
|
+
|--------|-------------|---------|
|
|
136
|
+
| `column('col')` | Array of single column values | `[1, 2, 3]` |
|
|
137
|
+
| `keyToValue('key', 'val')` | Map key to value | `{1: "John", 2: "Jane"}` |
|
|
138
|
+
| `keyToValue('key')` | Map key to full row | `{1: {id: 1, name: "John"}}` |
|
|
139
|
+
| `keyToValues('key', 'val')` | Map key to array of values | `{1: [100, 200], 2: [150]}` |
|
|
140
|
+
| `keyToValues('key')` | Map key to array of rows | `{1: [{...}, {...}]}` |
|
|
141
|
+
|
|
142
|
+
### Examples
|
|
143
|
+
|
|
144
|
+
```twig
|
|
145
|
+
{# Get array of IDs #}
|
|
146
|
+
{% set ids = db().table('users').column('id') %}
|
|
147
|
+
{# Result: [1, 2, 3] #}
|
|
148
|
+
|
|
149
|
+
{# Get id => name mapping #}
|
|
150
|
+
{% set userNames = db().table('users').keyToValue('id', 'name') %}
|
|
151
|
+
{# Result: {1: "John", 2: "Jane"} #}
|
|
152
|
+
|
|
153
|
+
{# Get id => full record mapping #}
|
|
154
|
+
{% set usersById = db().table('users').keyToValue('id') %}
|
|
155
|
+
{# Result: {1: {id: 1, name: "John", ...}} #}
|
|
156
|
+
|
|
157
|
+
{# Get user_id => order totals (multiple per user) #}
|
|
158
|
+
{% set ordersByUser = db().table('orders').keyToValues('user_id', 'total') %}
|
|
159
|
+
{# Result: {1: [100, 200], 2: [150]} #}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
> **Note:** There is no `pluck()` method. Use `column()` instead.
|
|
163
|
+
|
|
164
|
+
## CRUD Operations
|
|
165
|
+
|
|
166
|
+
### Insert
|
|
167
|
+
|
|
168
|
+
```twig
|
|
169
|
+
{% set response = crud()
|
|
170
|
+
.table('users')
|
|
171
|
+
.insert({
|
|
172
|
+
"name": "John",
|
|
173
|
+
"email": "john@example.com"
|
|
174
|
+
})
|
|
175
|
+
%}
|
|
176
|
+
|
|
177
|
+
{% if response.success %}
|
|
178
|
+
New ID: {{ response.id }}
|
|
179
|
+
{% else %}
|
|
180
|
+
Error: {{ response.message }}
|
|
181
|
+
{% endif %}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Update
|
|
185
|
+
|
|
186
|
+
```twig
|
|
187
|
+
{% set response = crud()
|
|
188
|
+
.table('users')
|
|
189
|
+
.update({
|
|
190
|
+
"id": 5,
|
|
191
|
+
"name": "John Updated"
|
|
192
|
+
})
|
|
193
|
+
%}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Delete
|
|
197
|
+
|
|
198
|
+
```twig
|
|
199
|
+
{% set response = crud()
|
|
200
|
+
.table('users')
|
|
201
|
+
.delete({
|
|
202
|
+
"id": 5
|
|
203
|
+
})
|
|
204
|
+
%}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Without Authentication (for webservices)
|
|
208
|
+
|
|
209
|
+
```twig
|
|
210
|
+
{% set response = crud('default', false)
|
|
211
|
+
.table('submissions')
|
|
212
|
+
.insert({...})
|
|
213
|
+
%}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Object Spec Helper Functions
|
|
217
|
+
|
|
218
|
+
Functions available in `processing_code` and `template_code`:
|
|
219
|
+
|
|
220
|
+
| Function | Context | Description |
|
|
221
|
+
|----------|---------|-------------|
|
|
222
|
+
| `getValue('column')` | processing_code | Get current record field value |
|
|
223
|
+
| `setValue('column', value)` | processing_code | Set field value |
|
|
224
|
+
| `errorMessage('msg')` | processing_code | Show error and stop processing |
|
|
225
|
+
| `getParameter('name')` | both | Get POST/GET parameter |
|
|
226
|
+
| `currentUser('field')` | both | Get current user info |
|
|
227
|
+
| `info.column` | template_code | Access current record data |
|
|
228
|
+
|
|
229
|
+
### Examples
|
|
230
|
+
|
|
231
|
+
```twig
|
|
232
|
+
{# In processing_code #}
|
|
233
|
+
{% set status = getValue('status') %}
|
|
234
|
+
{{ setValue('updated_at', 'now'|date('Y-m-d H:i:s')) }}
|
|
235
|
+
{{ errorMessage('Validation failed') }}
|
|
236
|
+
|
|
237
|
+
{# Get request parameter #}
|
|
238
|
+
{% set action = getParameter('action') %}
|
|
239
|
+
|
|
240
|
+
{# Get current user #}
|
|
241
|
+
{% set userId = currentUser('id') %}
|
|
242
|
+
{% set userEmail = currentUser('email') %}
|
|
243
|
+
|
|
244
|
+
{# In template_code #}
|
|
245
|
+
{{ info.title }}
|
|
246
|
+
{{ info.status }}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Settings
|
|
250
|
+
|
|
251
|
+
Retrieve application settings stored in `cms_setting_groups` and `cms_settings` tables.
|
|
252
|
+
|
|
253
|
+
```twig
|
|
254
|
+
{# Get a single setting value #}
|
|
255
|
+
{% set apiKey = setting('payment', 'api_key') %}
|
|
256
|
+
|
|
257
|
+
{# Get all settings in a group (returns object with alias => row mapping) #}
|
|
258
|
+
{% set paymentSettings = setting('payment') %}
|
|
259
|
+
{{ paymentSettings.api_key.value }}
|
|
260
|
+
{{ paymentSettings.secret_key.value }}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
| Parameter | Description |
|
|
264
|
+
|-----------|-------------|
|
|
265
|
+
| `group` | The `alias` from `cms_setting_groups` |
|
|
266
|
+
| `setting` | (Optional) The `alias` from `cms_settings` |
|
|
267
|
+
|
|
268
|
+
**Returns:** When `setting` is provided, returns the `value` field. When omitted, returns all settings in the group as `{alias: {value, val_1, val_2, ...}}`.
|
|
269
|
+
|
|
270
|
+
## Important Notes
|
|
271
|
+
|
|
272
|
+
1. **Integer indexes don't work in Twig arrays.** Use string prefixes:
|
|
273
|
+
```twig
|
|
274
|
+
{# Wrong #}
|
|
275
|
+
{% set data = {0: 'a', 1: 'b'} %}
|
|
276
|
+
|
|
277
|
+
{# Correct #}
|
|
278
|
+
{% set data = {'item_0': 'a', 'item_1': 'b'} %}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
2. **Cannot query multiple databases in single query.** Use separate queries.
|
|
282
|
+
|
|
283
|
+
3. **Error checking:** Always check `.butterfly/error_log.txt` for Twig errors.
|