SDK Reference
Shortcodes API

Shortcodes API

Shortcodes allow users to embed dynamic content using simple tags in their posts.

Registering Shortcodes

sdk.shortcodes.register(name, handler)

Register a new shortcode.

// Simple shortcode
sdk.shortcodes.register('year', () => {
  return new Date().getFullYear().toString();
});
 
// Usage: [year] → 2024
// Shortcode with attributes
sdk.shortcodes.register('button', (attrs) => {
  const { text = 'Click Me', url = '#', color = 'blue' } = attrs;
  
  return `
    <a href="${url}" class="btn btn-${color}">
      ${text}
    </a>
  `;
});
 
// Usage: [button text="Sign Up" url="/signup" color="green"]
// Shortcode with content
sdk.shortcodes.register('note', (attrs, content) => {
  const { type = 'info' } = attrs;
  
  return `
    <div class="note note-${type}">
      ${content}
    </div>
  `;
});
 
// Usage: [note type="warning"]Be careful![/note]

Async Shortcodes

Shortcodes can be async for database queries or API calls:

sdk.shortcodes.register('recent-posts', async (attrs) => {
  const { count = 5 } = attrs;
  
  const posts = await sdk.content.getLatestPosts(parseInt(count));
  
  let html = '<ul class="recent-posts">';
  posts.forEach(post => {
    html += `<li><a href="${post.url}">${post.title}</a></li>`;
  });
  html += '</ul>';
  
  return html;
});
 
// Usage: [recent-posts count="10"]

Attribute Types

Attributes are passed as strings. Convert them as needed:

sdk.shortcodes.register('gallery', async (attrs) => {
  // Convert types
  const columns = parseInt(attrs.columns) || 3;
  const showCaptions = attrs.showCaptions === 'true';
  const limit = parseInt(attrs.limit) || 20;
  
  // ... render gallery
});
 
// Usage: [gallery columns="4" showCaptions="true" limit="12"]

Context Access

The handler receives context as a third parameter:

sdk.shortcodes.register('author-info', async (attrs, content, context) => {
  // context.post - current post (if on post page)
  // context.category - current category (if on category page)
  // context.user - current user (if logged in)
  
  if (context.post && context.post.author) {
    const author = context.post.author;
    return `
      <div class="author-box">
        <img src="${author.avatar}" alt="${author.name}">
        <strong>${author.name}</strong>
        <p>${author.bio}</p>
      </div>
    `;
  }
  
  return '';
});

Built-in Shortcodes

These shortcodes are available by default:

ShortcodeDescriptionExample
[year]Current year[year] → 2024
[sitename]Site name[sitename]
[current_url]Current page URL[current_url]
[if_logged_in]...[/if_logged_in]Show if user logged in[if_logged_in]Welcome![/if_logged_in]

Common Shortcode Examples

Embed YouTube Video

sdk.shortcodes.register('youtube', (attrs) => {
  const { id, width = '560', height = '315' } = attrs;
  
  if (!id) return '<p>YouTube ID required</p>';
  
  return `
    <div class="video-container">
      <iframe 
        width="${width}" 
        height="${height}" 
        src="https://www.youtube.com/embed/${id}" 
        frameborder="0" 
        allowfullscreen>
      </iframe>
    </div>
  `;
});
 
// Usage: [youtube id="dQw4w9WgXcQ"]

Callout Box

sdk.shortcodes.register('callout', (attrs, content) => {
  const { type = 'info', title = '' } = attrs;
  
  const icons = {
    info: 'ℹ️',
    warning: '⚠️',
    success: '✅',
    error: '❌'
  };
  
  return `
    <div class="callout callout-${type}">
      <span class="callout-icon">${icons[type] || ''}</span>
      ${title ? `<strong class="callout-title">${title}</strong>` : ''}
      <div class="callout-content">${content}</div>
    </div>
  `;
});
 
// Usage: [callout type="warning" title="Important"]Read this carefully[/callout]

Accordion

sdk.shortcodes.register('accordion', (attrs, content) => {
  const { title = 'Click to expand' } = attrs;
  const id = 'acc-' + Math.random().toString(36).substr(2, 9);
  
  return `
    <div class="accordion">
      <button class="accordion-header" onclick="this.classList.toggle('active'); document.getElementById('${id}').classList.toggle('open')">
        ${title}
        <span class="accordion-icon">▼</span>
      </button>
      <div id="${id}" class="accordion-content">
        ${content}
      </div>
    </div>
  `;
});
 
// Usage: [accordion title="FAQ: How does this work?"]Explanation here...[/accordion]

Card Grid

sdk.shortcodes.register('card', (attrs, content) => {
  const { title = '', image = '', link = '' } = attrs;
  
  let html = '<div class="card">';
  
  if (image) {
    html += `<img src="${image}" class="card-image" alt="${title}">`;
  }
  
  html += '<div class="card-body">';
  
  if (title) {
    if (link) {
      html += `<h3 class="card-title"><a href="${link}">${title}</a></h3>`;
    } else {
      html += `<h3 class="card-title">${title}</h3>`;
    }
  }
  
  html += `<div class="card-content">${content}</div>`;
  html += '</div></div>';
  
  return html;
});
 
sdk.shortcodes.register('cards', (attrs, content) => {
  const { columns = '3' } = attrs;
  
  return `
    <div class="cards-grid" style="
      display: grid;
      grid-template-columns: repeat(${columns}, 1fr);
      gap: 20px;
    ">
      ${content}
    </div>
  `;
});
 
// Usage:
// [cards columns="3"]
//   [card title="Card 1" image="/img1.jpg"]Description[/card]
//   [card title="Card 2" image="/img2.jpg"]Description[/card]
//   [card title="Card 3" image="/img3.jpg"]Description[/card]
// [/cards]

Pricing Table

sdk.shortcodes.register('pricing', (attrs) => {
  const { name, price, period = 'month', features = '', cta = 'Sign Up', url = '#', featured = 'false' } = attrs;
  
  const featureList = features.split(',').map(f => f.trim());
  const isFeatured = featured === 'true';
  
  return `
    <div class="pricing-card ${isFeatured ? 'pricing-featured' : ''}">
      <h3 class="pricing-name">${name}</h3>
      <div class="pricing-price">
        <span class="price-amount">${price}</span>
        <span class="price-period">/${period}</span>
      </div>
      <ul class="pricing-features">
        ${featureList.map(f => `<li>✓ ${f}</li>`).join('')}
      </ul>
      <a href="${url}" class="pricing-cta">${cta}</a>
    </div>
  `;
});
 
// Usage: [pricing name="Pro" price="$29" features="Unlimited posts, Priority support, API access" featured="true"]

Removing Shortcodes

sdk.shortcodes.unregister('year');

Checking Existence

if (sdk.shortcodes.exists('gallery')) {
  // Shortcode already registered
}