PHPackages                             optimistdigital/nova-blog - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Admin Panels](/categories/admin)
4. /
5. optimistdigital/nova-blog

AbandonedArchivedLibrary[Admin Panels](/categories/admin)

optimistdigital/nova-blog
=========================

Blog manager for Laravel Nova

9.7.0(4y ago)3515.6k15[7 issues](https://github.com/outl1ne/nova-blog/issues)[24 PRs](https://github.com/outl1ne/nova-blog/pulls)MITPHPPHP &gt;=7.1.0

Since Aug 7Pushed 2y ago1 watchersCompare

[ Source](https://github.com/outl1ne/nova-blog)[ Packagist](https://packagist.org/packages/optimistdigital/nova-blog)[ RSS](/packages/optimistdigital-nova-blog/feed)WikiDiscussions master Synced 3w ago

READMEChangelog (10)Dependencies (6)Versions (95)Used By (0)

Nova Blog
=========

[](#nova-blog)

This [Laravel Nova](https://nova.laravel.com) package allows you to create a blog, manage blogposts and posts' content. The package is geared towards headless CMS's.

Installation
------------

[](#installation)

Install the package in a Laravel Nova project via Composer:

```
composer require optimistdigital/nova-blog
```

Publish the `nova-blog` configuration file and edit it to your preference:

```
php artisan vendor:publish --provider="OptimistDigital\NovaBlog\ToolServiceProvider" --tag="config"
```

Publish the database migration(s) and run migrate:

```
php artisan vendor:publish --provider="OptimistDigital\NovaBlog\ToolServiceProvider" --tag="migrations"
php artisan migrate
```

Register the tool with Nova in the `tools()` method of the `NovaServiceProvider`:

```
// in app/Providers/NovaServiceProvider.php

public function tools()
{
    return [
        // ...
        new \OptimistDigital\NovaBlog\NovaBlog
    ];
}
```

Defining locales
----------------

[](#defining-locales)

The config accepts a dictionary of locales.

```
// in /config/nova-blog.php

// ...
'locales' => [
  'en' => 'English',
  'et' => 'Estonian',
],

// OR

'locales' => function () {
  return Locale::all()->pluck('name', 'key');
},

// if you wish to cache the configuration, pass a reference instead:

'locales' => NovaBlogConfiguration::class . '::locales',

// ...
```

### Nova Lang

[](#nova-lang)

This package supports [optimistdigital/nova-lang](https://github.com/optimistdigital/nova-lang) for easier content localization. After installing and setting up `nova-lang` package, you can use `nova_lang_get_all_locales` helper function in `nova-blog` config file

```
'locales' => nova_lang_get_all_locales(),
```

### Toggling page draft feature

[](#toggling-page-draft-feature)

Draft feature allows you to create previews of resources before publishing them. By default this feature is disabled but can be enabled by installing [nova-drafts](https://github.com/optimistdigital/nova-drafts) package.

```
composer require optimistdigital/nova-drafts
```

### Add links to front-end pages

[](#add-links-to-front-end-pages)

To display a link to the actual page next to the slug, add or overwrite the closure in `config/nova-blog.php` for the key `page_url`.

```
// in /config/nova-blog.php

// ...
'page_url' => function (Post $post) {
  return env('FRONTEND_URL') . '/' . $post->slug;
},

// if you wish to cache the configuration, pass a reference instead:

'page_url' => NovaBlogConfiguration::class . '::pageUrl',
// ...
```

Helper functions
----------------

[](#helper-functions)

### nova\_get\_blog\_structure()

[](#nova_get_blog_structure)

The helper function `nova_get_blog_structure()` returns the base posts structure (titles, slugs, published at dates, content) that you can build your routes upon in the front-end.

Example response:

```
[
  {
    "id": 7,
    "created_at": "2019-06-19 11:58:56",
    "updated_at": "2019-06-19 11:59:23",
    "title": "Test post 1",
    "slug": "test-post-1",
    "post_content": [
      {
        "layout": "text",
        "key": "8965c7bfc0918086",
        "attributes": {
          "text-content": "Test post content."
        }
      },
      {
        "layout": "image",
        "key": "56f5bbe608b68cd6",
        "attributes": {
          "caption": "Test post image."
        }
      }
    ],
    "published_at": "2019-06-19 09:00:00",
    "seo_title": null,
    "seo_description": null,
    "seo_image": null,
    "data": null
  },
  {
    "id": 8,
    "created_at": "2019-06-19 12:00:06",
    "updated_at": "2019-06-19 12:00:06",
    "title": "Test post 2",
    "slug": "tes-post-2",
    "post_content": [
      {
        "layout": "text",
        "key": "0e340b84bc5dec28",
        "attributes": {
          "text-content": "Test post content."
        }
      },
      {
        "layout": "image",
        "key": "a4625050e49cf77c",
        "attributes": {
          "caption": "Test post image."
        }
      }
    ],
    "published_at": "2019-06-19 09:00:05",
    "seo_title": null,
    "seo_description": null,
    "seo_image": null,
    "data": null
  }
]
```

### nova\_get\_post\_by\_id($postId)

[](#nova_get_post_by_idpostid)

The helper function `nova_get_post_by_id($postId)` finds and returns the post with the given ID.

Example response for querying page with ID `7` (`nova_get_post_by_id(7)`):

```
{
  "id": 7,
  "name": "Test post 1",
  "slug": "testpost1",
  "published_at": "2019-06-19T09:00:00.000000Z",
  "post_content": [
    {
      "layout": "text",
      "key": "8965c7bfc0918086",
      "attributes": {
        "text-content": "Test post content."
      }
    },
    {
      "layout": "image",
      "key": "56f5bbe608b68cd6",
      "attributes": {
        "caption": "Test post image."
      }
    }
  ]
}
```

### nova\_get\_post\_by\_slug($slug)

[](#nova_get_post_by_slugslug)

The helper function `nova_get_post_by_slug($slug)` finds and returns the post with the given slug.

Example response for querying page with slug `test-post-3` (`nova_get_post_by_slug('test-post-3')`):

```
{
  "id": 14,
  "name": "Test post 3",
  "slug": "test-post-3",
  "published_at": "2019-06-25T09:00:00.000000Z",
  "post_content": [
    {
      "layout": "text",
      "key": "fc64d73f1f7508c4",
      "attributes": {
        "text-content": "Test post content."
      }
    },
    {
      "layout": "image",
      "key": "f8c9cc65b23b862a",
      "attributes": {
        "caption": "Test post image."
      }
    }
  ]
}
```

Credits
-------

[](#credits)

- [Marika Must](https://github.com/MarikaMustV)
- [Tarvo Reinpalu](https://github.com/Tarpsvo)

License
-------

[](#license)

Nova blog is open-sourced software licensed under the [MIT license](LICENSE.md).

###  Health Score

39

—

LowBetter than 85% of packages

Maintenance16

Infrequent updates — may be unmaintained

Popularity37

Limited adoption so far

Community17

Small or concentrated contributor base

Maturity70

Established project with proven stability

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~10 days

Recently: every ~35 days

Total

73

Last Release

1785d ago

Major Versions

5.6.0 → 6.0.02020-01-13

6.2.0 → 7.0.02020-02-18

7.4.0 → 8.0.02020-03-24

8.0.0 → 9.0.02020-04-14

7.0.x-dev → 9.3.02020-11-10

### Community

Maintainers

![](https://www.gravatar.com/avatar/1e15f6d62cfe0397e5ea7d355e9b642e7b1e24d2078097e07990e4b5e28d5812?d=identicon)[marycaz](/maintainers/marycaz)

---

Top Contributors

[![Tarpsvo](https://avatars.githubusercontent.com/u/2018660?v=4)](https://github.com/Tarpsvo "Tarpsvo (10 commits)")[![eleriojavere](https://avatars.githubusercontent.com/u/61348526?v=4)](https://github.com/eleriojavere "eleriojavere (9 commits)")[![MarikaMustV](https://avatars.githubusercontent.com/u/31190256?v=4)](https://github.com/MarikaMustV "MarikaMustV (6 commits)")[![MatisLepik](https://avatars.githubusercontent.com/u/9557916?v=4)](https://github.com/MatisLepik "MatisLepik (4 commits)")[![trippo](https://avatars.githubusercontent.com/u/497169?v=4)](https://github.com/trippo "trippo (1 commits)")

---

Tags

laravelpagemanagernovaoptimistdigital

### Embed Badge

![Health badge](/badges/optimistdigital-nova-blog/health.svg)

```
[![Health](https://phpackages.com/badges/optimistdigital-nova-blog/health.svg)](https://phpackages.com/packages/optimistdigital-nova-blog)
```

###  Alternatives

[optimistdigital/nova-page-manager

Page(s) and region(s) manager for Laravel Nova.

17989.2k](/packages/optimistdigital-nova-page-manager)[whitecube/nova-page

Static pages content management for Laravel Nova

23996.4k1](/packages/whitecube-nova-page)[outl1ne/nova-page-manager

Page(s) and region(s) manager for Laravel Nova.

17946.5k](/packages/outl1ne-nova-page-manager)[2lenet/crudit-bundle

The easy like Crud'it Bundle.

1615.6k12](/packages/2lenet-crudit-bundle)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
