Hi,
Would it be possible to generate all ABP Suite Template files in 1 go, instead of editing and saving each by hand? For MVC-EFCore, there are more or less 300 of them. It would save us a lot of time if we could edit them externally.
Thanks, Paul
3 Answer(s)
-
0
- ABP Suite does not have a built-in “export/generate all template files at once” feature. Suite templates are shipped inside the
Volo.Abp.Commercial.SuiteTemplatespackage and you typically customize them one by one from the Template Editing UI. - If you want to edit templates externally (in bulk), the practical approach is:
- Open ABP Suite → Template Editing.
- For the templates you want to change, create customized copies (Suite marks them as customized).
- Edit those customized template contents by copy/pasting from your external editor (or keep the content in your editor and paste back when needed).
- When you upgrade ABP/Suite and a template changes upstream, Suite will show it as outdated, and you’ll need to reconcile your customization with the updated template.
No verified source is available for a “generate/export all templates in one go” capability in ABP Suite.
- https://abp.io/docs/latest/suite/editing-templates
- https://abp.io/docs/latest/studio/working-with-suite
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post) - ABP Suite does not have a built-in “export/generate all template files at once” feature. Suite templates are shipped inside the
-
0
Hi Paul,
Good news, bulk external editing is possible. The Template Editing UI is only one way in, but under the hood Suite stores each customized template as a plain UTF-8 text file on disk, so you can edit them in any external editor and Suite picks them up at generation time.
How it works:
- Customized templates live in
<your-solution-folder>/.suite/customized-templates/, one file per template (the file name is the template resource name, e.g.Server.Repository.EfCoreRepository.txt). - At generation time Suite uses that file if it exists, otherwise it falls back to the default template. So editing these files externally takes effect on the next generation, no need to open each one in the UI.
- The first line of each file is a metadata header
##<MD5>##. Suite always strips the first line before using the template, so you must keep that line intact and put your edits below it. The hash itself is only used to detect whether the default template changed after an upgrade.
To get all the templates onto disk in one go, you can extract them from the
Volo.Abp.Commercial.SuiteTemplates.dllthat ends up in your solution's build output (for a tiered app it's under the*.HttpApi.Hostproject'sbinfolder). Build the solution first so the DLL is there, then run this from your solution folder:param( [string]$Dll, [switch]$Force ) $prefix = "Volo.Abp.Commercial.SuiteTemplates.Templates." if (-not $Dll) { $Dll = Get-ChildItem -Recurse -Filter "Volo.Abp.Commercial.SuiteTemplates.dll" | Sort-Object LastWriteTime -Descending | Select-Object -First 1 -ExpandProperty FullName } if (-not $Dll -or -not (Test-Path $Dll)) { throw "SuiteTemplates.dll not found. Build the solution first, or pass -Dll <path>." } # Suite uses the legacy folder if it exists, otherwise .suite/customized-templates $legacy = Join-Path (Get-Location) "customized-suite-templates" $outDir = if (Test-Path $legacy) { $legacy } else { Join-Path (Get-Location) ".suite\customized-templates" } New-Item -ItemType Directory -Force -Path $outDir | Out-Null # Load by bytes so the DLL in bin is not locked $asm = [System.Reflection.Assembly]::Load([System.IO.File]::ReadAllBytes((Resolve-Path $Dll))) $md5 = [System.Security.Cryptography.MD5]::Create() $utf8 = New-Object System.Text.UTF8Encoding($false) Write-Host "DLL : $Dll" Write-Host "Output: $outDir" $written = 0; $skipped = 0 foreach ($name in $asm.GetManifestResourceNames()) { if (-not $name.StartsWith($prefix)) { continue } if (-not $name.EndsWith(".txt")) { continue } # text templates only $file = $name.Substring($prefix.Length) $path = Join-Path $outDir $file if ((Test-Path $path) -and -not $Force) { $skipped++; continue } $reader = New-Object System.IO.StreamReader($asm.GetManifestResourceStream($name)) $content = $reader.ReadToEnd(); $reader.Dispose() $hash = (($md5.ComputeHash([System.Text.Encoding]::ASCII.GetBytes($content)) | ForEach-Object { $_.ToString("X2") }) -join "") [System.IO.File]::WriteAllText($path, "##$hash##`r`n" + $content, $utf8) $written++ } Write-Host "Written: $written Skipped (already exist): $skipped"A couple of things worth knowing:
- The script writes the header line with CRLF. If your editor rewrites files to LF-only, the first-line stripping can misfire and produce empty output, so make sure the editor preserves the existing line endings (and keeps that first
##...##line). - It skips files that already exist unless you pass
-Force, so re-running it after an upgrade won't wipe your own edits. - Every file you keep in that folder shadows the default template for good. After an upgrade, only the ones whose default actually changed get flagged as outdated, but any file you leave there will keep overriding future template improvements. So I'd recommend keeping only the templates you actually customize and deleting the rest, rather than leaving all of them in place.
Thanks
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post) - Customized templates live in