How the Luban H5 Publish Workflow and view_mode Preview System Works

The Luban H5 editor distinguishes between permanent publishing and temporary previewing by combining a boolean is_publish flag with a view_mode=preview query parameter, enforcing access control in both the Vue.js front-end engine and the Node.js back-end controller.

The ly525/luban-h5 repository implements a dual-layer visibility system that allows creators to preview unpublished works while ensuring only released content is publicly accessible. This design centers on two complementary mechanisms: a persistent is_publish property stored on the work model and a transient view_mode query string that grants temporary render access.

Publishing a Work from the Editor

The publish workflow originates in the editor's header component, where user actions translate into state mutations and API calls.

Triggering the Publish Action

In front-end/h5/src/components/core/editor/header/action-menu.js, the publish button triggers the handlePublish() method. This function updates the work's publication status through a Vuex mutation before persisting the change to the server.

// action-menu.vue
handlePublish () {
  this.updateWork({ is_publish: true })   // mark work as published
  this.saveWork({ successMsg: '发布成功' }) // persist to server
}

The updateWork mutation writes is_publish: true into the work object. In front-end/h5/src/components/core/models/work.js, the model stores this flag as this.is_publish = !!work.is_publish, ensuring a strict boolean value for downstream checks.

Generating Shareable Preview URLs

When a creator opens the Share Info modal, the system generates two distinct URLs based on the current work ID. In front-end/h5/src/components/core/editor/modals/share-info.js, the logic constructs these endpoints:

// share-info.vue
previewUrl: `${window.location.origin}/works/preview/${this.work.id}?view_mode=preview`
releaseUrl: `${window.location.origin}/works/preview/${this.work.id}`

The previewUrl appends ?view_mode=preview to force the rendering engine into preview mode, while the releaseUrl omits this parameter to simulate the experience of a standard visitor viewing a published work.

Front-End Rendering Decision Logic

The rendering engine entry point at front-end/h5/src/engine-entry.js implements the authorization gate. It inspects the URL query string and the work's is_publish property to determine whether to render the page content or display an unpublished placeholder.

const query = new URLSearchParams(window.location.search)
const canRender = query.get('view_mode') === 'preview' || work.is_publish
if (!canRender) return this.renderUnPublishTip()

This logic executes on lines 88–90 of the engine entry file. If the query parameter equals 'preview' or the work's is_publish flag is truthy, the engine proceeds to render the work's pages. Otherwise, it invokes renderUnPublishTip() to show a "未发布" (not published) message.

Back-End Verification Layer

The ly525/luban-h5 back-end duplicates this authorization check to prevent data leakage through API requests. In back-end/h5-api/api/work/controllers/Work.js, the previewOne controller evaluates the same conditions before returning page data.

const { view_mode } = ctx.request.query
const canRender = view_mode === VIEW_MODE.PREVIEW || work.is_publish
if (!canRender) work.pages = []   // hide unpublished content

Lines 24–27 of the Work controller demonstrate this defense-in-depth strategy. Even if a request bypasses the front-end checks, the server strips the pages array from the response when neither the preview query parameter nor the publish flag is present.

Summary

  • Publishing sets is_publish: true via the handlePublish() action in action-menu.js, persisting the state through the work model.
  • Preview URLs use the ?view_mode=preview query parameter to grant temporary access to unpublished works without modifying the database.
  • Front-end enforcement in engine-entry.js requires either the preview parameter or the publish flag to render content.
  • Back-end verification in Work.js mirrors this logic, returning empty page arrays for unauthorized requests to prevent data exposure.

Frequently Asked Questions

What is the difference between preview mode and published mode in Luban H5?

Preview mode provides temporary read-only access via the view_mode=preview query parameter, allowing creators to review changes before committing them. Published mode activates when is_publish is set to true in the database, making the work permanently accessible to all visitors without requiring special URL parameters.

How does the back-end prevent unauthorized access to unpublished works?

The previewOne controller in back-end/h5-api/api/work/controllers/Work.js checks both the view_mode query and the work.is_publish property. If neither condition is satisfied, the controller explicitly sets work.pages = [] before sending the response, ensuring unpublished content never reaches the client.

Where is the publish state stored in the Luban H5 data model?

The publish state lives as a boolean is_publish property on the work model, defined in front-end/h5/src/components/core/models/work.js. The Vuex store synchronizes this value between the client UI and the back-end API, with the database persisting the flag for long-term access control.

Can a user preview a work without clicking the Publish button?

Yes. The Share Info modal generates a previewUrl containing ?view_mode=preview, which bypasses the is_publish check in both the front-end engine and back-end controller. This allows safe sharing of draft works with stakeholders without marking them as publicly released.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →