language-translator
An Obsidian plugin to translate selected text in the desired language
Blog system of https://edi.wang, runs on Microsoft Azure
Moonglade is a personal blogging platform built for developers, optimized for seamless deployment on Microsoft Azure. It features essential blogging tools: posts, comments, categories, tags, archives, and pages.
Moonglade provides a self-hosted blog with a public reading experience and an authenticated admin portal. The core workflow is authoring posts and pages, organizing them with categories and tags, publishing immediately or on a schedule, and exposing the published content through web pages, feeds, sitemap, Webmention, and search-engine notification protocols.
Key business areas include:
The main solution file is src/Moonglade.slnx.
| Path | Purpose |
|---|---|
src/Moonglade.Web |
ASP.NET Core web host, Razor Pages, API controllers, endpoint mapping, filters, middleware wiring, and static assets. |
src/Moonglade.Features |
Blog feature commands and queries for posts, pages, comments, categories, tags, assets, dashboard data, and recycle bin behavior. |
src/Moonglade.Data |
EF Core BlogDbContext, entities, DTOs, mappings, and import/export primitives. |
src/Moonglade.Data.SqlServer, src/Moonglade.Data.PostgreSql |
SQL Server and PostgreSQL provider registration and provider-specific EF Core behavior. |
src/Moonglade.Configuration |
Persisted blog settings models, defaults, loading, and update commands. |
src/Moonglade.Auth |
Local account and Microsoft Entra ID authentication support. |
src/Moonglade.BackgroundServices |
Scheduled publishing, update checks, and fire-and-forget background work. |
src/Moonglade.* |
Supporting projects for image storage, email, IndexNow, moderation, Webmention, syndication, themes, widgets, setup, utilities, and middleware. |
src/Tests/Moonglade.*.Tests |
xUnit test projects aligned with the production projects. |
Deployment, Dockerfile, compose.yaml |
Azure and Docker deployment assets. |
This blogging system must not be used to serve users in mainland China or to publish content prohibited by Chinese law or any applicable regulations.
master.Get started in 10 minutes with minimal Azure resources using our automated deployment script.
For local testing or small-scale use, deploy Moonglade using Docker:
docker compose up -d
| Tools | Alternatives |
|---|---|
| Visual Studio 2026 | VS Code + .NET 10.0 SDK |
| SQL Server 2025 | LocalDB or PostgreSQL |
Tip: SQL Server Express (free) is sufficient for most production uses.
| Database | Example Connection String (appsettings.json > ConnectionStrings > MoongladeDatabase) |
|---|---|
| SQL Server | Server=(local);Database=moonglade;Trusted_Connection=True; |
| PostgreSQL | User ID=***;Password=***;Host=localhost;Port=5432;Database=moonglade;Pooling=true; |
Change ConnectionStrings:DatabaseProvider in appsettings.json to match your database type.
SqlServerPostgreSqlThe commands below are derived from the project files and launch settings:
dotnet restore src/Moonglade.Web/Moonglade.Web.csproj dotnet build src/Moonglade.Web/Moonglade.Web.csproj dotnet run --project src/Moonglade.Web/Moonglade.Web.csproj
Focused tests can be run from the matching test project, for example:
dotnet test src/Tests/Moonglade.Features.Tests/Moonglade.Features.Tests.csproj dotnet test src/Tests/Moonglade.Web.Tests/Moonglade.Web.Tests.csproj
./src/Moonglade.slnx or src/Moonglade.Web/Moonglade.Web.csprojhttps://localhost:10210https://localhost:10210/admin
adminadmin123Most settings are managed in
appsettings.json. For blog settings, use the/admin/settingsUI.
/admin/account)Authentication:Totp:Required=false; this bypass is ignored outside the Development environment./admin/account to reset it; the reset signs out the administrator and starts TOTP setup on the next sign-in."Authentication": {
"Totp": {
"Issuer": "Moonglade",
"Required": true
}
}
Built-in comment submissions are rate limited by the combination of client IP address and post ID. Configure the CommentRateLimit section in appsettings.json:
"CommentRateLimit": {
"Enabled": true,
"PermitLimit": 5,
"WindowMinutes": 10
}
PermitLimit is the number of comment submissions allowed for the same IP and post during each fixed window. WindowMinutes controls the fixed window length. Set Enabled to false to disable this host-level safeguard.
Built-in comment submissions also use a hidden honeypot field and form elapsed-time checks. Configure the CommentSubmissionGuard section in appsettings.json:
"CommentSubmissionGuard": {
"Enabled": true,
"HoneypotEnabled": true,
"MinimumElapsedSeconds": 3,
"MaxFormAgeMinutes": 240
}
MinimumElapsedSeconds rejects submissions that arrive too quickly after the comment form is rendered. MaxFormAgeMinutes rejects stale form timestamps; set it to 0 to disable the max-age check. Set Enabled to false to disable this guard.
Configure the ImageStorage section in appsettings.json to choose where blog images are stored.
Create an Azure Blob Storage container with appropriate permissions:
{
"Provider": "azurestorage",
"AzureStorageSettings": {
"ConnectionString": "YOUR_CONNECTION_STRING",
"ContainerName": "YOUR_CONTAINER_NAME"
}
}
Windows:
{
"Provider": "filesystem",
"FileSystemPath": "C:\\UploadedImages"
}
Linux:
{
"Provider": "filesystem",
"FileSystemPath": "/app/images"
}
When using the file system, ensure the path exists and has appropriate permissions. If the path does not exist, Moonglade will attempt to create it.
Leave the FileSystemPath empty to use the default path (~/home/moonglade/images on Linux or %UserProfile%\moonglade\images on Windows).
Moonglade comment moderation runs locally and does not call a remote moderation API. Configure the word filter and keyword list from /admin/settings/comment.
Moonglade always emits X-Content-Type-Options: nosniff. To enable a custom Content Security Policy response header, set EnableCSP to true and provide the policy in CSPValue:
{
"EnableCSP": true,
"CSPValue": "default-src 'self'; img-src 'self' https: data:"
}
For notifications on new comments, replies and webmentions, use Moonglade.Email Azure Function:
"Email": {
"ApiEndpoint": "",
"ApiKey": ""
}
Enable notifications in the admin portal.
| Name | Feature | Status | Endpoint |
|---|---|---|---|
| RSS | Subscription | Supported | /rss |
| Atom | Subscription | Supported | /atom |
| OPML | Subscription | Supported | /opml |
| Open Search | Search | Supported | /opensearch |
| FOAF | Social | Supported | /foaf.xml |
| Webmention | Social | Supported | /webmention |
| Reader View | Reader Mode | Supported | N/A |
| u-card | SEO | Supported | N/A |
| IndexNow | SEO | Supported | N/A |
| Dublin Core | SEO | Basic | N/A |
| RSD | Discovery | Deprecated | N/A |
| MetaWeblog | Blogging | Deprecated | N/A |
| Pingback | Social | Deprecated | N/A |
To ensure your Moonglade instance is running, you can use the health check endpoint:
GET /health
This endpoint returns a simple JSON response indicating the status of your Moonglade instance.
more like this
An Obsidian plugin to translate selected text in the desired language
Birdy is a nicely designed wild bird feeder that takes photos, identifies and classifies birds. - based on Raspberry Pi…
search projects, people, and tags