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

What Are Templates?

Templates define:
  • Custom Fields: Specific attributes for your assets (e.g., ISBN for books, vintage year for wine)
  • Field Types: Text, numbers, dates, dropdowns, checkboxes, etc.
  • Validation Rules: Required fields, min/max values, patterns
  • Categories: Classification for organizing templates
  • Metadata: Name, description, author information

Template Structure

Templates are represented by the AssetTemplate model (from lib/data/models/asset_template_model.dart:3):
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

1

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 any standard naming conventions (like ISBN, SKU, etc.)?
2

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
3

Choose a Category

Templates are organized by category:
  • Literature (books, magazines, comics)
  • Electronics (phones, cameras, laptops)
  • Collectibles (cards, coins, stamps)
  • Tools (power tools, hand tools)
  • Wine & Spirits
  • Art & Antiques
  • Sports Equipment
  • Custom categories

Creating Your First Template

Let’s create a template for a book collection.

Step 1: Define Basic Information

Start with the template metadata:
{
  "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": []
}

Step 2: Add Custom Fields

Define the fields for your book template:
{
  "fields": [
    {
      "name": "ISBN",
      "key": "isbn",
      "type": "text",
      "required": false,
      "description": "International Standard Book Number",
      "validation": {
        "pattern": "^[0-9-]{10,17}$"
      }
    },
    {
      "name": "Author",
      "key": "author",
      "type": "text",
      "required": true,
      "description": "Book author name"
    },
    {
      "name": "Publication Year",
      "key": "publication_year",
      "type": "number",
      "required": false,
      "validation": {
        "min": 1000,
        "max": 2100
      }
    },
    {
      "name": "Genre",
      "key": "genre",
      "type": "dropdown",
      "required": false,
      "options": [
        "Fiction",
        "Non-Fiction",
        "Mystery",
        "Science Fiction",
        "Fantasy",
        "Biography",
        "History",
        "Other"
      ]
    },
    {
      "name": "Page Count",
      "key": "page_count",
      "type": "number",
      "required": false,
      "validation": {
        "min": 1
      }
    },
    {
      "name": "Reading Status",
      "key": "reading_status",
      "type": "dropdown",
      "required": false,
      "options": [
        "To Read",
        "Reading",
        "Completed",
        "On Hold"
      ]
    },
    {
      "name": "Favorite",
      "key": "is_favorite",
      "type": "boolean",
      "required": false,
      "description": "Mark as a favorite book"
    },
    {
      "name": "Date Acquired",
      "key": "date_acquired",
      "type": "date",
      "required": false
    },
    {
      "name": "Notes",
      "key": "notes",
      "type": "textarea",
      "required": false,
      "description": "Personal notes and thoughts"
    }
  ]
}

Step 3: Test Locally

In Invenicum:
  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

Step 4: Publish to Marketplace

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

Field Types Reference

Text Field

Single-line text input.
{
  "name": "Title",
  "key": "title",
  "type": "text",
  "required": true,
  "validation": {
    "maxLength": 200,
    "pattern": "^[a-zA-Z0-9\\s]+$"
  }
}
Validation Options:
  • maxLength: Maximum character count
  • minLength: Minimum character count
  • pattern: Regular expression pattern

Textarea Field

Multi-line text input for longer content.
{
  "name": "Description",
  "key": "description",
  "type": "textarea",
  "required": false,
  "validation": {
    "maxLength": 1000
  }
}

Number Field

Numeric input with optional min/max validation.
{
  "name": "Quantity",
  "key": "quantity",
  "type": "number",
  "required": true,
  "validation": {
    "min": 0,
    "max": 10000
  }
}
Validation Options:
  • min: Minimum value
  • max: Maximum value
  • step: Increment step (e.g., 0.01 for decimals)

Date Field

Date picker input.
{
  "name": "Purchase Date",
  "key": "purchase_date",
  "type": "date",
  "required": false
}
Select from predefined options.
{
  "name": "Condition",
  "key": "condition",
  "type": "dropdown",
  "required": true,
  "options": [
    "Mint",
    "Excellent",
    "Good",
    "Fair",
    "Poor"
  ]
}

Boolean Field

Checkbox for true/false values.
{
  "name": "In Stock",
  "key": "in_stock",
  "type": "boolean",
  "required": false,
  "defaultValue": true
}

URL Field

Validated URL input.
{
  "name": "Product Link",
  "key": "product_url",
  "type": "url",
  "required": false,
  "validation": {
    "pattern": "^https?://.*"
  }
}

Template Categories

Organize templates by category for easier discovery:
CategoryExamples
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
Create custom categories as needed.

Template Service API

The TemplateService (from lib/data/services/template_service.dart:5) provides methods for template management:

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(),
  );
  
  final data = response.data['data'];
  return AssetTemplate.fromJson(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

{
  "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",
      "required": false
    },
    {
      "name": "Region",
      "key": "region",
      "type": "text",
      "required": false,
      "description": "e.g., Bordeaux, Napa Valley"
    },
    {
      "name": "Alcohol Content (%)",
      "key": "alcohol_content",
      "type": "number",
      "required": false,
      "validation": {
        "min": 0,
        "max": 25,
        "step": 0.1
      }
    },
    {
      "name": "Bottle Size (ml)",
      "key": "bottle_size",
      "type": "dropdown",
      "required": false,
      "options": ["375", "750", "1000", "1500"]
    },
    {
      "name": "Drink By Year",
      "key": "drink_by_year",
      "type": "number",
      "required": false
    },
    {
      "name": "Tasting Notes",
      "key": "tasting_notes",
      "type": "textarea",
      "required": false
    },
    {
      "name": "Rating (1-5)",
      "key": "rating",
      "type": "number",
      "required": false,
      "validation": {
        "min": 1,
        "max": 5
      }
    },
    {
      "name": "Cellared",
      "key": "is_cellared",
      "type": "boolean",
      "required": false
    }
  ]
}

Camera Collection Template

{
  "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",
      "required": false,
      "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",
      "required": false,
      "options": [
        "Full Frame",
        "APS-C",
        "Micro 4/3",
        "35mm Film",
        "120 Film",
        "4x5 Film"
      ]
    },
    {
      "name": "Megapixels",
      "key": "megapixels",
      "type": "number",
      "required": false,
      "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",
      "required": false,
      "options": ["Mint", "Excellent", "Good", "Fair", "Poor"]
    },
    {
      "name": "Serial Number",
      "key": "serial_number",
      "type": "text",
      "required": false
    },
    {
      "name": "Included Accessories",
      "key": "accessories",
      "type": "textarea",
      "required": false,
      "description": "Lenses, cases, manuals, etc."
    }
  ]
}

Trading Card Template

{
  "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",
      "required": false
    },
    {
      "name": "Card Number",
      "key": "card_number",
      "type": "text",
      "required": false
    },
    {
      "name": "Year",
      "key": "year",
      "type": "number",
      "required": false
    },
    {
      "name": "Rarity",
      "key": "rarity",
      "type": "dropdown",
      "required": false,
      "options": [
        "Common",
        "Uncommon",
        "Rare",
        "Ultra Rare",
        "Secret Rare",
        "Legendary"
      ]
    },
    {
      "name": "Graded",
      "key": "is_graded",
      "type": "boolean",
      "required": false
    },
    {
      "name": "Grade",
      "key": "grade",
      "type": "text",
      "required": false,
      "description": "e.g., PSA 10, BGS 9.5"
    },
    {
      "name": "Grading Company",
      "key": "grading_company",
      "type": "dropdown",
      "required": false,
      "options": ["PSA", "BGS", "CGC", "SGC", "Other"]
    },
    {
      "name": "Condition (Ungraded)",
      "key": "condition",
      "type": "dropdown",
      "required": false,
      "options": [
        "Mint",
        "Near Mint",
        "Excellent",
        "Good",
        "Fair",
        "Poor"
      ]
    },
    {
      "name": "Market Value",
      "key": "market_value",
      "type": "number",
      "required": false,
      "description": "Estimated current market value"
    }
  ]
}

Quality Guidelines

When creating templates for the marketplace:

Naming

  • Use clear, descriptive names
  • Avoid abbreviations unless widely recognized
  • Be specific (“Vintage Cameras” vs “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 tag 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

1

Finalize Your Template

  • Review all fields and validation
  • Test thoroughly with sample data
  • Write a clear description
  • Choose appropriate category and tags
2

Publish to Marketplace

In Invenicum:
  1. Go to Settings > Templates
  2. Select your template
  3. Click “Publish to Marketplace”
  4. Review the submission
  5. Confirm publication
3

Monitor Usage

Track your template’s performance:
  • Download count
  • User feedback
  • Update as needed

Best Practices

Begin with essential fields. You can always add more in updates. Too many fields overwhelm users.
Dropdowns are great for standardization but limit flexibility. Use them for fields with a known, limited set of options.
Fields users will search/filter by should be consistent (dropdowns, standardized text).
If your collection type has industry standards (ISBN, UPC, model numbers), include those fields.
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 keys
  • Ensure field keys use valid characters (letters, numbers, underscores)

Validation Not Working

  • Verify validation syntax matches field type
  • Test with edge cases
  • Check for typos in validation rules

Published Template Not Appearing

  • Wait a few minutes for sync
  • Verify isPublic is set to true
  • Check that category is valid
  • Ensure template has at least one field

Next Steps

Plugin Development

Extend Invenicum with custom plugins

Contributing Guide

Contribute to the Invenicum project

Resources

Build docs developers (and LLMs) love