ContributingTemplate Creation

CONTRIBUTING

Template Creation

Learn how to create custom asset templates for specialized collections in Invenicum.

Asset templates allow you to define custom structures for specific types of collections. Whether you’re cataloging books, wine, vintage cameras, or trading cards, templates provide a standardized way to capture the metadata that matters for your collection.


What Are Templates?

Custom Fields

Specific attributes for your assets — e.g. ISBN for books, vintage year for wine

Field Types

Text, numbers, dates, dropdowns, checkboxes and more

Validation Rules

Required fields, min/max values, regex patterns

Categories

Classification for organizing and discovering templates

Metadata

Name, description, author information, download count

Template Structure

Templates are represented by the AssetTemplate model (asset_template_model.dart:3):

asset_template_model.dart
class AssetTemplate {
final String id;
final String name;
final String description;
final String category;
final List<String> tags;
final String author;
final String? authorAvatarUrl;
final String? downloadUrl;
final List<CustomFieldDefinition> fields;
final bool isOfficial;
final bool isPublic;
final int downloadCount;
final DateTime? createdAt;
final DateTime? updatedAt;
}

Getting Started

Step 01

Plan Your Template

Before creating a template, answer these questions:

What type of items will this template describe?
What information is essential to capture?
What fields will help with searching and filtering?
Are there standard naming conventions (ISBN, SKU, etc.)?
Step 02

Understand Custom Fields

Custom fields are the building blocks of templates. Each field has:

Name

Display label — e.g. "Publication Year"

Key

Internal identifier — e.g. "publication_year"

Type

Data type: text, number, date, boolean, dropdown

Required

Whether the field must be filled

Validation

Rules for valid input

Step 03

Choose a Category

LiteratureElectronicsCollectiblesToolsWine & SpiritsArt & AntiquesSports EquipmentCustom categories

Creating Your First Template

Let’s create a template for a book collection step by step.

1Define Basic Information
{
"name": "Book Collection",
"description": "Track books with ISBN, author, genre, and reading status",
"category": "Literature",
"tags": ["books", "reading", "library"],
"author": "your-github-username",
"isPublic": true,
"fields": []
}
2Add Custom Fields9 fields for a complete book template
{
"fields": [
  {
    "name": "ISBN",       "key": "isbn",
    "type": "text",       "required": false,
    "validation": { "pattern": "^[0-9-]{10,17}$" }
  },
  {
    "name": "Author",     "key": "author",
    "type": "text",       "required": true
  },
  {
    "name": "Publication Year", "key": "publication_year",
    "type": "number",
    "validation": { "min": 1000, "max": 2100 }
  },
  {
    "name": "Genre",      "key": "genre",
    "type": "dropdown",
    "options": ["Fiction", "Non-Fiction", "Mystery",
      "Science Fiction", "Fantasy", "Biography", "History", "Other"]
  },
  {
    "name": "Reading Status", "key": "reading_status",
    "type": "dropdown",
    "options": ["To Read", "Reading", "Completed", "On Hold"]
  },
  {
    "name": "Favorite",   "key": "is_favorite",
    "type": "boolean",    "description": "Mark as a favorite book"
  },
  {
    "name": "Date Acquired", "key": "date_acquired",
    "type": "date"
  },
  {
    "name": "Notes",      "key": "notes",
    "type": "textarea",   "description": "Personal notes and thoughts"
  }
]
}
3Test Locally
1.Go to Settings > Templates > Create New
2.Fill in the template information
3.Add your custom fields one by one
4.Save as a draft
5.Test by creating an asset using this template
6.Verify all fields work as expected
4Publish to Marketplace

Once tested, publish your template to share it with the Invenicum community marketplace.

See the Publishing section below for full steps

Field Types Reference

textSingle-line text input

Validation Options

  • maxLength — Maximum character count
  • minLength — Minimum character count
  • pattern — Regular expression pattern
{
"name": "Title",      "key": "title",
"type": "text",       "required": true,
"validation": {
  "maxLength": 200,
  "pattern": "^[a-zA-Z0-9\\s]+$"
}
}
textareaMulti-line text for longer content

Validation Options

  • maxLength — Maximum character count
{
"name": "Description", "key": "description",
"type": "textarea",    "required": false,
"validation": { "maxLength": 1000 }
}
numberNumeric input with optional min/max

Validation Options

  • min — Minimum value
  • max — Maximum value
  • step — Increment (e.g. 0.01 for decimals)
{
"name": "Quantity",   "key": "quantity",
"type": "number",     "required": true,
"validation": { "min": 0, "max": 10000 }
}
dateDate picker input

No additional validation options — date format is handled automatically.

{
"name": "Purchase Date", "key": "purchase_date",
"type": "date",          "required": false
}
dropdownSelect from predefined options

Validation Options

  • options — Array of selectable string values
{
"name": "Condition",  "key": "condition",
"type": "dropdown",   "required": true,
"options": ["Mint", "Excellent", "Good", "Fair", "Poor"]
}
booleanCheckbox for true / false values

Validation Options

  • defaultValue — Initial boolean value
{
"name": "In Stock",   "key": "in_stock",
"type": "boolean",    "required": false,
"defaultValue": true
}
urlValidated URL input — clickable in item views

Validation Options

  • pattern — e.g. "^https?://.*"
{
"name": "Product Link", "key": "product_url",
"type": "url",          "required": false,
"validation": { "pattern": "^https?://.*" }
}

Template Categories

LiteratureBooks, magazines, comics, manuscripts
ElectronicsPhones, laptops, cameras, accessories
CollectiblesTrading cards, stamps, coins, memorabilia
ToolsPower tools, hand tools, equipment
Wine & SpiritsWine bottles, whiskey, craft beer
Art & AntiquesPaintings, sculptures, vintage items
SportsEquipment, jerseys, memorabilia
MusicVinyl records, instruments, gear
GamingVideo games, consoles, accessories
AutomotiveCar parts, motorcycles, accessories

Template Service API

The TemplateService (template_service.dart:5) provides the following methods:

Get Market Templates

Retrieve all publicly available templates

Future<List<AssetTemplate>> getMarketTemplates() async {
const url = '/templates/market';
final response = await _dio.get(url);
final List<dynamic> data = response.data;
return data.map((json) =>
  AssetTemplate.fromJson(json)).toList();
}

Publish Template

Publish a template to the marketplace

Future<AssetTemplate> publishTemplate(
  AssetTemplate template) async {
final response = await _dio.post(
  '/templates/publish',
  data: template.toJson(),
);
return AssetTemplate.fromJson(response.data['data']);
}

Get User Library

Get templates created by the current user

Future<List<AssetTemplate>> getUserLibrary() async {
const url = '/templates/my-library';
final response = await _dio.get(url);
final List<dynamic> data = response.data;
return data.map((json) =>
  AssetTemplate.fromJson(json)).toList();
}

Track Downloads

Increment download counter when template is used

Future<void> trackDownload(String templateId) async {
final url = '/templates/$templateId/download';
await _dio.post(url);
}

Advanced Template Examples

Wine Collection Template

11 fields · Wine & Spirits · vintage, region, tasting notes

{
"name": "Wine Collection",
"description": "Track wine bottles with vintage, region, and tasting notes",
"category": "Wine & Spirits",
"tags": ["wine", "cellar", "tasting"],
"fields": [
  { "name": "Vineyard",        "key": "vineyard",        "type": "text",     "required": true },
  { "name": "Vintage Year",    "key": "vintage_year",    "type": "number",   "required": true,
    "validation": { "min": 1900, "max": 2026 } },
  { "name": "Wine Type",       "key": "wine_type",       "type": "dropdown", "required": true,
    "options": ["Red", "White", "Rosé", "Sparkling", "Dessert", "Fortified"] },
  { "name": "Grape Varietal",  "key": "grape_varietal",  "type": "text" },
  { "name": "Region",          "key": "region",          "type": "text",
    "description": "e.g., Bordeaux, Napa Valley" },
  { "name": "Alcohol Content (%)", "key": "alcohol_content", "type": "number",
    "validation": { "min": 0, "max": 25, "step": 0.1 } },
  { "name": "Bottle Size (ml)","key": "bottle_size",     "type": "dropdown",
    "options": ["375", "750", "1000", "1500"] },
  { "name": "Drink By Year",   "key": "drink_by_year",   "type": "number" },
  { "name": "Tasting Notes",   "key": "tasting_notes",   "type": "textarea" },
  { "name": "Rating (1-5)",    "key": "rating",          "type": "number",
    "validation": { "min": 1, "max": 5 } },
  { "name": "Cellared",        "key": "is_cellared",     "type": "boolean" }
]
}

Camera Collection Template

10 fields · Electronics · manufacturer, model, sensor, condition

{
"name": "Vintage Cameras",
"description": "Catalog vintage and modern cameras with technical specs",
"category": "Electronics",
"tags": ["cameras", "photography", "vintage"],
"fields": [
  { "name": "Manufacturer",    "key": "manufacturer",    "type": "text",     "required": true },
  { "name": "Model",           "key": "model",           "type": "text",     "required": true },
  { "name": "Year Released",   "key": "year_released",   "type": "number",
    "validation": { "min": 1800, "max": 2026 } },
  { "name": "Camera Type",     "key": "camera_type",     "type": "dropdown", "required": true,
    "options": ["Film SLR", "Digital SLR", "Mirrorless", "Rangefinder",
      "Medium Format", "Large Format", "Point & Shoot"] },
  { "name": "Sensor/Film Size","key": "sensor_size",     "type": "dropdown",
    "options": ["Full Frame", "APS-C", "Micro 4/3", "35mm Film", "120 Film", "4x5 Film"] },
  { "name": "Megapixels",      "key": "megapixels",      "type": "number",
    "description": "For digital cameras" },
  { "name": "Working Condition","key": "working_condition","type": "dropdown","required": true,
    "options": ["Fully Functional", "Partially Working", "Not Working", "Untested"] },
  { "name": "Cosmetic Condition","key": "cosmetic_condition","type": "dropdown",
    "options": ["Mint", "Excellent", "Good", "Fair", "Poor"] },
  { "name": "Serial Number",   "key": "serial_number",   "type": "text" },
  { "name": "Included Accessories","key": "accessories", "type": "textarea",
    "description": "Lenses, cases, manuals, etc." }
]
}

Trading Card Template

11 fields · Collectibles · rarity, grading, market value

{
"name": "Trading Cards",
"description": "Track sports, Pokemon, and other collectible trading cards",
"category": "Collectibles",
"tags": ["cards", "collectibles", "trading-cards"],
"fields": [
  { "name": "Card Name",       "key": "card_name",       "type": "text",     "required": true },
  { "name": "Card Type",       "key": "card_type",       "type": "dropdown", "required": true,
    "options": ["Sports - Baseball", "Sports - Basketball", "Sports - Football",
      "Sports - Soccer", "Pokemon", "Magic: The Gathering", "Yu-Gi-Oh!", "Other TCG"] },
  { "name": "Set Name",        "key": "set_name",        "type": "text" },
  { "name": "Card Number",     "key": "card_number",     "type": "text" },
  { "name": "Year",            "key": "year",            "type": "number" },
  { "name": "Rarity",          "key": "rarity",          "type": "dropdown",
    "options": ["Common", "Uncommon", "Rare", "Ultra Rare", "Secret Rare", "Legendary"] },
  { "name": "Graded",          "key": "is_graded",       "type": "boolean" },
  { "name": "Grade",           "key": "grade",           "type": "text",
    "description": "e.g., PSA 10, BGS 9.5" },
  { "name": "Grading Company", "key": "grading_company", "type": "dropdown",
    "options": ["PSA", "BGS", "CGC", "SGC", "Other"] },
  { "name": "Condition (Ungraded)","key": "condition",   "type": "dropdown",
    "options": ["Mint", "Near Mint", "Excellent", "Good", "Fair", "Poor"] },
  { "name": "Market Value",    "key": "market_value",    "type": "number",
    "description": "Estimated current market value" }
]
}

Quality Guidelines

Naming

  • Use clear, descriptive names
  • Avoid abbreviations unless widely recognized
  • "Vintage Cameras" not "Cameras"

Descriptions

  • Explain what the template is for
  • Mention key fields included
  • Keep it under 200 characters
  • No marketing language

Field Design

  • Order fields logically — most important first
  • Use appropriate field types
  • Add descriptions for non-obvious fields
  • Set reasonable validation rules
  • Mark truly required fields only

Categories & Tags

  • Choose the most relevant category
  • Add 3–5 descriptive tags
  • Use consistent formatting (lowercase, hyphens)

Testing

  • Test with real data before publishing
  • Verify all validations work correctly
  • Check field order makes sense
  • Ensure dropdown options are comprehensive

Publishing Your Template

Step 01

Finalize Your Template

Review all fields and validationTest thoroughly with sample dataWrite a clear descriptionChoose appropriate category and tags
Step 02

Publish to Marketplace

1.Go to Settings > Templates
2.Select your template
3.Click "Publish to Marketplace"
4.Review the submission
5.Confirm publication
Step 03

Monitor Usage

Track download countReview user feedbackUpdate template as needed

Best Practices

Start Simple

Begin with essential fields. You can always add more in updates. Too many fields overwhelm users.

Use Dropdowns Wisely

Dropdowns are great for standardization but limit flexibility. Use them for fields with a known, limited set of options.

Think About Searching

Fields users will search/filter by should be consistent — dropdowns and standardized text work best.

Consider Market Standards

If your collection type has industry standards (ISBN, UPC, model numbers), include those fields.

Plan for Growth

Design templates that can evolve. Avoid overly specific fields that might not apply to all items.

Troubleshooting

Template Won’t Save
  • Verify all required fields are filled
  • Check for duplicate field key values
  • Ensure field keys use only valid characters (letters, numbers, underscores)
Validation Not Working
  • Verify validation syntax matches the field type
  • Test with edge cases (min, max, empty values)
  • Check for typos in validation rules
Published Template Not Appearing
  • Wait a few minutes for marketplace sync
  • Verify “isPublic” is set to true
  • Check that the category is valid
  • Ensure the template has at least one field
Previous

Plugin Development

End of Contributing

Section complete