Code Examples Plugin

Code snippets and examples library with syntax highlighting, categorization, and a full CRUD API.


Overview

The Code Examples plugin provides a complete system for managing code snippets and examples within SonicJS. Organize code by language and category, control visibility with publish states, and expose everything through a filterable REST API.

💻

Multi-Language Support

Store and categorize code snippets for any programming language

🏷️

Tags & Categories

Organize examples with categories and comma-separated tags

📡

REST API

Full CRUD API with filtering by language, category, and publish status

🔒

Publish Control

Draft and published states with sort ordering for display


Features

Code Management

  • Store code snippets with title, description, and source code
  • Specify the programming language for each example
  • Categorize examples into logical groups
  • Add comma-separated tags for flexible organization

Publishing & Ordering

  • Toggle publish state to control visibility
  • Set sort order for custom display sequencing
  • Automatic timestamps for creation and last update

Filtering API

  • Filter by publish status, language, or category
  • Results ordered by sort order then creation date (newest first)
  • Zod-validated request bodies on create and update

Data Schema

The plugin validates all data using Zod:

Code Example Schema

import { z } from 'zod'

const codeExampleSchema = z.object({
  id: z.number().optional(),
  title: z.string().min(1, 'Title is required').max(200),
  description: z.string().max(500).optional(),
  code: z.string().min(1, 'Code is required'),
  language: z.string().min(1, 'Language is required'),
  category: z.string().max(50).optional(),
  tags: z.string().max(200).optional(),
  isPublished: z.boolean().default(true),
  sortOrder: z.number().default(0),
  createdAt: z.number().optional(),
  updatedAt: z.number().optional(),
})

Field Reference

FieldTypeRequiredDescription
titlestringYesDisplay title (max 200 chars)
descriptionstringNoShort description (max 500 chars)
codestringYesThe code snippet content
languagestringYesProgramming language identifier
categorystringNoGrouping category (max 50 chars)
tagsstringNoComma-separated tags (max 200 chars)
isPublishedbooleanNoPublish state, defaults to true
sortOrdernumberNoDisplay order, defaults to 0

API Endpoints

All endpoints are mounted at /api/code-examples.

List Code Examples

GET /api/code-examples

# Get all code examples
curl https://your-site.com/api/code-examples

# Filter by published status
curl https://your-site.com/api/code-examples?published=true

# Filter by language
curl https://your-site.com/api/code-examples?language=typescript

# Filter by category
curl https://your-site.com/api/code-examples?category=authentication

# Combine filters
curl "https://your-site.com/api/code-examples?published=true&language=typescript&category=authentication"

Query Parameters:

ParameterTypeDescription
published"true" or "false"Filter by publish status
languagestringFilter by exact language match
categorystringFilter by exact category match

Response:

List Response

{
  "success": true,
  "data": [
    {
      "id": 1,
      "title": "Fetch API Example",
      "description": "Basic fetch request with error handling",
      "code": "const res = await fetch('/api/data')...",
      "language": "typescript",
      "category": "networking",
      "tags": "fetch,http,async",
      "isPublished": 1,
      "sortOrder": 0,
      "created_at": 1712678400,
      "updated_at": 1712678400
    }
  ]
}

Get Single Code Example

GET /api/code-examples/:id

curl https://your-site.com/api/code-examples/1

Response:

Single Response

{
  "success": true,
  "data": {
    "id": 1,
    "title": "Fetch API Example",
    "code": "const res = await fetch('/api/data')...",
    "language": "typescript",
    "category": "networking",
    "tags": "fetch,http,async",
    "isPublished": 1,
    "sortOrder": 0,
    "created_at": 1712678400,
    "updated_at": 1712678400
  }
}

Create Code Example

POST /api/code-examples

curl -X POST https://your-site.com/api/code-examples \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Hello World",
    "code": "console.log(\"Hello, World!\")",
    "language": "javascript",
    "category": "basics",
    "tags": "beginner,intro",
    "isPublished": true,
    "sortOrder": 1
  }'

Response (201):

Create Response

{
  "success": true,
  "data": { "id": 2, "title": "Hello World", "..." : "..." },
  "message": "Code example created successfully"
}

Update Code Example

Supports partial updates -- only include the fields you want to change.

PUT /api/code-examples/:id

curl -X PUT https://your-site.com/api/code-examples/2 \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Hello World (Updated)",
    "isPublished": false
  }'

Response:

Update Response

{
  "success": true,
  "data": { "id": 2, "title": "Hello World (Updated)", "isPublished": 0, "..." : "..." },
  "message": "Code example updated successfully"
}

Delete Code Example

DELETE /api/code-examples/:id

curl -X DELETE https://your-site.com/api/code-examples/2

Response:

Delete Response

{
  "success": true,
  "message": "Code example deleted successfully"
}

Error Responses

All endpoints return consistent error shapes:

StatusConditionBody
400Validation failed{ "success": false, "error": "Validation failed", "details": [...] }
404Not found{ "error": "Code example not found" }
500Server error{ "success": false, "error": "Failed to ..." }

Permissions

The Code Examples plugin uses role-based access for admin operations.

Admin Access

RolePermissions
adminFull access to all code example operations
editorCreate, edit, and delete code examples

API Access

The REST API routes do not require authentication by default. To restrict API access, wrap the routes with your own auth middleware.

Restrict API Access

import { Hono } from 'hono'
import { authMiddleware } from './middleware/auth'

const app = new Hono()

// Protect all code example API routes
app.use('/api/code-examples/*', authMiddleware())

Admin Interface

The plugin registers three admin pages and a sidebar menu item.

Code Examples List

Path: /admin/code-examples

Browse and manage all code examples:

  • View all snippets in a sortable list
  • Quick-filter by language or category
  • Publish and unpublish from the list view

Create Code Example

Path: /admin/code-examples/new

Add a new code snippet with the full form:

  • Title, description, code editor
  • Language selector and category input
  • Tags, publish toggle, and sort order

Edit Code Example

Path: /admin/code-examples/:id

Edit an existing code snippet with the same form layout.

Menu Item

The plugin adds a Code Examples item to the admin sidebar with a code icon at position 65.


Integration

Plugin Registration

Register the Plugin

import { createCodeExamplesPlugin } from '@sonicjs-cms/core/plugins'

// Using the factory function
const codeExamplesPlugin = createCodeExamplesPlugin()

// Or import the pre-built instance
import { codeExamplesPlugin } from '@sonicjs-cms/core/plugins'

Lifecycle Hooks

The plugin implements install, uninstall, activate, and deactivate lifecycle hooks:

Lifecycle Hooks

// Install: creates the code_examples table and indexes
// Uninstall: drops the code_examples table
// Activate / Deactivate: logging only

builder.lifecycle({
  install: async (context) => {
    await context.db.prepare(codeExampleMigration).run()
  },
  uninstall: async (context) => {
    await context.db.prepare('DROP TABLE IF EXISTS code_examples').run()
  },
  activate: async () => { /* logs activation */ },
  deactivate: async () => { /* logs deactivation */ },
})

Querying from Custom Code

Custom Query

import { Hono } from 'hono'

const app = new Hono()

app.get('/api/snippets-by-lang/:lang', async (c) => {
  const lang = c.req.param('lang')
  const db = (c as any).env?.DB

  const { results } = await db
    .prepare(
      'SELECT * FROM code_examples WHERE language = ? AND isPublished = 1 ORDER BY sortOrder ASC'
    )
    .bind(lang)
    .all()

  return c.json({ data: results })
})

Database Schema

The plugin creates a single table with supporting indexes and an update trigger:

ColumnTypeDescription
idINTEGER (PK)Auto-incrementing primary key
titleTEXTCode example title (NOT NULL)
descriptionTEXTOptional description
codeTEXTThe code snippet (NOT NULL)
languageTEXTProgramming language (NOT NULL)
categoryTEXTOptional category
tagsTEXTOptional comma-separated tags
isPublishedINTEGER1 = published, 0 = draft (NOT NULL)
sortOrderINTEGERDisplay order (NOT NULL, default 0)
created_atINTEGERUnix timestamp, set on insert
updated_atINTEGERUnix timestamp, auto-updated via trigger

Indexes

IndexColumn
idx_code_examples_publishedisPublished
idx_code_examples_sort_ordersortOrder
idx_code_examples_languagelanguage
idx_code_examples_categorycategory

Next Steps

Was this page helpful?