Maintainers
Pricing
Enterprise
More
More
Documentation
Try Live
Rankings
Install
Blog
Docs7
Ask
New
Add Docs
Halo
https://docs.halo.run/
Admin
Halo is a powerful and easy-to-use open-source website building tool.
Tokens:
77,911
Snippets:
1,128
Trust Score:
10
Update:
3 months ago
Context
Chat
Benchmark
52.57
Latest
Show doc for...
Code
Info
Show Results
Tokens:
Raw
Copy
Link
Tokens:
Raw
Copy
Link
### Quick Start with Docker Source: https://docs.halo.run/next Use this command to quickly start an experience environment for Halo using Docker. Ensure you have Docker installed on your system. ```bash docker run -d --name halo -p 8090:8090 -v ~/.halo2:/root/.halo2 halohub/halo:2.25 ``` -------------------------------- ### Quick Start with Docker Source: https://docs.halo.run/2.22 Use this command to quickly start a Halo experience environment if you have Docker installed. This is for trial purposes; refer to the detailed deployment documentation for production. ```bash docker run -d --name halo -p 8090:8090 -v ~/.halo2:/root/.halo2 halohub/halo:2.22 ``` -------------------------------- ### Execute Installation Script Source: https://docs.halo.run/2.20/getting-started/install/offline Navigates to the installation directory and executes the installation script. Follow the on-screen prompts for configuration. ```bash # Navigate to the installation package directory (halo-offline-installer-v2.17.0-amd64 is an example, replace with your actual directory name) cd halo-offline-installer-v2.17.0-amd64 # Run the installation script /bin/bash install.sh ``` -------------------------------- ### Run UI Service with pnpm Source: https://docs.halo.run/2.23/developer-guide/core/run Navigate to the UI directory, install dependencies, build packages, and start the UI development server using pnpm. This is necessary for the development environment. ```bash cd path/to/halo/ui pnpm install pnpm build:packages pnpm dev ``` -------------------------------- ### Start Halo Server for Testing Source: https://docs.halo.run/2.20/developer-guide/plugin/basics/devtools Use the haloServer task to start a Halo instance for testing your plugin. This task requires Docker to be installed and running. ```bash ./gradlew haloServer ``` -------------------------------- ### Start Halo Service Source: https://docs.halo.run/2.22/getting-started/install/jar-file Start the Halo service using systemctl. ```bash systemctl start halo ``` -------------------------------- ### Install API Client and Axios Source: https://docs.halo.run/2.24/developer-guide/restful-api/api-client Install the @halo-dev/api-client and axios packages using pnpm. ```bash pnpm install @halo-dev/api-client axios ``` -------------------------------- ### Example API Query with Selectors and Sorting Source: https://docs.halo.run/next/developer-guide/plugin/api-reference/server/extension Illustrates a GET request to list custom model objects, applying pagination, sorting, label selectors, and field selectors for precise data retrieval. ```http GET /apis/my-plugin.halo.run/v1alpha1/persons?page=1&size=10&sort=name,desc&labelSelector=name=halo&fieldSelector=spec.slug=halo ``` -------------------------------- ### Start Halo Service after Upgrade Source: https://docs.halo.run/2.22/getting-started/install/jar-file Start the Halo service using the service command after updating the JAR file. ```bash service halo start ``` -------------------------------- ### Route Definition Example Source: https://docs.halo.run/2.22/developer-guide/plugin/api-reference/ui/route This example demonstrates how to define routes for both the Console and UC personal center within a Halo plugin. It includes configuration for parent routes, path, name, component, and meta information such as permissions, menu display name, group, icon, and priority. ```APIDOC ## Route Definition Console and UC personal center routes are defined similarly to Vue Router. Halo provides two distinct entry points: * `routes`: For Console routes. * `ucRoutes`: For UC personal center routes. ### Example ```javascript import HomeView from "./views/HomeView.vue" import { IconComputer } from "@halo-dev/components"; export default definePlugin({ routes: [ { parentName: "Root", route: { path: "/foo", name: "Foo", component: HomeView, meta: { permissions: [""], menu: { name: "Foo", group: "content", icon: markRaw(IconComputer), priority: 40 }, }, }, }, ], ucRoutes: [ { parentName: "Root", route: { path: "/uc-foo", name: "FooUC", component: HomeView, meta: { permissions: [""], menu: { name: "FooUC", group: "content", icon: markRaw(IconComputer), priority: 40 }, }, }, }, ] }); ``` ### Type Definitions `RouteRecordRaw` is from Vue Router. Halo extends it with a `meta` property of type `RouteMeta`. ```typescript interface RouteMeta { title?: string; // Browser title searchable?: boolean; // Whether it can be searched in Console's global search permissions?: string[]; // UI permissions menu?: { name: string; // Menu name group?: CoreMenuGroupId; // Built-in menu group ID or custom group name icon?: Component; // Menu icon (Vue component) priority: number; // Menu item sorting (lower number is higher priority) mobile?: boolean; // Whether to display on mobile }; } type CoreMenuGroupId = "dashboard" | "content" | "interface" | "system" | "tool"; export interface RouteRecordAppend { parentName: RouteRecordName; route: RouteRecordRaw; } ``` `parentName` specifies the parent route. Set to `"Root"` for top-level routes. If `parentName` is set and `meta.menu` is configured, the route becomes a submenu item. Supported `parentName` values include: * **Console**: `AttachmentsRoot`, `CommentsRoot`, `SinglePagesRoot`, `PostsRoot`, `MenusRoot`, `ThemeRoot`, `OverviewRoot`, `BackupRoot`, `PluginsRoot`, `SettingsRoot`, `UsersRoot`, `ToolsRoot` * **UC**: `PostsRoot`, `NotificationsRoot` ``` -------------------------------- ### Enable Halo Service on System Startup Source: https://docs.halo.run/next/getting-started/install/jar-file Configure the Halo service to start automatically when the system boots up. ```bash systemctl enable halo ``` -------------------------------- ### Deployed Application Directory Structure Source: https://docs.halo.run/2.20/getting-started/install/offline Shows the file structure after a successful installation, assuming the default installation location of /opt/halo. ```bash [root@meter-prototype halo]# tree . ├── data # Data storage directory │ ├── db # Database data storage directory, mounted to the database container │ └── halo # Halo data storage directory, mounted to the Halo container │ ├── indices │ ├── keys │ ├── logs │ ├── plugins │ └── themes ├── docker-compose.yaml # Docker Compose file ├── .env # Environment variable declaration file for Docker Compose ├── install.log # Installation script log file ├── LICENSE └── README.md ``` -------------------------------- ### Halo Application Configuration Example Source: https://docs.halo.run/getting-started/install/config An example of an application.yaml file used for configuring Halo, typically placed in the directory specified by --spring.config.additional-location. ```yaml spring: r2dbc: url: r2dbc:h2:file:///${halo.work-dir}/db/halo-next?MODE=MySQL&DB_CLOSE_ON_EXIT=FALSE username: admin password: 123456 sql: init: mode: always platform: h2 ``` -------------------------------- ### Enable Halo Service on Boot Source: https://docs.halo.run/2.22/getting-started/install/jar-file Configure the Halo service to start automatically when the system boots up. ```bash systemctl enable halo ``` -------------------------------- ### Deploy Halo with Existing External Database Source: https://docs.halo.run/2.23/getting-started/install/helm Configure Halo to use an existing external database (MySQL in this example) by disabling automatic database installation and providing connection details. ```bash helm install halo halo/halo \ --set mysql.enabled=false \ --set postgresql.enabled=false \ --set externalDatabase.platform=mysql \ --set externalDatabase.host=mysql \ --set externalDatabase.port=3306 \ --set externalDatabase.user=halo \ --set externalDatabase.password=0P0gJrCyzz \ --set externalDatabase.database=halo ``` -------------------------------- ### Docker Version Information Source: https://docs.halo.run/next/developer-guide/plugin/basics/devtools This example shows how to check your Docker version and API version, which might be needed for configuring the `docker.apiVersion` in the `halo {}` block. ```bash ➤ docker version Client: Version: 24.0.7 API version: 1.43 ``` -------------------------------- ### Example Custom Page Template Configuration Source: https://docs.halo.run/2.23/developer-guide/theme/template-variables/page An example of how to configure a custom page template named 'About Company' in `theme.yaml`. ```yaml customTemplates: page: - name: 关于公司 description: 用于展示公司的一些信息 screenshot: file: page_about.html ``` -------------------------------- ### Table Extension Slash Command Example Source: https://docs.halo.run/2.24/developer-guide/plugin/extension-points/ui/default-editor-extension-create An example of implementing `getCommandMenuItems` in the `Table` extension to add a 'table' command. This command inserts a 3x3 table with a header row. ```javascript addOptions() { return { ...this.parent?.(), getCommandMenuItems() { return { priority: 120, icon: markRaw(MdiTable), title: "editor.extensions.commands_menu.table", keywords: ["table", "biaoge"], command: ({ editor, range }: { editor: Editor; range: Range }) => { editor .chain() .focus() .deleteRange(range) .insertTable({ rows: 3, cols: 3, withHeaderRow: true }) .run(); }, }; }, } } ``` -------------------------------- ### Start Halo Service with Docker Compose Source: https://docs.halo.run/2.23/getting-started/install/docker-compose Command to start Halo services in detached mode using Docker Compose. ```bash docker compose up -d ``` -------------------------------- ### PostCommentSubject Implementation Example Source: https://docs.halo.run/next/developer-guide/plugin/extension-points/server/comment-subject An example implementation of the CommentSubject extension point for 'Post' objects. It fetches post details and formats them for display. ```java public class PostCommentSubject implements CommentSubject<Post> { private final ReactiveExtensionClient client; private final ExternalLinkProcessor externalLinkProcessor; @Override public Mono<Post> get(String name) { return client.fetch(Post.class, name); } @Override public Mono<SubjectDisplay> getSubjectDisplay(String name) { return get(name) .map(post -> { var url = externalLinkProcessor .processLink(post.getStatusOrDefault().getPermalink()); return new SubjectDisplay(post.getSpec().getTitle(), url, "文章"); }); } @Override public boolean supports(Ref ref) { Assert.notNull(ref, "Subject ref must not be null."); GroupVersionKind groupVersionKind = new GroupVersionKind(ref.getGroup(), ref.getVersion(), ref.getKind()); return GroupVersionKind.fromExtension(Post.class).equals(groupVersionKind); } } ``` -------------------------------- ### Offline Installer Package Directory Structure Source: https://docs.halo.run/2.20/getting-started/install/offline Overview of the files and directories included in the offline installation package. ```bash [root@localhost halo-offline-installer-v2.17.0-amd64]# tree . ├── docker # Files for offline Docker installation │ ├── bin │ │ ├── containerd │ │ ├── containerd-shim-runc-v2 │ │ ├── ctr │ │ ├── docker │ │ ├── docker-compose │ │ ├── dockerd │ │ ├── docker-init │ │ ├── docker-proxy │ │ └── runc │ └── service │ └── docker.service ├── docker-compose.yaml # Docker Compose file for Halo and database services ├── .env # Environment variable declaration file for Docker Compose ├── images # Container image files for Halo and databases │ ├── halo.tar.gz │ ├── mysql.tar.gz │ └── postgres.tar.gz ├── install.sh # Installation script ├── LICENSE └── README.md ``` -------------------------------- ### Example Implementation: PostCommentSubject Source: https://docs.halo.run/next/developer-guide/plugin/extension-points/server/comment-subject An example implementation of the `CommentSubject` extension point for handling comments related to 'Post' entities. ```APIDOC ## Class: PostCommentSubject ### Description An example implementation of the `CommentSubject` extension point that handles comments associated with `Post` entities. It retrieves post details, formats display information, and checks if the reference is for a `Post`. ### Implements `CommentSubject<Post>` ### Fields * `client` (ReactiveExtensionClient) - Client for fetching extension resources. * `externalLinkProcessor` (ExternalLinkProcessor) - Processor for handling external links. ### Methods * **`Mono<Post> get(String name)`** * Description: Fetches a `Post` object by its name using the `client`. * Parameters: * `name` (String) - The name of the post. * Returns: `Mono<Post>` - A Mono emitting the `Post` object. * **`Mono<SubjectDisplay> getSubjectDisplay(String name)`** * Description: Generates the `SubjectDisplay` information for a `Post`. * Parameters: * `name` (String) - The name of the post. * Returns: `Mono<SubjectDisplay>` - A Mono emitting the `SubjectDisplay` object containing the post's title, permalink URL, and kind name ('文章'). * **`boolean supports(Ref ref)`** * Description: Checks if the given `Ref` is for a `Post` entity. * Parameters: * `ref` (Ref) - The reference object to check. * Returns: `boolean` - `true` if the `Ref` is for a `Post`, `false` otherwise. ``` -------------------------------- ### Halo Server Startup Success Log Source: https://docs.halo.run/2.20/developer-guide/plugin/basics/devtools This log indicates that the Halo server has started successfully and provides access URLs and credentials. ```text ======================================================================= > Halo 启动成功! 访问地址:http://localhost:8090/console?language=zh-CN 用户名:admin 密码:admin API 文档:http://localhost:8090/swagger-ui.html 插件开发文档:https://docs.halo.run/developer-guide/plugin/introduction ======================================================================= ``` -------------------------------- ### Reload Systemd and Start Halo Service Source: https://docs.halo.run/2.22/getting-started/install/podman Reloads the systemd daemon to recognize the new Quadlet file and starts the Halo container service. ```bash systemctl daemon-reload systemctl start halo ``` -------------------------------- ### Basic Reconciler Implementation Source: https://docs.halo.run/2.24/developer-guide/plugin/api-reference/server/reconciler A simple implementation of the Reconciler interface, defining the `reconcile` and `setupWith` methods. This serves as a starting point for custom resource reconciliation. ```java import io.halo.app.extension.Extension; import io.halo.app.extension.Reconciler; import io.halo.app.extension.Reconciler.Request; import io.halo.app.extension.Result; import io.halo.app.extension.controller.Controller; import io.halo.app.extension.controller.ControllerBuilder; import org.springframework.stereotype.Component; @Component public class PostReconciler implements Reconciler<Reconciler.Request> { @Override public Result reconcile(Request request) { return Result.doNotRetry(); } @Override public Controller setupWith(ControllerBuilder builder) { return builder .extension(new Post()) .build(); } } ``` -------------------------------- ### Control Sync Scope with syncAllListOptions Source: https://docs.halo.run/2.22/developer-guide/plugin/api-reference/server/reconciler Configure the scope of objects synchronized at controller startup using syncAllListOptions and syncAllOnStart. This example synchronizes only posts created by a specific user. ```java import org.springframework.stereotype.Component; import io.halo.app.controller.Controller; import io.halo.app.controller.ControllerBuilder; import io.halo.app.controller.Reconciler; import io.halo.app.extension.Extension; import io.halo.app.extension.ExtensionMatcher; import io.halo.app.model.ListOptions; import static run.halo.app.extension.index.query.Queries.equal; @Component public class PostReconciler implements Reconciler<Reconciler.Request> { @Override public Result reconcile(Request request) { return Result.doNotRetry(); } @Override public Controller setupWith(ControllerBuilder builder) { return builder .extension(new Post()) .syncAllListOptions(ListOptions.builder() .fieldQuery(equal("spec.owner", "guqing") .build() ) .syncAllOnStart(true) .build(); } } ``` -------------------------------- ### Example: Download Attachment Operation Source: https://docs.halo.run/2.22/developer-guide/plugin/extension-points/ui/attachment-list-item-operation-create Implements a 'Download' operation that allows users to download an attachment to their local machine. It checks for a permalink and triggers a file download. ```typescript import { definePlugin, type OperationItem } from "@halo-dev/ui-shared"; import { Toast, VDropdownItem } from "@halo-dev/components"; import { markRaw, type Ref } from "vue"; import type { Attachment } from "@halo-dev/api-client"; export default definePlugin({ extensionPoints: { "attachment:list-item:operation:create": ( attachment: Ref<Attachment> ): OperationItem<Attachment>[] | Promise<OperationItem<Attachment>[]> => { return [ { priority: 10, component: markRaw(VDropdownItem), props: {}, action: (item?: Attachment) => { if (!item?.status?.permalink) { Toast.error("该附件没有下载地址"); return; } const a = document.createElement("a"); a.href = item.status.permalink; a.download = item?.spec.displayName || item.metadata.name; a.click(); }, label: "下载", hidden: false, permissions: [], children: [], }, ]; }, }, }); ``` -------------------------------- ### Deploy Halo with Ingress Enabled Source: https://docs.halo.run/2.23/getting-started/install/helm Install Halo and enable Ingress to expose the application outside the Kubernetes cluster. Specify the hostname for accessing your Halo site. ```bash helm install halo halo/halo --set ingress.enabled=true --set ingress.hostname=demo.halo.run ``` -------------------------------- ### Upgrade Halo Application to Enable Ingress Source: https://docs.halo.run/2.23/getting-started/install/helm For an already installed Halo application, use this command to update its configuration and enable Ingress, specifying the desired hostname. ```bash helm upgrade halo halo/halo --set ingress.enabled=true --set ingress.hostname=demo.halo.run ``` -------------------------------- ### Extract Offline Installation Package Source: https://docs.halo.run/2.20/getting-started/install/offline Extracts the downloaded offline installer package. Replace the example filename with your actual package name. ```bash cd /tmp # Extract the installation package (halo-offline-installer-v2.17.0-amd64.tar.gz is an example, replace with your actual package name) tar zxvf halo-offline-installer-v2.17.0-amd64.tar.gz ``` -------------------------------- ### Person Endpoint Example Source: https://docs.halo.run/2.24/developer-guide/plugin/api-reference/server/extension An example of defining a custom GET endpoint for listing persons using SpringdocRouteBuilder. This demonstrates how to set metadata like operationId, description, and tag for API documentation. ```APIDOC ## GET /persons ### Description List all persons. ### Method GET ### Endpoint /persons ### Parameters #### Query Parameters - **param1** (type) - Required/Optional - Description ### Request Example ```json { "example": "request body" } ``` ### Response #### Success Response (200) - **field1** (type) - Description #### Response Example ```json { "example": "response body" } ``` ``` -------------------------------- ### Quick Deploy Halo with Default Settings Source: https://docs.halo.run/2.23/getting-started/install/helm Install Halo using default parameters. This command deploys Halo with an automatically provisioned PostgreSQL database and persistent storage for data. ```bash helm install halo halo/halo ``` -------------------------------- ### Create systemd Service File Source: https://docs.halo.run/2.22/getting-started/install/jar-file Create and open the systemd service file for Halo using vim. ```bash vim /etc/systemd/system/halo.service ``` -------------------------------- ### Create Podman Quadlet Configuration Directory Source: https://docs.halo.run/2.22/getting-started/install/podman Creates the necessary directories for Podman Quadlet configuration files. ```bash mkdir -p /opt/podman-data/halo mkdir -p /etc/containers/systemd ``` -------------------------------- ### Run Halo Backend with Gradle Source: https://docs.halo.run/2.23/developer-guide/core/run Run the Halo backend application using Gradle. Specify the active Spring profiles for development. The arguments differ for Windows and macOS/Linux. ```bash # macOS / Linux ./gradlew bootRun --args="--spring.profiles.active=dev" # Windows gradlew.bat bootRun --args="--spring.profiles.active=dev,win" ``` -------------------------------- ### Halo Docker Startup Parameters for Redis Source: https://docs.halo.run/2.24/getting-started/install/config Use these parameters when running Halo as a Docker container to enable Redis integration for session storage. Ensure the Redis host is accessible from the Halo container. ```bash - --spring.data.redis.host=localhost # Redis 服务地址 - --spring.data.redis.port=6379 # Redis 服务端口 - --spring.data.redis.database=0 # Redis 数据库 - --spring.data.redis.password= # Redis 密码 - --halo.session.store-type=redis # 声明 session 存储方式为 redis,默认不配置则为 in-memory - --halo.redis.enabled=true # 启用 Redis 服务 ``` -------------------------------- ### Example Custom Tab Component Source: https://docs.halo.run/2.22/developer-guide/plugin/extension-points/ui/plugin-self-tabs-create A Vue component example for a custom plugin tab. It injects the current plugin object to display its display name. ```vue <script lang="ts" setup> const plugin = inject<Ref<Plugin | undefined>>("plugin"); </script> <template> <h1>{{ plugin?.spec.displayName }}</h1> </template> ``` -------------------------------- ### Download Plugin Presets with Gradle Source: https://docs.halo.run/2.23/developer-guide/core/run Download preset plugins for Halo using Gradle. This command is optional and depends on your development needs. ```bash # Windows ./gradlew.bat downloadPluginPresets # macOS / Linux ./gradlew downloadPluginPresets ``` -------------------------------- ### Table Extension Floating Menu Example Source: https://docs.halo.run/2.24/developer-guide/plugin/extension-points/ui/default-editor-extension-create An example of implementing `getBubbleMenu` in the `Table` extension to add a 'add column before' button to the floating menu. It includes custom rendering logic and tippy options. ```javascript addOptions() { return { ...this.parent?.(), getBubbleMenu({ editor }) { return { pluginKey: "tableBubbleMenu", shouldShow: ({ state }: { state: EditorState }): boolean => { return isActive(state, Table.name); }, getRenderContainer(node) { let container = node; if (container.nodeName === "#text") { container = node.parentElement as HTMLElement; } while ( container && container.classList && !container.classList.contains("tableWrapper") ) { container = container.parentElement as HTMLElement; } return container; }, tippyOptions: { offset: [26, 0], }, items: [ { priority: 10, props: { icon: markRaw(MdiTableColumnPlusBefore), title: i18n.global.t("editor.menus.table.add_column_before"), action: () => editor.chain().focus().addColumnBefore().run(), }, }, ] } } } } ``` -------------------------------- ### API Request Example for Remote Code Generation Source: https://docs.halo.run/next/user-guide/shop/virtual-delivery This is an example of the JSON request body sent to your remote service for generating virtual codes (卡密) when a customer places an order. Ensure your service can handle this structure and the `orderItem` details. ```json { "orderItem": { "id": 10001, "orderId": 90001, "productId": 80001, "quantity": 2, "itemTitle": "年度会员兑换码", "productVariantSnapshot": { "id": 123, "name": "默认规格" } }, "dryRun": false } ``` -------------------------------- ### UI Service Running Confirmation Source: https://docs.halo.run/2.23/developer-guide/core/run This output indicates that the UI development server is running correctly. It shows the Vite version and the ready time, along with the local and network addresses. ```bash VITE v8.0.0 ready in 805 ms ➜ Local: http://localhost:3000/ ➜ Network: http://192.168.1.7:3000/ ``` -------------------------------- ### API Error Response Example for Remote Code Generation Source: https://docs.halo.run/next/user-guide/shop/virtual-delivery This example shows a structured error response format for your remote code generation service. Non-2xx status codes should be used for failures, providing a clear error code, message, and a request ID for traceability. ```json { "code": "CDK_OUT_OF_STOCK", "message": "No enough CDKs available", "requestId": "f38db1c2-2f7a-4dc3-b5a8-2d0012345678" } ``` -------------------------------- ### Example Site Basic Information Source: https://docs.halo.run/2.22/developer-guide/plugin/basics/server/object-management This JSON object represents the basic information of a Halo site, including title, subtitle, logo, URL, version details, SEO settings, locale, timezone, and activated theme. This data structure is returned by the SystemInfoGetter bean. ```json ```json { "title" : "guqing's blog", "subtitle" : "副标题", "logo" : "/upload/myavatar.png", "favicon" : "/upload/myavatar.png", "url" : "http://localhost:8090", "version" : { "majorVersion" : 2, "minorVersion" : 20, "normalVersion" : "2.20.10", "preRelease" : true, "publicApiStable" : true, "patchVersion" : 10, "preReleaseVersion" : "SNAPSHOT", "buildMetadata" : "", "stable" : false }, "seo" : { "blockSpiders" : false, "keywords" : "keyword1,keyword2", "description" : "站点描述" }, "locale" : "zh_CN_#Hans", "timeZone" : "Asia/Shanghai", "activatedThemeName" : "theme-earth" } ``` ``` -------------------------------- ### available(pluginName) Source: https://docs.halo.run/2.24/developer-guide/theme/finder-apis/plugin Checks if a plugin is available, considering both installation and activation status. ```APIDOC ## available(pluginName) ### Description Determines if a plugin is available by checking if it is both installed and enabled. ### Method `pluginFinder.available(pluginName)` ### Parameters #### Path Parameters * **pluginName** (string) - Required - The unique identifier of the plugin (`metadata.name`). ### Returns `boolean` - True if the plugin is available, false otherwise. ### Example ```html <li th:if="${pluginFinder.available('PluginSearchWidget')}"> <a href="javascript:SearchWidget.open()" title="搜索"> 搜索 </a> </li> ``` ``` -------------------------------- ### Configure Halo Container with Podman Quadlet (Root User) Source: https://docs.halo.run/2.22/getting-started/install/podman Defines the systemd unit file for the Halo container using Podman Quadlet syntax, optimized for running as the root user. ```ini # /etc/containers/systemd/halo.container [Unit] Description=The halo container Wants=network-online.target After=network-online.target [Container] AutoUpdate=registry ContainerName=halo Volume=/opt/podman-data/halo:/root/.halo PublishPort=127.0.0.1:8090:8090 Image=ghcr.io/halo-dev/halo:2.22 Exec=--halo.external-url=https://localhost:8090 --spring.sql.init.platform=postgresql --spring.r2dbc.url=r2dbc:pool:postgresql://127.0.0.1:5432/my-db --spring.r2dbc.username=my-user --spring.r2dbc.password=my-password [Service] Restart=always RestartSec=30s StartLimitInterval=30 TimeoutStartSec=900 TimeoutStopSec=70 [Install] WantedBy=multi-user.target default.target ``` -------------------------------- ### Get Post Archives (Paginated) Source: https://docs.halo.run/2.22/developer-guide/theme/finder-apis/post Retrieves a list of post archives based on pagination parameters. ```APIDOC ## archives(page,size) ### Description 根据分页参数获取文章归档列表。 ### Parameters 1. `page:int` - 分页页码,从 1 开始 2. `size:int` - 分页条数 ### Returns #ListResult<PostArchiveVo> ### Example __``` <th:block th:with="archives = ${postFinder.archives(1,10)}"> <th:block th:each="archive : ${archives.items}"> <h1 th:text="${archive.year}"></h1> <ul> <th:block th:each="month : ${archive.months}"> <li th:each="post : ${month.posts}"> <a th:href="@{${post.status.permalink}}" th:text="${post.spec.title}"> </a> </li> </th:block> </ul> </th:block> </th:block> ``` ``` -------------------------------- ### Registering Custom Model Indexes Source: https://docs.halo.run/next/developer-guide/plugin/api-reference/server/extension Demonstrates how to register custom model indexes using `IndexSpecs.single` and `IndexSpecs.multi`. This is crucial for optimizing queries on custom data models. ```java import java.time.Instant; import java.util.HashSet; import java.util.Set; import run.halo.app.extension.index.IndexSpecs; @Override public void start() { schemeManager.register(Moment.class, indexSpecs -> { // multi 用于声明一个返回多个值的索引 indexSpecs.add(IndexSpecs.<Moment, String>multi("spec.tags", String.class) .indexFunc(moment -> { var tags = moment.getSpec().getTags(); return tags == null ? Set.of() : tags; })); // single 用于声明一个返回单个值的索引,可以返回 null indexSpecs.add(IndexSpecs.<Moment, String>single("spec.owner", String.class) .indexFunc(moment -> moment.getSpec().getOwner())); // 索引值不再局限于字符串,也可以使用 Boolean、Integer、Instant 等可比较类型 indexSpecs.add(IndexSpecs.<Moment, Boolean>single("spec.pinned", Boolean.class) .indexFunc(moment -> moment.getSpec().getPinned())); indexSpecs.add(IndexSpecs.<Moment, Integer>single("spec.priority", Integer.class) .indexFunc(moment -> moment.getSpec().getPriority())); indexSpecs.add(IndexSpecs.<Moment, Instant>single("spec.publishTime", Instant.class) .indexFunc(moment -> moment.getSpec().getPublishTime())); }); } ``` -------------------------------- ### Implement a Basic Reconciler Source: https://docs.halo.run/2.22/developer-guide/plugin/api-reference/server/reconciler Implement the Reconciler interface and its reconcile() method. Configure the controller in setupWith() by specifying the extension to observe and building the controller. ```java import org.springframework.stereotype.Component; import io.halo.app.controller.Controller; import io.halo.app.controller.ControllerBuilder; import io.halo.app.controller.Reconciler; @Component public class PostReconciler implements Reconciler<Reconciler.Request> { @Override public Result reconcile(Request request) { } @Override public Controller setupWith(ControllerBuilder builder) { return builder .extension(new Post()) .build(); } } ``` -------------------------------- ### UppyUpload Component Usage Source: https://docs.halo.run/2.20/developer-guide/plugin/api-reference/ui/components/uppy-upload Example of how to use the UppyUpload component in a Vue.js application, including setting the upload endpoint and metadata. ```APIDOC ## UppyUpload Component ### Description A Vue.js component for handling file uploads using the Uppy library. ### Usage ```vue <script lang="ts" setup> import { ref } from 'vue'; const policyName = ref('my-test-policy'); const groupName = ref('my-test-group'); </script> <template> <UppyUpload endpoint="/apis/api.console.halo.run/v1alpha1/attachments/upload" :meta="{ policyName: policyName, groupName: groupName, }" /> </template> ``` ### Props - **`restrictions`** (Restrictions) - Optional - Specifies any restrictions for uploads. - **`meta`** (Record<string, unknown>) - Optional - Additional metadata to send with the upload. - **`autoProceed`** (boolean) - Optional - Automatically proceed with uploads after certain actions. Defaults to `false`. - **`allowedMetaFields`** (string[]) - Optional - Specifies allowed metadata fields. - **`endpoint`** (string) - Required - The URL endpoint where the data will be sent. No default value. - **`name`** (string) - Optional - The name of the form field for the upload. Defaults to `file`. - **`note`** (string) - Optional - Any notes or descriptions for the upload. - **`method`** (string) - Optional - The HTTP method to use for the request. Allowed values: "GET", "POST", "PUT", "HEAD", "get", "post", "put". Defaults to `post`. - **`disabled`** (boolean) - Optional - If true, the component will be disabled. Defaults to `false`. - **`width`** (string) - Optional - The width of the component. Defaults to `750px`. - **`height`** (string) - Optional - The height of the component. Defaults to `550px`. - **`doneButtonHandler`** (() => void) - Optional - A handler function called when the upload is done. ### Emits - **`uploaded`**: Emitted when a file upload is successful. It passes the `response` object (type: `SuccessResponse`). - **`error`**: Emitted when a file upload fails. It passes the `file` object and the `response` data. ``` -------------------------------- ### Add Halo Helm Repository and Update Charts Source: https://docs.halo.run/2.23/getting-started/install/helm Before installing, add the official Halo Helm chart repository and update your local chart repository to fetch the latest information. ```bash helm repo add halo https://halo-sigs.github.io/charts/ helm repo update ``` -------------------------------- ### Get Post Archives (Paginated by Year) Source: https://docs.halo.run/2.22/developer-guide/theme/finder-apis/post Retrieves a list of post archives based on pagination parameters and a specific year. ```APIDOC ## archives(page,size,year) ### Description 根据年份和分页参数获取文章归档列表。 ### Parameters 1. `page:int` - 分页页码,从 1 开始 2. `size:int` - 分页条数 3. `year:string` - 年份 ### Returns #ListResult<PostArchiveVo> ### Example __``` <th:block th:with="archives = ${postFinder.archives(1,10,'2022')}"> <th:block th:each="archive : ${archives.items}"> <h1 th:text="${archive.year}"></h1> <ul> <th:block th:each="month : ${archive.months}"> <li th:each="post : ${month.posts}"> <a th:href="@{${post.status.permalink}}" th:text="${post.spec.title}"> </a> </li> </th:block> </ul> </th:block> </th:block> ``` ``` -------------------------------- ### Reconciler with ExtensionMatcher for Public Posts Source: https://docs.halo.run/2.24/developer-guide/plugin/api-reference/server/reconciler An example of implementing ExtensionMatcher to filter reconciliation for 'Post' resources, specifically targeting those with a 'PUBLIC' visibility. ```java import static run.halo.app.extension.index.query.Queries.equal; import io.halo.app.extension.Extension; import io.halo.app.extension.Reconciler; import io.halo.app.extension.Reconciler.Request; import io.halo.app.extension.Result; import io.halo.app.extension.controller.Controller; import io.halo.app.extension.controller.ControllerBuilder; import io.halo.app.extension.controller.ExtensionMatcher; import org.springframework.stereotype.Component; @Component public class PostReconciler implements Reconciler<Reconciler.Request> { @Override public Result reconcile(Request request) { return Result.doNotRetry(); } @Override public Controller setupWith(ControllerBuilder builder) { // 只想观察 VisibleEnum.PUBLIC 的文章 ExtensionMatcher extensionMatcher = extension -> { var post = (Post) extension; return VisibleEnum.PUBLIC.equals(post.getSpec().getVisible()); }; return builder .extension(new Post()) .onAddMatcher(extensionMatcher) .onUpdateMatcher(extensionMatcher) .onDeleteMatcher(extensionMatcher) .build(); } } ```