Import
Import
A drop-in module for barakoCMS that turns spreadsheet
uploads into content. It parses .xlsx/CSV with the zero-dependency
Talaan reader, then bulk-creates content items through the
CMS's own validation, permissions, and event-sourcing.
Enable it
dotnet add package BarakoCMS.Import
builder.Services.AddBarakoCMS(builder.Configuration);
var app = builder.Build();
app.UseBarakoCMS();
The package reference plus a restart is the install. AddBarakoCMS finds every module in the
application's dependency context, and BarakoCMS:Modules:Enabled decides which of them run
(BarakoCMS__Modules__Enabled=Import). Unset, every referenced module runs and the API logs
one warning saying so. To name it by hand instead, put
modules.Add(new BarakoCMS.Import.ImportModule())
in the AddBarakoCMS callback; discovery skips a type the host already added. See MODULES.md in
the repository.
No services or schema to configure — the module only contributes endpoints.
The two-step flow
Analyze —
POST /api/import/analyze(multipart file upload). Returns a typed preview grid (rows × columns, each cell taggedText/Number/Date/Boolean) plus a suggested header row. Nothing is stored. A UI uses this to let the user map columns to content fields.Create —
POST /api/import/content(JSON):{ "contentType": "member", "records": [ { "FirstName": "Dindo", "LastName": "Abantao", "MemberNo": "3322657" } ], "continueOnError": false }Every record is validated against the content type first. With
continueOnError: false(default), a single invalid row aborts the whole import and returns per-row errors — nothing is written. Otherwise valid rows are created and failures reported. All creates commit in one transaction.Each record goes through the same write path as
POST /api/contents: a field the caller may not see is dropped, the record is validated, and the type's lifecycle hooks run, each row written before the next is checked inside one transaction, so a hook sees the rows before it. The rows it writes are held until the import commits, so run a large one outside busy hours: a post that needs the same row, such as the journal entry number sequence, waits and may need a retry. One request creates at most 5,000 records (Import:MaxRecords); past that it answers 400 and writes nothing.A cell arrives as text. For a
moneyfield that declares a currency, plain decimal text (an optional sign, digits, at most one point) is stored as a number. Anything else in that column, such as1,250.00, or an amount with more decimal places than the currency has, is refused for that row naming the field. A money field with no currency stores the cell as it always did.
Why split analyze from create
The mapping and any cleanup (skipping title/section rows, formatting numbers, choosing which columns matter) happen in your UI between the two calls. The module stays generic: it parses, and it creates validated content — it does not hard-code any particular spreadsheet's shape.
Authorization
analyze requires the analyze_spreadsheets capability. content is gated by the target content type's own
create permission (via the CMS permission resolver) — so a role that can create member content
can import members, and nothing else.
Requires
barakoCMS, BarakoCMS.Abstractions and Talaan, at the versions NuGet lists as this package's dependencies. The first two are never older than 4.3.0, the release that added BarakoCMS.Abstractions. Targets .NET 10.
License
MIT © BaryoDev
If barakoCMS is useful to you, a star on the repository helps other people find it.