# Workflow: Publish Content

This workflow guides you through safely publishing content to make it live.

## Understanding Draft vs Published

| Status | Behavior |
|--------|----------|
| **Draft** | Content is saved but not visible on the live site. Only visible in preview mode. |
| **Published** | Content is visible to all site visitors. |

By default, new content is created as a draft.

## Publishing Individual Items

### Publish an Entry

```bash
riverbankcms entry publish <content-type> <identifier>
```

**Example:**

```bash
riverbankcms entry publish blog-post my-first-post
```

### Publish a Page

```bash
riverbankcms page publish <identifier>
```

**Example:**

```bash
riverbankcms page publish about
```

## Checking Publication Status

### Check Entry Status

```bash
riverbankcms entry get <content-type> <identifier>
```

Look for:
- `status: "published"` or `status: "draft"`
- `hasUnpublishedChanges: true/false`

### Check Page Status

```bash
riverbankcms page get <identifier>
```

### List All with Status (JSON)

```bash
# List entries with status
riverbankcms entry list blog-post --json

# Filter to see status fields (requires jq)
riverbankcms entry list blog-post --json | jq '.entries[] | {identifier, status, hasUnpublishedChanges}'

# List pages with status
riverbankcms page list --json
```

## Bulk Publishing via Push

When using `riverbankcms push`, the status is synced based on your local content files.

### How Status Sync Works

Push compares the `status` field in your local files to the remote status:
- If local is "published" and remote is "draft" → push will **publish** the content
- If local is "draft" and remote is "published" → push will **unpublish** the content
- If statuses match → no status change

### Edit Local Files to Control Status

In your local content files, set the status field:

```json
{
  "identifier": "my-post",
  "status": "published",
  "data": { "title": "My Post" }
}
```

Then push:

```bash
riverbankcms push
```

### Push Then Publish Selectively

```bash
# Push as drafts (default behavior)
riverbankcms push

# Then publish specific items
riverbankcms entry publish blog-post featured-post
riverbankcms page publish landing-page
```

## Unpublishing Content

### Unpublish an Entry

```bash
riverbankcms entry unpublish <content-type> <identifier>
```

**Example:**

```bash
riverbankcms entry unpublish blog-post old-post
```

### Unpublish a Page

```bash
riverbankcms page unpublish <identifier>
```

**Example:**

```bash
riverbankcms page unpublish outdated-landing
```

Unpublishing reverts content to draft status. The content is preserved but no longer visible on the live site.

## Safe Publishing Workflow

Follow these steps to safely publish content:

### 1. Pull Latest Content

Ensure you're working with the current state:

```bash
riverbankcms pull
```

### 2. Make and Verify Changes

```bash
# Make changes via CLI or edit local files
riverbankcms entry upsert blog-post my-post --data '...'

# Or edit content/entries/blog-post.json
```

### 3. Preview Changes

```bash
# Preview what would be pushed
riverbankcms push --dry-run

# Preview specific blocks visually
riverbankcms preview block.hero --data '...' --open
```

### 4. Push Changes (as Draft)

```bash
riverbankcms push
```

### 5. Verify in CMS Dashboard

- Log into the dashboard
- Review the content in preview mode
- Check formatting, images, links

### 6. Publish

```bash
riverbankcms entry publish blog-post my-post
# or
riverbankcms page publish my-page
```

### 7. Verify Live

- Check the live site
- Confirm content appears correctly
- Test any links or interactive elements

## Handling Unpublished Changes

When you edit published content, it stays published but gains pending changes.

### Check for Pending Changes

```bash
riverbankcms entry get blog-post my-post --json | grep hasUnpublishedChanges
```

- `hasUnpublishedChanges: true` - There are edits not yet live
- `hasUnpublishedChanges: false` - Live version is current

### Apply Pending Changes

Re-publish to make pending changes live:

```bash
riverbankcms entry publish blog-post my-post
```

### Discard Pending Changes

To revert to the published version, you would need to:

1. Pull the published content: `riverbankcms pull`
2. The local files will have the current (modified) state
3. Manually revert in the dashboard or re-push the original content

## Publishing to Production

For production environments, use `--env=remote`:

```bash
# Pull from production
riverbankcms pull --env=remote

# Preview production push
riverbankcms push --env=remote --dry-run

# Push to production (requires --yes for safety)
riverbankcms push --env=remote --yes

# Publish specific content on production
riverbankcms entry publish blog-post my-post --env=remote
riverbankcms page publish landing --env=remote
```

**Safety notes:**
- `--env=remote` targets production environment
- Push to remote requires `--yes` flag to prevent accidents
- Always preview with `--dry-run` first

## Publishing Checklist

Before publishing content, verify:

- [ ] Content is accurate and complete
- [ ] Images load correctly
- [ ] Links work (internal and external)
- [ ] SEO metadata is set (title, description)
- [ ] Mobile layout looks good (if applicable)
- [ ] No placeholder or test content remains
- [ ] Spell check / grammar check completed

## Troubleshooting

### Content not appearing on live site

1. Check if published: `riverbankcms entry get <type> <identifier>`
2. Look for `status: "published"`
3. If draft, publish it: `riverbankcms entry publish <type> <identifier>`
4. Check for caching - may need to wait or clear cache

### Published but showing old content

1. Check for pending changes: `hasUnpublishedChanges: true`
2. Re-publish to apply changes: `riverbankcms entry publish <type> <identifier>`
3. Clear any CDN or browser cache

### Can't publish - validation error

1. Check required fields are filled
2. Review the error message for specifics
3. Get full entry data: `riverbankcms entry get <type> <identifier> --json`
4. Fix missing/invalid fields and retry
