feat: add Carbone tags help - view in-app modal and download as .docx
This commit is contained in:
BIN
renderer/carbone-templates/HELP_TAGS_REFERENCE.docx
Normal file
BIN
renderer/carbone-templates/HELP_TAGS_REFERENCE.docx
Normal file
Binary file not shown.
364
renderer/carbone-templates/HELP_TAGS_REFERENCE.md
Normal file
364
renderer/carbone-templates/HELP_TAGS_REFERENCE.md
Normal file
@@ -0,0 +1,364 @@
|
||||
# Carbone Template Tags Reference
|
||||
|
||||
This document lists all available Carbone tags you can use in your CV templates (.docx files).
|
||||
You can use these tags when editing your template in Microsoft Word or LibreOffice.
|
||||
|
||||
---
|
||||
|
||||
## 1. Personal Details (Simple Text Tags)
|
||||
|
||||
These tags are replaced with the candidate's personal information.
|
||||
|
||||
| Tag | Description | Example Output |
|
||||
|-----|-------------|----------------|
|
||||
| `{d.fullName}` | Full name (first + last) | John Smith |
|
||||
| `{d.firstName}` | First name only | John |
|
||||
| `{d.lastName}` | Last name only | Smith |
|
||||
| `{d.email}` | Email address | john.smith@email.com |
|
||||
| `{d.phone}` | Phone number | +1-555-123-4567 |
|
||||
| `{d.address}` | Physical address | Cape Town, South Africa |
|
||||
| `{d.linkedin}` | LinkedIn profile URL | linkedin.com/in/johnsmith |
|
||||
| `{d.github}` | GitHub profile URL | github.com/jsmith |
|
||||
| `{d.website}` | Personal website | www.johnsmith.com |
|
||||
| `{d.summary}` | Professional summary paragraph | Experienced software engineer... |
|
||||
| `{d.generationDate}` | Date the CV was generated | July 16, 2026 |
|
||||
|
||||
---
|
||||
|
||||
## 2. Work Experience (Loop Tags)
|
||||
|
||||
Loop tags repeat a section of your document for each item in an array.
|
||||
Carbone automatically detects loops when you use `[i]` in the tag name.
|
||||
|
||||
### Basic Loop Fields
|
||||
|
||||
| Tag | Description | Example Output |
|
||||
|-----|-------------|----------------|
|
||||
| `{d.experience[i].position}` | Job title | Senior Software Engineer |
|
||||
| `{d.experience[i].company}` | Company name | TechCorp International |
|
||||
| `{d.experience[i].location}` | Work location | Cape Town |
|
||||
| `{d.experience[i].startDate}` | Start date (formatted) | Jan 2022 |
|
||||
| `{d.experience[i].endDate}` | End date or "Present" | Present |
|
||||
| `{d.experience[i].duration}` | Calculated duration | 4.5 years |
|
||||
| `{d.experience[i].description}` | Job description | Led a team building microservices |
|
||||
| `{d.experience[i].skillsUsed}` | Comma-separated skills used | C#, Azure, Docker |
|
||||
|
||||
### Achievements Sub-Loop
|
||||
|
||||
Inside the experience section, you can loop through achievements:
|
||||
|
||||
| Tag | Description |
|
||||
|-----|-------------|
|
||||
| `{d.experience[i].achievements[j]}` | Individual achievement bullet point |
|
||||
|
||||
### How to Set Up a Loop in Word
|
||||
|
||||
In your Word document, simply write the tags in the section you want repeated.
|
||||
Carbone auto-detects the loop boundaries based on the document structure
|
||||
(paragraphs, table rows, or list items).
|
||||
|
||||
Example layout in Word:
|
||||
```
|
||||
{d.experience[i].position} at {d.experience[i].company}
|
||||
{d.experience[i].startDate} - {d.experience[i].endDate} ({d.experience[i].duration})
|
||||
{d.experience[i].description}
|
||||
|
||||
• {d.experience[i].achievements[j]}
|
||||
|
||||
Skills used: {d.experience[i].skillsUsed}
|
||||
```
|
||||
|
||||
For each job entry in the candidate's data, Carbone will duplicate this block
|
||||
and fill in the values.
|
||||
|
||||
---
|
||||
|
||||
## 3. Skills (Loop Tags)
|
||||
|
||||
### Flat Skills List
|
||||
|
||||
| Tag | Description | Example Output |
|
||||
|-----|-------------|----------------|
|
||||
| `{d.skills[i].name}` | Skill name | C# / .NET |
|
||||
| `{d.skills[i].category}` | Skill category | Programming |
|
||||
| `{d.skills[i].proficiency}` | Proficiency level | Expert |
|
||||
| `{d.skills[i].years}` | Years of experience (dynamic) | 8.5 |
|
||||
| `{d.skills[i].startYear}` | Year started | 2018 |
|
||||
|
||||
### Skills Grouped by Category
|
||||
|
||||
Use this when you want skills organized under category headings:
|
||||
|
||||
| Tag | Description | Example Output |
|
||||
|-----|-------------|----------------|
|
||||
| `{d.skillsByCategory[i].category}` | Category name | Programming |
|
||||
| `{d.skillsByCategory[i].skills[j].name}` | Skill name within category | C# / .NET |
|
||||
| `{d.skillsByCategory[i].skills[j].years}` | Years of experience | 8.5 |
|
||||
| `{d.skillsByCategory[i].skills[j].proficiency}` | Proficiency level | Expert |
|
||||
|
||||
Example layout in Word:
|
||||
```
|
||||
{d.skillsByCategory[i].category}:
|
||||
• {d.skillsByCategory[i].skills[j].name} ({d.skillsByCategory[i].skills[j].years}y)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Education (Loop Tags)
|
||||
|
||||
| Tag | Description | Example Output |
|
||||
|-----|-------------|----------------|
|
||||
| `{d.education[i].degree}` | Degree name | BSc Computer Science |
|
||||
| `{d.education[i].field}` | Field of study | Computer Science |
|
||||
| `{d.education[i].institution}` | University/institution | University of Cape Town |
|
||||
| `{d.education[i].startDate}` | Start date | Jan 2014 |
|
||||
| `{d.education[i].endDate}` | End date | Dec 2017 |
|
||||
| `{d.education[i].grade}` | Grade/result | First Class Honours |
|
||||
|
||||
---
|
||||
|
||||
## 5. Certifications (Loop Tags)
|
||||
|
||||
| Tag | Description | Example Output |
|
||||
|-----|-------------|----------------|
|
||||
| `{d.certifications[i].name}` | Certification name | Azure Developer Associate |
|
||||
| `{d.certifications[i].issuer}` | Issuing organization | Microsoft |
|
||||
| `{d.certifications[i].date}` | Issue date | Jun 2021 |
|
||||
| `{d.certifications[i].expiryDate}` | Expiry date (if any) | Jun 2024 |
|
||||
|
||||
---
|
||||
|
||||
## 6. Conditional Tags (Show/Hide Content)
|
||||
|
||||
Conditionals let you show or hide content based on whether a field has a value.
|
||||
|
||||
### Show if NOT Empty: `:showBegin` / `:showEnd`
|
||||
|
||||
Only shows the content between the markers if the field has a value:
|
||||
|
||||
```
|
||||
{d.linkedin:showBegin}LinkedIn: {d.linkedin}{d.linkedin:showEnd}
|
||||
```
|
||||
|
||||
If the candidate has no LinkedIn, the entire "LinkedIn: ..." text is hidden.
|
||||
|
||||
### Hide if NOT Empty: `:hideBegin` / `:hideEnd`
|
||||
|
||||
Shows content only if the field IS empty (opposite of showBegin):
|
||||
|
||||
```
|
||||
{d.website:hideBegin}No website provided{d.website:hideEnd}
|
||||
```
|
||||
|
||||
### If Empty: `:ifEM`
|
||||
|
||||
Shows the replacement text if the field is empty:
|
||||
|
||||
```
|
||||
{d.address:ifEM(Address not provided)}
|
||||
```
|
||||
|
||||
### If Not Empty: `:ifNEM`
|
||||
|
||||
Shows the replacement text if the field has a value:
|
||||
|
||||
```
|
||||
{d.email:ifNEM(Email verified)}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Formatting Tags
|
||||
|
||||
### Date Formatting: `:formatD`
|
||||
|
||||
Format dates inside your template:
|
||||
|
||||
```
|
||||
{d.experience[i].startDate:formatD(YYYY-MM-DD)} -> 2022-01-01
|
||||
{d.experience[i].startDate:formatD(MMM YYYY)} -> Jan 2022
|
||||
{d.experience[i].startDate:formatD(DD/MM/YYYY)} -> 01/01/2022
|
||||
```
|
||||
|
||||
Note: Our system already pre-formats dates as "Mon YYYY", so you typically
|
||||
don't need this formatter unless you want a different format.
|
||||
|
||||
### Number Formatting: `:formatN`
|
||||
|
||||
```
|
||||
{d.skills[i].years:formatN(0.0)} -> 8.5
|
||||
{d.skills[i].years:formatN(0)} -> 9
|
||||
```
|
||||
|
||||
### Case Conversion
|
||||
|
||||
```
|
||||
{d.fullName:upperCase} -> JOHN SMITH
|
||||
{d.fullName:lowerCase} -> john smith
|
||||
{d.fullName:ucFirst} -> John smith
|
||||
{d.fullName:ucWords} -> John Smith
|
||||
```
|
||||
|
||||
### Text Operations
|
||||
|
||||
```
|
||||
{d.summary:substr(0, 100)} -> First 100 characters of summary
|
||||
{d.summary:slice(0, 50)} -> First 50 characters
|
||||
{d.email:padl(30)} -> Padded to 30 chars on the left
|
||||
{d.email:padr(30)} -> Padded to 30 chars on the right
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Comparison Conditionals
|
||||
|
||||
These conditionals compare a field to a specific value:
|
||||
|
||||
### If Equal: `:ifEQ`
|
||||
|
||||
```
|
||||
{d.skills[i].proficiency:ifEQ(Expert):showBegin}
|
||||
This person is an expert!
|
||||
{d.skills[i].proficiency:showEnd}
|
||||
```
|
||||
|
||||
### If Not Equal: `:ifNE`
|
||||
|
||||
```
|
||||
{d.experience[i].endDate:ifNE():showBegin}
|
||||
(Former position)
|
||||
{d.experience[i].endDate:showEnd}
|
||||
```
|
||||
|
||||
### If Greater Than: `:ifGT`
|
||||
|
||||
```
|
||||
{d.skills[i].years:ifGT(5):showBegin}Senior level{d.skills[i].years:showEnd}
|
||||
```
|
||||
|
||||
### If Greater Than or Equal: `:ifGTE`
|
||||
|
||||
```
|
||||
{d.skills[i].years:ifGTE(3):showBegin}Experienced{d.skills[i].years:showEnd}
|
||||
```
|
||||
|
||||
### If Less Than: `:ifLT`
|
||||
|
||||
```
|
||||
{d.skills[i].years:ifLT(2):showBegin}Junior level{d.skills[i].years:showEnd}
|
||||
```
|
||||
|
||||
### If Contains: `:ifContain`
|
||||
|
||||
```
|
||||
{d.skills[i].name:ifContain(Azure):showBegin}Cloud certified{d.skills[i].name:showEnd}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Array Operations
|
||||
|
||||
### Array Join: `:arrayJoin`
|
||||
|
||||
Join all items in an array with a separator:
|
||||
|
||||
```
|
||||
{d.skills:arrayJoin(, )} -> C#, Azure, React, Docker
|
||||
```
|
||||
|
||||
### Array Map: `:arrayMap`
|
||||
|
||||
Extract a specific field from all array items:
|
||||
|
||||
```
|
||||
{d.skills:arrayMap(name):arrayJoin(, )} -> C#, Azure, React, Docker
|
||||
```
|
||||
|
||||
### Count: `:count`
|
||||
|
||||
Count items in an array:
|
||||
|
||||
```
|
||||
{d.experience:count} -> 3
|
||||
{d.skills:count} -> 7
|
||||
```
|
||||
|
||||
### Length: `:len`
|
||||
|
||||
String length:
|
||||
|
||||
```
|
||||
{d.summary:len} -> 145
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Complete Example Template
|
||||
|
||||
Here is how a complete section of your Word document might look:
|
||||
|
||||
```
|
||||
{d.fullName}
|
||||
{d.email} | {d.phone} | {d.address}
|
||||
{d.linkedin:showBegin}LinkedIn: {d.linkedin} | {d.linkedin:showEnd}
|
||||
{d.github:showBegin}GitHub: {d.github}{d.github:showEnd}
|
||||
|
||||
PROFESSIONAL SUMMARY
|
||||
{d.summary}
|
||||
|
||||
WORK EXPERIENCE
|
||||
{d.experience[i].position} at {d.experience[i].company}
|
||||
{d.experience[i].startDate} - {d.experience[i].endDate} ({d.experience[i].duration})
|
||||
{d.experience[i].location:showBegin}Location: {d.experience[i].location}{d.experience[i].location:showEnd}
|
||||
{d.experience[i].description}
|
||||
|
||||
Achievements:
|
||||
• {d.experience[i].achievements[j]}
|
||||
|
||||
Skills used: {d.experience[i].skillsUsed}
|
||||
|
||||
SKILLS
|
||||
{d.skillsByCategory[i].category}:
|
||||
• {d.skillsByCategory[i].skills[j].name} ({d.skillsByCategory[i].skills[j].years}y)
|
||||
{d.skillsByCategory[i].skills[j].proficiency:showBegin} - {d.skillsByCategory[i].skills[j].proficiency}{d.skillsByCategory[i].skills[j].proficiency:showEnd}
|
||||
|
||||
EDUCATION
|
||||
{d.education[i].degree} in {d.education[i].field}
|
||||
{d.education[i].institution}
|
||||
{d.education[i].startDate} - {d.education[i].endDate}
|
||||
{d.education[i].grade:showBegin}Grade: {d.education[i].grade}{d.education[i].grade:showEnd}
|
||||
|
||||
CERTIFICATIONS
|
||||
• {d.certifications[i].name} - {d.certifications[i].issuer} ({d.certifications[i].date})
|
||||
|
||||
Generated on {d.generationDate}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference Card
|
||||
|
||||
| Syntax | Meaning |
|
||||
|--------|---------|
|
||||
| `{d.field}` | Simple text replacement |
|
||||
| `{d.array[i].field}` | Loop - repeats for each array item |
|
||||
| `{d.array[i].subarray[j].field}` | Nested loop |
|
||||
| `:showBegin` / `:showEnd` | Show content if field is not empty |
|
||||
| `:hideBegin` / `:hideEnd` | Show content if field is empty |
|
||||
| `:ifEM(text)` | Show text if field is empty |
|
||||
| `:ifNEM(text)` | Show text if field is not empty |
|
||||
| `:ifEQ(value)` | Show if field equals value |
|
||||
| `:ifNE(value)` | Show if field does not equal value |
|
||||
| `:ifGT(value)` | Show if field is greater than value |
|
||||
| `:ifGTE(value)` | Show if field is greater than or equal |
|
||||
| `:ifLT(value)` | Show if field is less than value |
|
||||
| `:ifLTE(value)` | Show if field is less than or equal |
|
||||
| `:ifContain(text)` | Show if field contains text |
|
||||
| `:formatD(YYYY-MM-DD)` | Format date |
|
||||
| `:formatN(0.0)` | Format number |
|
||||
| `:upperCase` / `:lowerCase` | Case conversion |
|
||||
| `:ucFirst` / `:ucWords` | Capitalize first letter / each word |
|
||||
| `:arrayJoin(, )` | Join array with separator |
|
||||
| `:count` | Count array items |
|
||||
| `:substr(0, 100)` | Substring |
|
||||
| `:padl(30)` / `:padr(30)` | Pad string to length |
|
||||
Reference in New Issue
Block a user