Downloads
Everything Grav
Download Grav
Grav Core is the base package with core functionality and a few essential starting pages. Grav Core + Admin also includes the Administration Panel plugin. Both are easy to get started with — check out our Basic Tutorial and Guide to the Administration Panel.
Latest stable release
Production-ready. The version we recommend for every new site and every upgrade of an existing one.
Get Started
1
Quick installation
- Download either the Grav Core or Grav Core + Admin2 plugin installation package.
- Extract the zip file into your webroot.
- Point your browser at your local webserver:
http://yoursite.com
2
How to install the Admin2 plugin
If you have not already installed the admin plugin, you can do so easily with GPM:
$
This will install the admin plugin plus its dependencies (api & login). After this is complete, point your browser to your Grav installation and you will be prompted to create a new admin user.
Changelog
v2.1.6
Latest
1 day ago
-
- A package that ships its own
.htaccesscan no longer opt out of the protections arounduser/. Those rules are pushed down into every folder beneathuser/and run first, which is what stops a plugin or theme from replacing them. A folder can still ask Apache to run them last and then stop before they are reached. That takes a deliberate line in the package's own file rather than the accidental case this guards against, but the protection Grav shipped before 2.1.4 held against it, so this restores that. A second set of rules now backs up the first using a different Apache module, one that a folder underneath cannot switch off. #4236
- A package that ships its own
-
- The compiled cache is written in one piece, so a busy site no longer logs
Corrupt compiled cachewarnings after an install or a cache clear. Every request includes the compiled copy of a YAML or markdown file without taking a lock, while the process rebuilding it truncated the file first and filled it afterwards. A request landing in between saw a syntax error, and since 2.0.20 each one wrote a warning tograv.log, which on a cold cache with the admin's parallel requests meant a burst of them for a problem that had already healed itself. The compiled file is now written next to its target and renamed over it, so a reader only ever sees a complete file. The warning stays for a file that really is broken, but no longer fires when another process is in the middle of writing it, and a corrupt file is reported once per request rather than once per read path. A compiled file that cannot be written is now a cache miss instead of a server error. user/dataanswers correctly on a restricted host too, on sites an earlier update had put beyond the reach of 2.1.5's repair. An update in June widened that folder's file in place rather than replacing it, which produced two versions that exist only on disk — in no release and in no checkout — so the sweep behind 2.1.5 could not find them to list. A site carrying either one kept the directive that returns a server error for the whole folder on a host with a restrictedAllowOverride, which is every image and file uploaded touser/data. Both are now recognised and replaced. #4311- A number field accepts every value that sits on its step, instead of refusing some of them. Checking a value against a step was done in binary floating point, where a decimal like
0.0000001has no exact representation, so a perfectly valid entry could be rejected with no way for the person filling the form to tell why — a latitude of81.96on a field stepping by0.0000001was refused. The check is now done on the digits as typed, which has an exact answer. Thanks @TheoAcker12 #3585 - A number, range or select field no longer takes the site down when its step is
any, zero, or not a number.anyis the standard way to say a field has no step at all, and it was being read as zero and then divided by, which is a fatal error rather than a failed validation — the same for a step left empty or set to something that is not a number. Multi-value select and checkbox fields had the same fault a few lines away. All of them now treat a step that is not a positive number as no step, which is what browsers do. Thanks @sridharkalaibala #4308 - The last folder under
user/that could answer with a server error on a host with a restrictedAllowOverridenow answers correctly. 2.1.5 fixed the four files Grav ships, but a site with auser/envfolder also has a file there that an earlier update wrote, and Grav has never shipped that one — so it kept the directive the rest were moved off. Nothing is served from that folder, so no site was broken by it; it is a stray error page where a "forbidden" belongs. An upgrade replaces the file if it is the one Grav wrote, and leaves a file you edited alone. #4311
- The compiled cache is written in one piece, so a busy site no longer logs
v2.1.5 3 days ago
-
- Avatars and files uploaded to
user/dataare served again, and the rest of theuser/.htaccessfix from 2.1.4 now reaches the folders it missed. 2.1.4 restated the site root's folder blocks without the two exceptions the root makes, so profile avatars and Flex Object image uploads came back as "forbidden" on Apache. The separate files inuser/accounts,user/configanduser/dataalso still used the directive that takes a site offline on a host with a restrictedAllowOverride, so those three folders kept failing where 2.1.4 had fixed the rest. All four files now work the same way, and an upgrade replaces any of them a previous Grav wrote — a file you edited yourself is left alone. Thanks @onetrev #4311 - A premium package covered by a licence you already hold now installs, instead of being refused as unlicensed. A store can sell one licence that carries several packages — a shop plugin whose payment providers come with it, say — and the repository entry says so with
premium.license_product. The download proxy has always honoured that, but GPM only ever looked for a key filed under the package's own name, so a customer holding one key had to paste it once per package, andbin/gpm installfailed on every package they had not pasted it against. The key filed under the product a package belongs to now counts for that package, and a key filed under the package's own name still wins wherever there is one.
- Avatars and files uploaded to
v2.1.4 3 days ago
-
- Sites on hosts with a restricted
AllowOverrideare no longer taken offline by theuser/.htaccessfile added in 2.0.19. That file used an Apache directive many shared hosts do not permit in.htaccess, and where it was not permitted Apache returned an error for everything insideuser/— so the admin went blank, the theme's styles and scripts stopped loading, and the front end broke too. It kept happening after a rollback, because rolling back Grav never replacesuser/. The file now does the same job with directives every host running Grav already allows. Thanks @elanorpam #4309
- Sites on hosts with a restricted
v2.1.3 4 days ago
-
- Asking a template for an image caption or credit that was never set no longer changes the image address. Reading a
.meta.yamlfield that is missing, such as{{ image.copyright }}, added the field name to the end of the image URL for every visitor instead of simply returning nothing. Thanks @phmg701 #4301 - The debug bar is back on pages that swap in a different page while the request runs. A form that failed validation, or an error page served by the Error plugin, rendered without the bar because Grav no longer recognised the replacement page as one it had already loaded. Thanks @hughbris #4300
- The Clockwork debug badge now appears when the JavaScript pipeline is enabled. Its script was being merged into the combined file, which dropped the attributes it needs to find itself. Thanks @wakqasahmed #3871
- AVIF images now honour the quality setting when the Imagick adapter is in use. The value was being written to a field the AVIF encoder never reads, so every AVIF came out at the encoder's own default regardless of the setting. Thanks @sridharkalaibala and @Rotzbua #4059
- Saving a page or a Flex object no longer fails with
Invalid input in "Date"on a date the author never touched. Adate:written the ordinary unquoted way comes back out of YAML as a number, and the date validator only accepted text, so editing any other field and saving was refused outright in Admin Next and through the API. Classic admin was never affected because it reformatted the date before submitting it #4304
- Asking a template for an image caption or credit that was never set no longer changes the image address. Reading a
v2.1.2 6 days ago
-
- Updating a 2.0 site to 2.1 from Admin2 no longer fails. The check that runs before an update still treated a minor release as a major one, so it refused the update unless every enabled plugin and theme listed Grav 2.1 as compatible, which almost none do yet. From 2.0 on those checks only run for a new major version #4299
bin/gpm updateno longer calls a 2.0 to 2.1 update a new major version
v2.1.1 6 days ago
-
- Grav 2.0 sites can update to 2.1.
bin/gpm selfupgradetreated each minor release as a separate line, the way 1.7 and 1.8 were, so a 2.0 site was told it was up to date while 2.1.0 was out. Only a new major version now needs a manual move #4299 - When a new major version of Grav is out,
bin/gpm selfupgradesays so and links to the migration guide instead of only reporting that the site is up to date
- Grav 2.0 sites can update to 2.1.
v2.1.6
Latest
1 day ago
-
- A package that ships its own
.htaccesscan no longer opt out of the protections arounduser/. Those rules are pushed down into every folder beneathuser/and run first, which is what stops a plugin or theme from replacing them. A folder can still ask Apache to run them last and then stop before they are reached. That takes a deliberate line in the package's own file rather than the accidental case this guards against, but the protection Grav shipped before 2.1.4 held against it, so this restores that. A second set of rules now backs up the first using a different Apache module, one that a folder underneath cannot switch off. #4236
- A package that ships its own
-
- The compiled cache is written in one piece, so a busy site no longer logs
Corrupt compiled cachewarnings after an install or a cache clear. Every request includes the compiled copy of a YAML or markdown file without taking a lock, while the process rebuilding it truncated the file first and filled it afterwards. A request landing in between saw a syntax error, and since 2.0.20 each one wrote a warning tograv.log, which on a cold cache with the admin's parallel requests meant a burst of them for a problem that had already healed itself. The compiled file is now written next to its target and renamed over it, so a reader only ever sees a complete file. The warning stays for a file that really is broken, but no longer fires when another process is in the middle of writing it, and a corrupt file is reported once per request rather than once per read path. A compiled file that cannot be written is now a cache miss instead of a server error. user/dataanswers correctly on a restricted host too, on sites an earlier update had put beyond the reach of 2.1.5's repair. An update in June widened that folder's file in place rather than replacing it, which produced two versions that exist only on disk — in no release and in no checkout — so the sweep behind 2.1.5 could not find them to list. A site carrying either one kept the directive that returns a server error for the whole folder on a host with a restrictedAllowOverride, which is every image and file uploaded touser/data. Both are now recognised and replaced. #4311- A number field accepts every value that sits on its step, instead of refusing some of them. Checking a value against a step was done in binary floating point, where a decimal like
0.0000001has no exact representation, so a perfectly valid entry could be rejected with no way for the person filling the form to tell why — a latitude of81.96on a field stepping by0.0000001was refused. The check is now done on the digits as typed, which has an exact answer. Thanks @TheoAcker12 #3585 - A number, range or select field no longer takes the site down when its step is
any, zero, or not a number.anyis the standard way to say a field has no step at all, and it was being read as zero and then divided by, which is a fatal error rather than a failed validation — the same for a step left empty or set to something that is not a number. Multi-value select and checkbox fields had the same fault a few lines away. All of them now treat a step that is not a positive number as no step, which is what browsers do. Thanks @sridharkalaibala #4308 - The last folder under
user/that could answer with a server error on a host with a restrictedAllowOverridenow answers correctly. 2.1.5 fixed the four files Grav ships, but a site with auser/envfolder also has a file there that an earlier update wrote, and Grav has never shipped that one — so it kept the directive the rest were moved off. Nothing is served from that folder, so no site was broken by it; it is a stray error page where a "forbidden" belongs. An upgrade replaces the file if it is the one Grav wrote, and leaves a file you edited alone. #4311
- The compiled cache is written in one piece, so a busy site no longer logs
v2.1.5 3 days ago
-
- Avatars and files uploaded to
user/dataare served again, and the rest of theuser/.htaccessfix from 2.1.4 now reaches the folders it missed. 2.1.4 restated the site root's folder blocks without the two exceptions the root makes, so profile avatars and Flex Object image uploads came back as "forbidden" on Apache. The separate files inuser/accounts,user/configanduser/dataalso still used the directive that takes a site offline on a host with a restrictedAllowOverride, so those three folders kept failing where 2.1.4 had fixed the rest. All four files now work the same way, and an upgrade replaces any of them a previous Grav wrote — a file you edited yourself is left alone. Thanks @onetrev #4311 - A premium package covered by a licence you already hold now installs, instead of being refused as unlicensed. A store can sell one licence that carries several packages — a shop plugin whose payment providers come with it, say — and the repository entry says so with
premium.license_product. The download proxy has always honoured that, but GPM only ever looked for a key filed under the package's own name, so a customer holding one key had to paste it once per package, andbin/gpm installfailed on every package they had not pasted it against. The key filed under the product a package belongs to now counts for that package, and a key filed under the package's own name still wins wherever there is one.
- Avatars and files uploaded to
v2.1.4 3 days ago
-
- Sites on hosts with a restricted
AllowOverrideare no longer taken offline by theuser/.htaccessfile added in 2.0.19. That file used an Apache directive many shared hosts do not permit in.htaccess, and where it was not permitted Apache returned an error for everything insideuser/— so the admin went blank, the theme's styles and scripts stopped loading, and the front end broke too. It kept happening after a rollback, because rolling back Grav never replacesuser/. The file now does the same job with directives every host running Grav already allows. Thanks @elanorpam #4309
- Sites on hosts with a restricted
v2.1.3 4 days ago
-
- Asking a template for an image caption or credit that was never set no longer changes the image address. Reading a
.meta.yamlfield that is missing, such as{{ image.copyright }}, added the field name to the end of the image URL for every visitor instead of simply returning nothing. Thanks @phmg701 #4301 - The debug bar is back on pages that swap in a different page while the request runs. A form that failed validation, or an error page served by the Error plugin, rendered without the bar because Grav no longer recognised the replacement page as one it had already loaded. Thanks @hughbris #4300
- The Clockwork debug badge now appears when the JavaScript pipeline is enabled. Its script was being merged into the combined file, which dropped the attributes it needs to find itself. Thanks @wakqasahmed #3871
- AVIF images now honour the quality setting when the Imagick adapter is in use. The value was being written to a field the AVIF encoder never reads, so every AVIF came out at the encoder's own default regardless of the setting. Thanks @sridharkalaibala and @Rotzbua #4059
- Saving a page or a Flex object no longer fails with
Invalid input in "Date"on a date the author never touched. Adate:written the ordinary unquoted way comes back out of YAML as a number, and the date validator only accepted text, so editing any other field and saving was refused outright in Admin Next and through the API. Classic admin was never affected because it reformatted the date before submitting it #4304
- Asking a template for an image caption or credit that was never set no longer changes the image address. Reading a
v2.1.2 6 days ago
-
- Updating a 2.0 site to 2.1 from Admin2 no longer fails. The check that runs before an update still treated a minor release as a major one, so it refused the update unless every enabled plugin and theme listed Grav 2.1 as compatible, which almost none do yet. From 2.0 on those checks only run for a new major version #4299
bin/gpm updateno longer calls a 2.0 to 2.1 update a new major version
v2.1.1 6 days ago
-
- Grav 2.0 sites can update to 2.1.
bin/gpm selfupgradetreated each minor release as a separate line, the way 1.7 and 1.8 were, so a 2.0 site was told it was up to date while 2.1.0 was out. Only a new major version now needs a manual move #4299 - When a new major version of Grav is out,
bin/gpm selfupgradesays so and links to the migration guide instead of only reporting that the site is up to date
- Grav 2.0 sites can update to 2.1.