{"id":15511657,"url":"https://github.com/craftcms/starter-blog","last_synced_at":"2025-04-06T01:09:41.823Z","repository":{"id":36198302,"uuid":"199734494","full_name":"craftcms/starter-blog","owner":"craftcms","description":"Blog starter site learning resource.","archived":false,"fork":false,"pushed_at":"2025-01-21T18:04:48.000Z","size":9658,"stargazers_count":78,"open_issues_count":29,"forks_count":25,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-03-30T00:08:35.519Z","etag":null,"topics":["craftcms","example","gatsbyjs"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"0bsd","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/craftcms.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-07-30T22:09:32.000Z","updated_at":"2025-02-04T14:36:08.000Z","dependencies_parsed_at":"2024-01-10T23:45:57.304Z","dependency_job_id":"d57e2257-e0db-46ae-802a-b89f1d075068","html_url":"https://github.com/craftcms/starter-blog","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/craftcms%2Fstarter-blog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/craftcms%2Fstarter-blog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/craftcms%2Fstarter-blog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/craftcms%2Fstarter-blog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/craftcms","download_url":"https://codeload.github.com/craftcms/starter-blog/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247419861,"owners_count":20936012,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["craftcms","example","gatsbyjs"],"created_at":"2024-10-02T09:53:09.919Z","updated_at":"2025-04-06T01:09:41.805Z","avatar_url":"https://github.com/craftcms.png","language":"JavaScript","funding_links":[],"categories":["PHP"],"sub_categories":[],"readme":"\u003e [!IMPORTANT]\n\u003e **2024-11-26** — We have [a new suite of starter projects](https://craftcms.com/starters) that make better use of Craft 5, and are available in a variety of front-end frameworks!\n\n# Craft CMS Blog Starter\n\nThis blog starter project is for developers who are new to Craft CMS and want to learn the basics quickly. It seeks to demonstrate a few Craft essentials, without being too prescriptive about other parts of your development toolkit. You’ll get a turn-key front-end built on the native Twig templating language.\n\n### Topics, features, and implementations:\n\n- Using a [Matrix field](https://craftcms.com/docs/4.x/matrix-fields.html) as a page-builder;\n- [Templating fundamentals](https://craftcms.com/docs/4.x/dev/twig-primer.html#dry-templating), including: inheritance with layouts, dynamic includes, and macros;\n- [Pagination](https://craftcms.com/docs/4.x/element-queries.html#pagination) of entries;\n- Responsive images\n- Local asset volumes\n- [Error pages](https://craftcms.com/docs/4.x/routing.html#error-templates)\n- Installation and configuration of [plugins](https://plugins.craftcms.com)\n- Front-end development with Webpack and Tailwind CSS\n\n### It’s free to use\n\nWhen you install this starter, you’ll see that it’s running Craft Solo, which is free to use for any purpose. The installed plugins are also free. You can upgrade to Craft Pro or add paid plugins any time. See our [pricing page](https://craftcms.com/pricing) for details and feature comparisons.\n\n## Navigation\n\n* [Learning Resources](#learning-resources)\n* [Installation](#installation)\n  * [Clone this repo](#clone-this-repo)\n  * [Set up your local environment](#set-up-your-local-environment)\n  * [Create `.env`](#create-env)\n  * [Install Composer packages](#install-composer-packages)\n  * [Install Craft](#install-craft)\n* [Learn Craft](#learn-craft)\n  * [Create some content](#create-some-content)\n  * [Look at the settings](#look-at-the-settings)\n  * [Look at the template files](#look-at-the-template-files)\n  * [Try something new](#try-something-new)\n* [CSS and JS Development with Tailwind CSS, Webpack, and HMR](#css-and-js-development-with-tailwind-css-webpack-and-hmr)\n  * [Removal](#removal)\n  * [Setup](#setup)\n  * [Tailwind Development Flow](#tailwind-development-flow)\n* [Go headless with GraphQL](#go-headless-with-graph-ql)\n  * [Switch to Pro trial](#switch-to-pro-trial)\n  * [Headless Mode](#headless-mode)\n  * [Set up a GraphQL API endpoint](#set-up-a-graph-ql-api-endpoint)\n  * [Create GraphQL schemas and private tokens](#create-graph-ql-schemas-and-private-tokens)\n  * [Try our Gatsby starter](#try-our-gatsby-starter)\n* [Appendix](#appendix)\n  * [Apache or Nginx?](#apache-or-nginx)\n  * [MySQL or Postgres?](#my-sql-or-postgres)\n  * [URL Rewrites](#url-rewrites)\n\n## Learning Resources\n\nBefore you get started, we want you to know about a few helpful learning resources.\n\nOur official training partner, [CraftQuest](https://craftquest.io), provides many free training videos just for creating a free account. You’ll find excellent paid tutorials on advanced topics as well.\n\nThe [nystudio107 blog](https://nystudio107.com/blog) has some great articles on advanced topics such as optimization, module development, etc.\n\nYou’re always welcome in the [Craft Discord chat](https://craftcms.com/community). You’ll find a lot of super friendly, knowledgeable, Craft developers. Stop in and say hi!\n\n## Installation\n\nThis project is designed to work with [DDEV](https://ddev.readthedocs.io/en/stable/), our recommended local development environment.\n\n### Clone this repo\n\nOpen up a terminal window in a directory where you’d like to install Craft and run the following:\n\n```bash\ngit clone git@github.com:craftcms/starter-blog.git\n```\n\nMove into the newly created project folder:\n\n```bash\ncd starter-blog\n```\n\nAssuming you are starting your own project (rather than contributing to this repo), you don’t need to keep the existing git history:\n\n```bash\nrm -rf .git\n# (Optional) Start a new repository:\ngit init .\n```\n\n### Set up your local environment\n\n\u003e **Note**  \n\u003e You are welcome to use any local development tool you like—but these instructions only cover [DDEV](https://ddev.readthedocs.io/en/stable/).\n\u003e \n\u003e As long as the environment is capable of using the `web/` directory as the “web root,” you’ll be able to try it out!\n\n### Create `.env`\n\nCraft depends on environment variables set in a root `.env` file so you’ll need to copy the `.env.example` over.\n\n```bash\ncp .env.example .env\n```\n\n\u003e **Warning**\n\u003e It’s important that you do this _before_ installation. This starter project requires a couple of special environment variables found in `.env.example` that will be missing if you let the installer (or DDEV) populate the file.\n\n### Start DDEV\n\n[DDEV](https://ddev.readthedocs.io/en/stable/) is a Docker-based development environment that makes spinning up Craft projects quick and reliable. The required configuration files were cloned with the repo, so all you need to do is run:\n\n```bash\nddev start\n```\n\n### Install Composer packages\n\nRunning Composer with DDEV ensures that everything is done within the appropriate PHP environment:\n\n```bash\nddev composer update\n```\n\nWhy `update`? `composer install` will work just fine (using the existing `composer.lock` file)—but as you’re getting set up, we might as well make sure everything is up-to-date.\n\nYou might see some error output about cache clearing—not to worry! Craft isn’t installed yet, so that’s perfectly fine.\n\n### Install Craft\n\nRun the setup wizard with this command:\n\n```bash\nddev craft setup\n```\n\nCraft will generate a random value for `SECURITY_KEY` in your `.env` file. It will also ask you for database credentials, update the `.env` file accordingly (if necessary), and test the database connection.\n\nYou’ll be asked if you’d like to install Craft right away. If you choose not to, you can come back later and run:\n\n```bash\nddev craft install\n```\n\nThe setup wizard will also prompt you for details about your first account, including a username, email, and password. You’ll use these in just a moment!\n\n\u003e **Note**  \n\u003e If you are not using DDEV, you will need to provide a “Site URL” setting during installation.\n\nAfter the installer runs you should be able to see log into the Control Panel at `https://starter-blog.ddev.site/admin`. You can also run `ddev launch admin` to open a browser, directly.\n\n## Learn Craft\n\n### Create some content\n\nThis starter project ships without any content, so you get familiarize yourself with Craft’s intuitive [control panel](https://craftcms.com/docs/4.x/control-panel.html) while populating it. Start by adding some content and watch how the site comes together.\n\n(If you would prefer to just have some bogus content to get started, you can run `ddev craft up` to execute the included seed/content migration.)\n\n\u003e **Note**  \n\u003e [Unsplash](https://unsplash.com/) is a great place to grab free images if you need some to play with.\n\u003e When you add an image with an image field, you’ll see a thumbnail of it. Double-click that thumbnail to reveal more editing options.\n\n### Look at the settings\n\nIn the Control Panel, go to **Settings** → **Sections**.\n\n#### Fields\n\nTake a look at the fields to see how they are configured. Take note of the Matrix field named _Body Content_. Developers use the Matrix field as a page builder field quite often. Each Matrix block represents a content module that content authors may use to piece together pages creatively—and safely.\n\n#### Sections\n\nYou’ll find three Sections: Two [Singles](https://craftcms.com/docs/4.x/entries.html#singles) and one [Channel](https://craftcms.com/docs/4.x/entries.html#channels). Singles are for standalone, evergreen pages and Channels are for listable content like news articles. Craft also has a hierarchical section type, [Structure](https://craftcms.com/docs/4.x/entries.html#structures), but it is not used in this project.\n\n#### Assets\n\nThis starter includes one local asset volume for all of your uploads. You’ll find a related `/web/uploads` folder. Take a look at the Uploads volume settings to see how it’s configured. You’ll find that it has a Field Layout tab with a couple of fields applied to it. It is possible for uploaded Assets to have custom fields for metadata.\n\n\u003e **Note**  \n\u003e If you want to start with a large image library, you can copy images directly to the `/web/uploads/images` folder, then run the asset indexing tool from the control panel (**Utilities** → **Asset Indexes**), or via the CLI: `ddev craft index-assets/one uploads`.\n\n### Look at the template files\n\nBe sure and read up on Craft’s [front-end development docs](https://craftcms.com/docs/4.x/dev/) for Twig templating features. Twig is not unique to Craft! It’s a well-loved, PHP-driven templating language, with great [documentation](https://twig.symfony.com/doc/3.x/) of its own.\n\nTake a look at the files in the `/templates` folder. There are comments throughout the templates to help you understand what’s going on—and why things are set up as they are. The `.twig` extension is not required (`.html` is also acceptable), but it provides a hint to IDEs (like the free [Visual Studio Code](https://code.visualstudio.com/)) that they should use special rules for syntax highlighting.\n\n\u003e **Note**  \n\u003e Curious about the folders with underscores? When Craft doesn’t find a matching element URL or [route](https://craftcms.com/docs/4.x/routing.html), it automatically looks for a file in your `templates/` with the request’s path. For example, if you create `templates/foo/bar.twig` then Craft will render that template when the URL `https://starter-project.ddev.site/foo/bar` is requested. If you’d like to keep template folders (or individual files) private, prepend the name with an underscore (`_`). In this starter project, there is a single folder, `_private`, to hold all templates that should not be publicly accessible.\n\u003e\n\u003e You can still use a “private” template in a section’s settings!\n\n### Try something new\n\nTry adding a feature of your own. For example, you might like to add [categories](https://craftcms.com/docs/4.x/categories.html) to your blog posts and have listing pages for them.\n\n#### Create an empty template\n\nMake a new, empty file here:  `templates/_private/category.twig`. It doesn’t need any code yet.\n\n#### Create a new category group\n\n1. Go to **Settings** → **Categories** and create a new category group named Topics\n2. Set Max Levels to `1`\n3. Set the URI format to `topic/{slug}`\n4. Set the Template path to the template you created in the first step.\n5. Save it.\n\n#### Create a new category field\n\n1. Go to **Settings** → **Fields** and create a **Categories** field for your new group.\n2. Go to **Settings** → **Sections** → **Blog** and add your new field under the _Field Layout_ tab.\n\nBack on a blog entry, you can now assign categories, or create new ones on-the-fly!\n\n\u003e **Note**  \n\u003e Double-click an attached category to edit it, in-place.\n\n#### Modify your category template\n\nCopy over code from the `templates/_private/home.twig` template.\n\nFind the `\u003ch1\u003e` tag and modify the `\u003ca\u003e` tag like so:\n\n```twig\n\u003ca href=\"{{ category.url }}\"\u003eTopic: {{ category.title }}\u003c/a\u003e\n```\n\nFind the [element query](https://craftcms.com/docs/4.x/element-queries.html) that looks like this…\n\n```twig\n{% set query = craft.entries()\n  .section('blog')\n  .limit(10) %}\n```\n\n…and add `.relatedTo(category)` to it, like this:\n\n```twig\n{% set query = craft.entries()\n  .section('blog')\n  .relatedTo(category)\n  .limit(10) %}\n```\n\nFinally, find and delete this:\n\n```twig\n{% if pageInfo.currentPage == 1 %}\n  {{ entry.siteIntroduction }}\n{% endif %}\n```\n\n#### Add some categories\n\nIf you haven’t already added some categories, now’s the time!\n\n1. Go to **Categories** in the left navigation in the control panel and create a few topics\n2. Go to some blog entries and add categories to them\n\n#### Test it\n\nVisit `https://starter-blog.ddev.site/topic/{a-topic-slug}` to see a list of blog posts related to one of your topics! You can find the slug of a topic on its edit screen, at the top of the right-hand column.\n\n#### Finish it\n\nYou’ll want to expose these categories somewhere, like the main navigation, in a sidebar, or as “tags” under a blog post title.\n\nHere are a few tips to get you going…\n\nTo create a navigation menu for the _Topics_ category you created, you could do something like this:\n\n```twig\n{% set allCategories = craft.categories.group('topics').all() %}\n```\n\n\u003e **Note**  \n\u003e This query will work anywhere—Craft doesn’t limit where your content can be accessed or output.\n\nTo get the first (or only) category from a blog entry (assuming your category field’s handle is `topic`) you’d do this:\n\n```twig\n{% set category = entry.topic.one() %}\n\n{% if category %}{{ category.link }}{% endif %}\n\n{# OR #}\n\n{% if category %}\n  \u003ca href=\"{{ category.url }}\" class=\"class names\"\u003e{{ category.title }}\u003c/a\u003e\n{% endif %}\n```\n\nIf you’d like to feature three other blog posts within the same category at the bottom of a blog post, you can grab them like so:\n\n```twig\n{% set category = entry.topic.one() %}\n\n{% if category %}\n  {% set otherBlogPosts = craft.entries()\n    .relatedTo(category)\n    .not(entry)\n    .limit(3)\n    .all() %}\n\n  {% if otherBlogPosts | length %}\n    \u003ch3\u003eYou might also like:\u003ch3\u003e\n    \u003cul\u003e\n      {% for otherBlogPost in otherBlogPosts %}\n        \u003cli\u003e{{ otherBlogPost.link }}\u003cli\u003e\n      {% endfor %}\n    \u003c/ul\u003e\n  {% endif %}\n{% endif %}\n```\n\nWe’ll leave the rest to you!\n\n## CSS and JS Development with Tailwind CSS, Webpack, and HMR\n\n[Webpack](https://webpack.js.org/) and [Tailwind CSS](https://tailwindcss.com/) are popular front-end technologies. We chose Tailwind because it allows you to quickly add style to your markup with “utility classes.”\n\n### Removal\n\nWe hope you’ll give it a go, but if you prefer not to, then delete these folders and files:\n\n* `src/`\n* `package.json`\n* `package-lock.json`\n\nIn the `templates/layout/main.twig` find this:\n\n```twig\n{% set stylesheet = rev('main.css') %}\n{% if stylesheet %}\n  \u003clink rel=\"stylesheet\" href=\"{{ rev('main.css') }}\"\u003e\n{% endif %}\n```\n\nReplace it with a link to your own stylesheet.\n\nYou can also safely uninstall and remove the Asset Rev plugin from the Control Panel (and delete the `config/assetrev.php` file).\n\n### Setup\n\nDDEV comes installed with Node and [NPM](https://www.npmjs.com). From your project folder, run:\n\n```bash\nddev npm install\n```\n\n### Tailwind Development Flow\n\nAll of the SCSS and JavaScript files are in the project root `src/` folder.\n\nThere are three npm scripts you can run:\n\n#### Development Build\n\n```bash\nddev npm run dev\n```\n\nThe above command  builds the largest possible css file with _all_ of Tailwind’s classes available to you. The resulting file is generally considered too large for production use, but it allows you to explore all of the possibilities during development.\n\n#### Production Build\n\n```bash\nddev npm run production\n```\n\nThe above command will minify all of the CSS and JavaScript. It will also remove any classes that aren’t actually used in the `/template` files resulting in a very small file.\n\n#### Hot Module Reloading (HMR)\n\nFor this to work you must make sure you are in Dev Mode. Check the `/.env` file to make sure you see this:\n\n```bash\nENVIRONMENT=\"dev\"\n```\n\nThen run this script:\n\n```bash\nddev npm run hot\n```\n\nRefresh the browser. Now you’ll see changes in the browser immediately (without a page refresh) as you edit `.scss` files in the `/src` folder. Hot module reloading does not apply to changes made in Twig templates.\n\nWhen you’re done, cancel the npm process with CTRL+C.\n\nYou can build minified CSS and JS for production by running:\n\n```bash\nddev npm run build\n```\n\nIf you’d rather compile without minification, run:\n\n```bash\nddev npm run production\n```\n\n## Go headless with GraphQL\n\nCraft Pro includes a native GraphQL implementation which makes Craft perfect for front-end frameworks like [Gatsby](https://www.gatsbyjs.org/) and [Gridsome](https://gridsome.org/).\n\nSee Craft’s [GraphQL documentation](https://craftcms.com/docs/4.x/graphql.html) to learn more about it.\n\n### Switch to Pro trial\n\nCraft is installed with the free Solo edition. In your local environment, you can switch to Pro in trial mode with no time limits. That allows you to try Pro features as well as commercial plugins for as long as you like. Read more about that in our guide, [Try Craft Pro \u0026 Plugins Before Buying](https://craftcms.com/guides/try-craft-pro-plugins-before-buying).\n\nTo enable GraphQL support, find the “Solo” badge at the bottom of the left side navigation column and click it. On the next screen, under the Pro edition block, click the “Try for free” button. After trial mode is enabled, refresh the browser. You should now see a GraphQL menu item.\n\n### Headless Mode\n\nIf you want to use Craft purely as a headless CMS, set the [`headlessMode` configuration](https://craftcms.com/docs/4.x/config/config-settings.html#headlessmode) in `/config/general.php`:\n\n```php\nreturn GeneralConfig::create()\n  // ...\n  -\u003eheadlessMode(true)\n  // ...\n;\n```\n\nAssuming your front-end is in another repository, you are free to remove these files and folders:\n\n* All files in the `templates` folder\n* All front-end development files and folders\n  * `/node_modules` (if you previously ran `npm install`)\n  * `/src`\n  * `package-lock.json`\n  * `package.json`\n  * `postcss.config.js`\n  * `tailwind.config.js`\n  * `webpack.config.js`\n\n### Set up a GraphQL API endpoint\n\nEdit `config/routes.php` to look like this:\n\n```php\nreturn [\n    'api' =\u003e 'graphql/api'\n];\n```\n\nThe `'api'` key can be any route you prefer as long as it maps to `graphql/api`.\n\n### Create GraphQL schemas and private tokens\n\nGo to GraphQL → Schemas. You’ll see one public schema for which you can add access to various elements. You can also create private schemas with tokens, each with their own permissions.\n\n### Try our Gatsby starter\n\nYou’ll find a Craft + Gatsby blog starter in the `/headless-front-end/gatsby` directory. Check out that [README](/headless-front-end/gatsby/README.md) to get started with it.\n\n## Appendix\n\n### Apache or Nginx?\n\nIf you’re just getting started with Craft, roll with Apache. See the [URL rewrites appendix](#url-rewrites) above to learn why. Otherwise, it’s up to you!\n\n### MySQL or Postgres?\n\nCraft likes both. MySQL is the most popular but you should be aware of a caveat that produces [unexpected search results](https://github.com/craftcms/cms/issues/3240) and how to solve it by [enabling fuzzy search](https://craftcms.com/guides/enabling-fuzzy-search-by-default). \n\nSpoiler: Add this to your `config/general.php` file under the `'*'` array key:\n\n```php\n'defaultSearchTermOptions' =\u003e [\n    'subLeft' =\u003e true,\n    'subRight' =\u003e true,\n],\n```\n\n### URL Rewrites\n\nIf you’re coming to Craft from WordPress then this topic is in line with [enabling pretty URLs](https://wordpress.org/support/article/using-permalinks/#mod_rewrite-pretty-permalinks), and should feel familiar. See our guide, [Removing “index.php” from URLs](https://craftcms.com/guides/removing-index-php-from-urls).\n\nCraft’s default setup assumes you want to see urls like this:\n\n```\nhttp://mysite.test/path/to/entry\n```\n\nNot URLs like:\n\n```\nhttp://mysite.test/index.php?p=path/to/entry\n```\n\nCraft ships with the following configuration setting:\n\n```php\n# file /config/general.php\n...\n'omitScriptNameInUrls' =\u003e true,\n...\n```\n\nThat tells Craft to leave `index.php?p=` out of any URLs it generates. If server URL rewrites are not set up correctly, then Craft-generated links will be broken.\n\nCraft also ships with an `.htaccess` file in the `/web` directory that will rewrite URLs correctly for Apache as long as `mod_rewrite`  and `AllowOverride` are enabled.  Most local environment options are configured this way already.\n\nIf your links are still broken, don’t let it slow you down. Set the configuration setting like so:\n\n```php\n# file /config/general.php\n...\n'omitScriptNameInUrls' =\u003e false,\n...\n```\n\nURLs might not be pretty, but you can get to work!\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcraftcms%2Fstarter-blog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcraftcms%2Fstarter-blog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcraftcms%2Fstarter-blog/lists"}