diff --git a/src/views/components/TemplateBuilder.svelte b/src/views/components/TemplateBuilder.svelte
new file mode 100644
index 00000000..16e053e9
--- /dev/null
+++ b/src/views/components/TemplateBuilder.svelte
@@ -0,0 +1,30 @@
+
+
+
+
+
Fields to include in frontmatter
+ {#each $fields as field}
+
+
+
+ model.setField(field.name, { onFrontmatter: v.currentTarget.checked })}
+ />
+
+ {/each}
+
+
+
diff --git a/src/views/components/TemplateBuilder.ts b/src/views/components/TemplateBuilder.ts
new file mode 100644
index 00000000..adbd13b8
--- /dev/null
+++ b/src/views/components/TemplateBuilder.ts
@@ -0,0 +1,58 @@
+import { A, pipe } from "@std";
+import { FormDefinition } from "src/core/formDefinition";
+import { writable } from "svelte/store";
+
+// type FieldDefinition = FormDefinition["fields"][number];
+
+interface FieldOption {
+ name: string;
+ onFrontmatter: boolean;
+ onBody: boolean;
+ omit: false;
+}
+
+interface OmitedFieldOption {
+ name: string;
+ omit: true;
+ // field: FieldDefinition;
+}
+
+type Field = FieldOption | OmitedFieldOption;
+
+const Field = (name: string): FieldOption => ({
+ name,
+ onFrontmatter: false,
+ onBody: false,
+ omit: false,
+});
+
+export const makeModel = (formDefinition: FormDefinition) => {
+ const fields = writable(
+ formDefinition.fields.reduce((acc, { name }) => [...acc, Field(name)], [] as Field[]),
+ );
+
+ // function setField(name: string, newValues: Partial) {
+ // fields.update((f) => {
+ // const field = f[name] ?? { name, onFrontmatter: false, onBody: false };
+ // f[name] = { ...field, ...newValues };
+ // return f;
+ // });
+ // }
+
+ function setField(name: string, newValues: Partial) {
+ fields.update(($fields) =>
+ pipe(
+ $fields,
+ A.updateFirst(
+ (f) => f.name === name,
+ (f) => {
+ return { ...f, ...newValues } as Field;
+ },
+ ),
+ ),
+ );
+ }
+ return { fields, setField };
+};
+
+export type TemplateBuilderModel = ReturnType;