{"_id":"@apostrophecms/blog-stable","name":"@apostrophecms/blog-stable","dist-tags":{"latest":"1.0.6"},"versions":{"1.0.6":{"name":"@apostrophecms/blog-stable","version":"1.0.6","description":"Blog module for ApostropheCMS websites","main":"index.js","scripts":{"lint":"npm run eslint","eslint":"eslint .","test":"npm run lint"},"repository":{"type":"git","url":"git+https://github.com/apostrophecms/apostrophe.git","directory":"packages/blog"},"homepage":"https://github.com/apostrophecms/apostrophe/tree/main/packagesblog#readme","author":{"name":"Apostrophe Technologies"},"license":"MIT","publishConfig":{"access":"public"},"dependencies":{"dayjs":"^1.10.7"},"devDependencies":{"eslint":"^9.39.1","eslint-config-apostrophe":"workspace:^"},"gitHead":"b3e29f004f514041e1e389293ae67017c60d006e","_id":"@apostrophecms/blog-stable@1.0.6","bugs":{"url":"https://github.com/apostrophecms/apostrophe/issues"},"_nodeVersion":"24.10.0","_npmVersion":"11.6.1","dist":{"integrity":"sha512-04NJ740nh9j4LSZoWQqdEEIEoh4WlifLb2fmyxfsQEcPIl5rL+9LqDMdXbMjOpPhdNzn3rQNAXePV6J3dSTzqA==","shasum":"fa36eadef7a13a0edac7a9c6c2651f4bc2c1503f","tarball":"https://registry.npmjs.org/@apostrophecms/blog-stable/-/blog-stable-1.0.6.tgz","fileCount":18,"unpackedSize":20736,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIBC0cx3biZ1OCF9EIk5E+7W4fKrr4NcRwpcIxMZp2xFrAiEAqpDOEnvZrpDaGBsHslzEsQWT7pRZLeUm1OR7vshYy6g="}]},"_npmUser":{"name":"boutell","email":"tom@apostrophecms.com"},"directories":{},"maintainers":[{"name":"alexgilbert","email":"alex@apostrophecms.com"},{"name":"boutell","email":"tom@apostrophecms.com"},{"name":"romanek","email":"stuart+npm@apostrophecms.com"},{"name":"bodonkey","email":"robert.means1969+apostrophecms@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/blog-stable_1.0.6_1781112762159_0.7693087762059008"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-10T17:32:41.974Z","1.0.6":"2026-06-10T17:32:42.311Z","modified":"2026-06-10T17:32:42.659Z"},"maintainers":[{"name":"alexgilbert","email":"alex@apostrophecms.com"},{"name":"boutell","email":"tom@apostrophecms.com"},{"name":"romanek","email":"stuart+npm@apostrophecms.com"},{"name":"bodonkey","email":"robert.means1969+apostrophecms@gmail.com"}],"description":"Blog module for ApostropheCMS websites","homepage":"https://github.com/apostrophecms/apostrophe/tree/main/packagesblog#readme","repository":{"type":"git","url":"git+https://github.com/apostrophecms/apostrophe.git","directory":"packages/blog"},"author":{"name":"Apostrophe Technologies"},"bugs":{"url":"https://github.com/apostrophecms/apostrophe/issues"},"license":"MIT","readme":"<div align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/apostrophecms/apostrophe/main/logo.svg\" alt=\"ApostropheCMS logo\" width=\"80\" height=\"80\">\n\n  <h1>Apostrophe Blog</h1>\n  <p>\n    <a aria-label=\"Apostrophe logo\" href=\"https://docs.apostrophecms.org\">\n      <img src=\"https://img.shields.io/badge/MADE%20FOR%20ApostropheCMS-000000.svg?style=for-the-badge&logo=Apostrophe&labelColor=6516dd\">\n    </a>\n    <a aria-label=\"Join the community on Discord\" href=\"http://chat.apostrophecms.org\">\n      <img alt=\"\" src=\"https://img.shields.io/discord/517772094482677790?color=5865f2&label=Join%20the%20Discord&logo=discord&logoColor=fff&labelColor=000&style=for-the-badge&logoWidth=20\">\n    </a>\n    <a aria-label=\"License\" href=\"https://github.com/apostrophecms/blog/blob/main/LICENSE.md\">\n      <img alt=\"\" src=\"https://img.shields.io/static/v1?style=for-the-badge&labelColor=000000&label=License&message=MIT&color=3DA639\">\n    </a>\n  </p>\n</div>\n\n**Add blog functionality to ApostropheCMS sites** with article management, date-based filtering, and multiple blog support. Provides both the blog piece type and page templates to get started quickly.\n\n## Features\n\n- **📝 Blog Article Management** - Complete CRUD interface for blog posts with publication dates\n- **🗓️ Date-based Filtering** - Built-in year/month/day query filters for archives and navigation\n- **🎨 Fully Customizable** — Override templates, add fields, and style it to match your brand\n- **🔗 Multiple Blog Types** - Extend to create different blog categories (news, updates, etc.)\n- **⏰ Publication Control** - Articles only appear when published date is in the past\n\n## Installation\n\nTo install the module, use the command line to run this command in an Apostrophe project's root directory:\n\n```bash\nnpm install @apostrophecms/blog\n```\n\n## Usage\n\nConfigure the blog modules in your `app.js` file:\n\n```javascript\nimport apostrophe from 'apostrophe';\n\nexport default apostrophe({\n  root: import.meta,\n  shortName: 'my-project',\n  bundles: [ '@apostrophecms/blog' ],\n  modules: {\n    '@apostrophecms/blog': {},\n    '@apostrophecms/blog-page': {}\n  }\n});\n```\n\n### Enable the page type\n\nAdd the blog page type to your page configuration:\n\n```javascript\n// modules/@apostrophecms/page/index.js\nexport default {\n  options: {\n    types: [\n      {\n        name: '@apostrophecms/home-page',\n        label: 'Home'\n      },\n      {\n        name: '@apostrophecms/blog-page',\n        label: 'Blog'\n      }\n    ]\n  }\n};\n```\n\n## Customizing Templates\n\nThe included templates (`index.html`, `show.html`, `filters.html`) are starting points that demonstrate the available data. Override them in your project to implement your own styling and layout:\n\n```\nmodules/\n├── @apostrophecms/\n│   └── blog-page/\n│       └── views/\n│           ├── index.html      # Blog listing page\n│           ├── show.html       # Individual blog post\n│           └── filters.html    # Date filtering controls\n```\n\n## Date-based Filtering\n\nThe blog includes built-in query filters for creating archive navigation and date-based URLs:\n\n| Filter | Format | Example URL |\n|--------|--------|-------------|\n| `year` | `YYYY` | `/blog?year=2024` |\n| `month` | `YYYY-MM` | `/blog?month=2024-03` |\n| `day` | `YYYY-MM-DD` | `/blog?day=2024-03-15` |\n\n### Publication Control\n\nBlog posts use the `publishedAt` field to control visibility. Only articles with publication dates in the past appear on the public site. Editors see all articles in the admin interface.\n\n> **Note:** This doesn't automatically publish draft changes on the publication date. For scheduled publishing of draft content, consider the [@apostrophecms/scheduled-publishing](https://apostrophecms.com/extensions/scheduled-publishing) module.\n\n## Multiple Blog Types\n\nSometimes a website needs multiple, distinct types of blog posts. If the blog posts types can be managed together, it might be easiest to [add a new field](https://docs.apostrophecms.org/guide/content-schema.html#using-existing-field-groups) and [query builder](https://docs.apostrophecms.org/reference/module-api/module-overview.html#queries-self-query) to customize blog views. But if the blog posts types should be managed completely separately, it may be better to create separate piece types for each.\n\n### Creating a Custom Blog Type\n\n```javascript\n// modules/news-blog/index.js - for news articles\nexport default {\n  extend: '@apostrophecms/blog',\n  options: {\n    label: 'News Article',\n    pluralLabel: 'News Articles'\n  },\n  fields: {\n    add: {\n      priority: {\n        type: 'select',\n        choices: [\n          { label: 'Standard', value: 'standard' },\n          { label: 'Breaking', value: 'breaking' },\n          { label: 'Featured', value: 'featured' }\n        ]\n      },\n      source: {\n        type: 'string',\n        label: 'News Source',\n        help: 'Original source of this news item'\n      }\n    },\n    group: {\n      basics: { fields: ['priority', 'source'] }\n    }\n  }\n};\n```\n\nEvery blog piece type needs a corresponding page type that extends `@apostrophecms/blog-page`:\n\n```javascript\n// modules/news-blog-page/index.js - page type for news articles\nexport default {\n  extend: '@apostrophecms/blog-page'\n};\n```\n\n### Custom Templates for Blog Types\n\nEach blog type can have its own templates. Create them in the corresponding page module:\n\n```\nmodules/\n├── news-blog-page/\n│   └── views/\n│       ├── index.html      # News listing page\n│       ├── show.html       # Individual news article\n│       └── filters.html    # Custom filters for news\n└── @apostrophecms/\n    └── blog-page/\n        └── views/\n            ├── index.html  # Default blog listing\n            └── show.html   # Default blog post\n```\n\nThis allows you to:\n- Style news articles differently from regular blog posts\n- Add custom filtering options specific to news content\n- Display different fields or layouts for each blog type\n- Create distinct navigation and user experiences\n\nThis approach works well when blog types have different:\n- **Content structures** - News articles vs. technical tutorials vs. company announcements\n- **Editorial workflows** - Different teams managing different content types\n- **Display requirements** - Unique styling, filtering, or organization needs\n- **URL patterns** - `/blog/`, `/news/`, `/updates/` with distinct navigation\n\n## Field Reference\n\nThe blog piece type includes these fields by default:\n\n- **Title** (`title`) - Article headline\n- **Slug** (`slug`) - URL-friendly identifier  \n- **Publication Date** (`publishedAt`) - Controls public visibility\n- **Content** (`body`) - Rich text content area\n- **Meta Description** (`metaDescription`) - SEO description\n- **Tags** (`tags`) - Taxonomy for categorization\n\n---\n*Built with ❤️ by the ApostropheCMS team.*\n---\n**Found this useful?** [Give us a star on GitHub](https://github.com/apostrophecms/blog) ⭐","readmeFilename":"README.md","_rev":"1-5b86d59e5a4badb1d21517ec3a13845d"}