New Project

Reuse & Collections#

Import, collections, choices, and slots

Names: import from export collection extends choice slots style requires kind construction

When to use#

  • import to use another file's assembly or component, or the built-in drawer (std:drawer).
  • collection when one design must come in several "looks" or standards (a US base height vs a slab-front frameless kitchen) without forking the file: standards as params, word-valued settings as choice, and role names (slots) bound to materials, hardware, components or assemblies.

Syntax#

import <Alias> from="lib/x.kdl" export=<Name>[,<Name>]      // or from="std:drawer"
project name="..." units=mm collection=<Name> {
    collection <Name> [extends=<Base>] {
        params { <name> <default> ... }                   // read as coll_<name>
        choice <n>=<word> { <word> <word> ... }           // read as coll_<n>_is_<word> (0 or 1)
        slots { <role> <material|hardware|component|assembly> <Target> [requires="p q"]
                <role> <Target> }                          // a derived collection rebinds
    }
}
  • Import: one line; both values plain text. from= is relative to the importing file's directory (CLI: inside the entry file's directory only, no absolute paths, no .., .kdl only). export= is a comma-separated list; omitted, it takes everything the file offers. The imported file marks what it offers with assembly Name export=Name { ... }. A file resolves in its own scope: an imported drawer sees the drawer file's params, never the importer's. Override at the instance: child nodes on the part (width 800.0) set the assembly's own params. Imported top-level assemblies are templates, never scene roots.
  • std:drawer is built in, works in the browser and on a server: DrawerBox, a box-jointed Baltic-birch drawer box; params width depth height (outside size; origin the top face's south-west corner).
  • Collections: project ... collection=Name selects the one in force; there is no default. extends=Base merges root-first, a derived collection overriding only keys the base declares. choice n=word { words } is project-level only; with n = construction and words face_frame frameless the params are coll_construction_is_face_frame and coll_construction_is_frameless; branch with repeat _ count=coll_construction_is_face_frame {...}. Slots are declared once in the base as name kind Target [requires="p1 p2"]; used as @name wherever a material, hardware, component or assembly name goes (stock @carcass ..., part Door instance=@door {...}, hardware_use @pull qty=1, joinery, finish). requires= lists the params a bound component must declare, checked for every collection's slots whether in force or not.
  • Materials, hardware and joinery are one global catalogue by name across imports, but an imported entry is evaluated in its own file's scope.

Example#

project name="Kitchen Cabinet" units=mm schema_version=1 collection=SlabFrameless {
    import DrawerBox from="std:drawer" export=DrawerBox
    collection UsBase {
        params {
            base_h (in)34.5
            reveal (in)0.125
        }
        choice construction=face_frame { face_frame frameless }
        slots {
            carcass material CarcassPly
        }
    }
    collection SlabFrameless extends=UsBase {
        params { base_h (in)36 }
        choice construction=frameless
    }
    materials { material CarcassPly type=sheet nominal_th=18.0 finished_th=17.6 }
    assembly Cabinet {
        part Side material=@carcass role=side {
            stock @carcass 560.0 "coll_base_h" 17.6
            by top_sw
            pos x=0.0 y=0.0 z=0.0
        }
        part Drawer instance=DrawerBox width=400.0 depth=450.0 height=120.0 {
            by top_sw
            pos x=20.0 y=0.0 z=-100.0
        }
    }
}

Pitfalls and diagnostics#

  • Diagnostics: ww::dsl::collection_unknown_key (a derived collection sets a key the base lacks), collection_cycle, unknown_collection, bad_choice, slot_contract (a bound component lacks a requires= param, reported at the slot line), unknown_slot (@x with no collection in force or naming no slot).
  • Import diagnostics: import_cycle, import_too_deep, too_many_imports, unknown_export, import_conflict (a same-name material/hardware/joinery that differs, or reads a param so means something different in each file). Diagnostics inside an imported file name that file and count from its own line 1 (lib/bad.kdl:7:15).
  • Limits (documented, not defects): collections are local to the file (not importable); coll_* params are not visible inside imported components; computed values cannot be exported (only assemblies and components); ww author edits (join, marks, joinery) refuse targets inside an imported file.
  • Imported parts appear with mangled names (DrawerBox.DrawerBoxEnd~Wide.Bottom.Front).
  • style here is the project/collection look; the style rules a finish or style file applies are a separate family (see INDEX.md).

See also#

  • docs/KDL_AUTHORING.md §14 (import), §16 (collections); ADR-0020 (import), ADR-0021.
  • examples/kitchen_collections.kdl (a three-unit kitchen; the second collection is ten lines).
  • parts-and-assemblies.md (instance overrides), materials-and-hardware.md.

Names#

Every name this page declares, how the example library uses it, and the shortest real use.

import#

project-level node; node in 5 of 116 examples (8 uses).

Shortest real use, from drawer_stack.kdl:

import DrawerBox from="std:drawer" export=DrawerBox

from#

word-valued property; property in 7 of 116 examples (11 uses).

Shortest real use, from drawer_stack.kdl:

import DrawerBox from="std:drawer" export=DrawerBox

export#

word-valued property; property in 5 of 116 examples (10 uses).

Shortest real use, from drawer_stack.kdl:

import DrawerBox from="std:drawer" export=DrawerBox

collection#

project-level node, word-valued property; node in 1 of 116 examples (3 uses); property in 1 of 116 examples (1 uses).

Shortest real use, from kitchen_collections.kdl:

collection ShakerFaceFrame extends=UsBase style=traditional-shaker {
}

extends#

word-valued property; property in 1 of 116 examples (2 uses).

Shortest real use, from kitchen_collections.kdl:

collection ShakerFaceFrame extends=UsBase style=traditional-shaker {
}

choice#

project-level node; node in 1 of 116 examples (2 uses).

Shortest real use, from kitchen_collections.kdl:

choice construction=frameless

slots#

node in 1 of 116 examples (2 uses).

Shortest real use, from kitchen_collections.kdl:

slots {
    carcass CarcassPly
    door    Door_Slab
    front   WalnutPly
    pull    Knob_1_25
}

style#

word-valued property; property in 1 of 116 examples (2 uses).

Shortest real use, from kitchen_collections.kdl:

collection ShakerFaceFrame extends=UsBase style=traditional-shaker {
}

requires#

word-valued property; property in 1 of 116 examples (1 uses).

Shortest real use, from kitchen_collections.kdl:

door       component Door_Shaker requires="dw dh pull_x pull_y"

kind#

word-valued property; property in 4 of 116 examples (5 uses).

Shortest real use, from welsh_dresser.kdl:

travel kind=angle axis=z body=assembly pivot=Pin_Back

construction#

property; property in 1 of 116 examples (2 uses).

Shortest real use, from kitchen_collections.kdl:

choice construction=frameless

Settings

Region

A region picks sensible defaults; change any of these separately.

Units

In inches, type lengths the way you say them: 34 1/2, 3/4", 1'-2" or 12.7mm. A length that can't be read is flagged, never rounded to something else.

Paper
Date order
Clock