From e5836f6b6f52a040562061339ff467a65a3073e3 Mon Sep 17 00:00:00 2001 From: maliming Date: Sun, 19 Jul 2026 12:10:23 +0800 Subject: [PATCH] Add standalone Blogging module documentation --- docs/en/modules/blogging.md | 172 ++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 docs/en/modules/blogging.md diff --git a/docs/en/modules/blogging.md b/docs/en/modules/blogging.md new file mode 100644 index 0000000000..39492a696c --- /dev/null +++ b/docs/en/modules/blogging.md @@ -0,0 +1,172 @@ +```json +//[doc-seo] +{ + "Description": "Learn how to install and configure the standalone ABP Blogging module, including its MVC UI, routes, permissions, files and database providers." +} +``` + +# Blogging Module + +The Blogging module is a free and open-source application module for creating one or more blogs. It provides an MVC / Razor Pages user interface, application services, HTTP APIs and Entity Framework Core and MongoDB integrations for blogs, posts, tags, comments and member profiles. + +> This page documents the standalone `Volo.Blogging` module. [CMS Kit: Blogging](cms-kit/blogging.md) is a different feature family with different entities, configuration and UI. + +## How to Install + +Use the ABP CLI to add the module to an existing solution: + +```bash +abp add-module Volo.Blogging +``` + +The command adds the module packages and dependencies to the compatible projects in your solution. Apply the generated database migration after adding the module. + +### The Source Code + +The source code of this module is available in the [ABP repository](https://github.com/abpframework/abp/tree/dev/modules/blogging). It is licensed with [MIT](https://choosealicense.com/licenses/mit/), so you can use and customize it. + +## User Interface and Content Workflow + +The module provides two MVC / Razor Pages surfaces: + +* The public site lists blogs, posts and popular tags, renders post content as Markdown, displays member profiles and allows authenticated users to add comments. +* The administration page manages blogs. Post creation and editing are available from the public blog UI to users with the corresponding permissions. + +When the application has one blog, the blog index redirects directly to that blog. With multiple blogs, the index displays the available blogs. + +Creating a post makes it available to the public list and reading APIs immediately. The standalone module does not add a draft, review or scheduled-publication state. If a post URL is already used in the same blog, the application service appends a generated suffix and returns the resulting URL. + +Tags are entered with a post. The application service normalizes tag names to lowercase, removes duplicates and maintains their usage counts. + +### Member Profiles + +The module keeps a local `BlogUser` record for post and comment authors. It uses ABP's [user lookup and synchronization](identity/user-synchronization.md) infrastructure to obtain Identity user data. The public member page lists an active user's posts and profile information; the current user can edit the Blogging-specific fields on their own profile. + +## Permissions + +The administration menu is visible with the `Blogging.Blog.Management` permission. Blog operations use separate child permissions: + +* `Blogging.Blog.Create` +* `Blogging.Blog.Update` +* `Blogging.Blog.Delete` +* `Blogging.Blog.ClearCache` + +Post creation, update and deletion require `Blogging.Post.Create`, `Blogging.Post.Update` and `Blogging.Post.Delete`, respectively. + +Any authenticated user can create a comment. A comment can be updated or deleted by its creator or by a user with `Blogging.Comment.Update` or `Blogging.Comment.Delete`. + +See the [Authorization](../framework/fundamentals/authorization/index.md) documentation to learn how to grant permissions to roles and users. + +## Routing + +`BloggingUrlOptions.RoutePrefix` controls the public URL prefix. Its default value produces URLs under `/blog/`. The following example moves the public blog under `/articles/` and enables single-blog mode for the blog whose short name is `engineering`: + +```csharp +Configure(options => +{ + options.RoutePrefix = "articles"; + options.SingleBlogMode.Enabled = true; + options.SingleBlogMode.BlogName = "engineering"; +}); +``` + +Single-blog mode removes the blog short-name segment from post URLs. If the application contains multiple blogs, set `SingleBlogMode.BlogName` to the short name of the blog to expose. If it contains exactly one blog, the module can select it without setting `BlogName`. + +Set `RoutePrefix` to an empty string to serve the blog from `/`. In this mode the route constraint uses `IgnoredPaths` to avoid capturing other top-level application routes. The module already adds its framework endpoints, bundle folder and member route; add application-specific top-level paths when needed: + +```csharp +Configure(options => +{ + options.RoutePrefix = ""; + options.IgnoredPaths.Add("health"); +}); +``` + +## Post Images + +Post images are saved through the [BLOB Storing](../framework/infrastructure/blob-storing) system in the `blogging-files` container. Configure a BLOB provider for this container as you would for any other typed container. + +The upload service accepts JPEG, PNG, GIF and BMP images. The maximum file size is 5 MiB by default. `BloggingWebConsts.FileUploading.MaxFileSize` is a process-wide static value, so set it once during application startup, before the application begins accepting uploads: + +```csharp +BloggingWebConsts.FileUploading.MaxFileSize = 10 * 1024 * 1024; +``` + +## Social Media Metadata + +The post page emits Twitter card metadata. Configure the site handle with `BloggingTwitterOptions`: + +```csharp +Configure(options => +{ + options.Site = "@myblog"; +}); +``` + +## Post List Cache + +The time-ordered post list is cached per blog for one hour. Creating, updating or deleting posts through `IPostAppService` invalidates that cache within the current unit of work. The blog administration page also provides a **Clear Cache** action to users with the `Blogging.Blog.ClearCache` permission. + +If custom code changes posts directly through `IPostRepository`, publish the module's `PostChangedEvent` with the affected blog ID. The built-in event handler then removes that blog's cached list as part of the current unit of work. + +## Internals + +### Domain Layer + +The main aggregates are: + +* `Blog`: A named blog identified in public URLs by its short name. +* `Post`: Markdown content, cover image, URL, tags and read count for a blog. +* `Comment`: A comment or direct reply attached to a post. +* `Tag`: A normalized tag and its usage count within a blog. +* `BlogUser`: The module-local representation of an Identity user and Blogging profile. + +### Application Layer + +The public application-service contracts are `IBlogAppService`, `IPostAppService`, `ICommentAppService`, `ITagAppService` and `IFileAppService`. `IBlogManagementAppService` provides blog administration operations. + +The HTTP API uses the `Blogging` remote-service name for public operations and `BloggingAdmin` for administration operations. Add `BloggingHttpApiClientModule` or `BloggingAdminHttpApiClientModule` to a client application when these services run remotely. + +### Database Providers + +#### Common + +The module uses `Blogging` as its connection string name and falls back to `Default` when that connection is not configured. See the [Connection Strings](../framework/fundamentals/connection-strings.md) documentation. + +Tables and collections use the `Blg` prefix by default. Set `AbpBloggingDbProperties.DbTablePrefix` and, for providers that support schemas, `AbpBloggingDbProperties.DbSchema` before the database model is created: + +```csharp +AbpBloggingDbProperties.DbTablePrefix = "MyBlog"; +AbpBloggingDbProperties.DbSchema = "blogging"; +``` + +#### Entity Framework Core + +The Entity Framework Core provider uses these tables: + +* `BlgUsers` +* `BlgBlogs` +* `BlgPosts` +* `BlgComments` +* `BlgTags` +* `BlgPostTags` + +Call `ConfigureBlogging()` from your migration DbContext when integrating the module manually. + +#### MongoDB + +The MongoDB provider uses these collections: + +* `BlgUsers` +* `BlgBlogs` +* `BlgPosts` +* `BlgComments` +* `BlgTags` + +Post-tag links are stored with the post documents, so MongoDB does not use a separate `BlgPostTags` collection. + +## See Also + +* [CMS Kit: Blogging](cms-kit/blogging.md) +* [BLOB Storing](../framework/infrastructure/blob-storing) +* [User Lookup and Synchronization](identity/user-synchronization.md)