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.0.15
Latest
4 days ago
-
- A plugin's blueprints can use the data providers that plugin ships again, instead of having every one of them refused by a check that only recognised the providers core itself registers (getgrav/grav-plugin-email#193). Fields defined in page frontmatter are held to the stricter rule instead, which is where the risk actually was.
- [security] A configuration admin can no longer reach an unvetted built-in routine by writing a blueprint field's data provider as a plain function name, a spelling that was still being checked against a list of known-bad names rather than the list of approved ones (GHSA-f8wv-xp27-6gq7).
- [security] The content security scan now reads an unpaired quote inside an unquoted attribute value the way a browser does, closing another way a page editor could hide a script from it (GHSA-vfmf-q6x9-cw96).
- [security] The media URL in an audio or video tag is now escaped, so a filename carrying markup can no longer add its own attributes to the player (GHSA-6qw9-4vv5-jr97).
- JSON responses no longer fail outright when the data contains invalid UTF-8.
json_encode()returnsfalseon malformed bytes, and the PSR-7 response body is type-hintedstring|resource|StreamInterface, so thatfalsecame back out as an unhandledTypeErrorfrom inside the vendor stream rather than as a response. AffectedcreateJsonResponse()and both JSON error responses inControllerResponseTrait, where an exception message carrying a bad byte would take out the error handler itself, plus the Clockwork data endpoint inDebugger. Bad bytes are now substituted, and the remaining structural failures (recursion depth,INF/NAN) raise a catchableJsonExceptioninstead of a silentfalse. Output for valid data is unchanged. - [security] The fast static asset server now keeps a request inside the directory the site published, instead of also allowing any neighbouring directory whose name starts with the same letters (GHSA-4v9q-p283-qc2m).
- [security] File uploads now reject a few more extensions that browsers run script from, or that a server may hand to PHP:
xhtml,xht,svgz,php7,php8,pht,phtmandphps(GHSA-66xf-ggf4-6hmc). - [security] The bundled
Caddyfileprotections did nothing. They were written as nginx-style regexes, which Caddy reads as literal paths that never match, and therespondthey redirected to ran after the catch-all rewrite had already claimed the request. A site served with this config handed outuser/accounts/,user/config/,logs/,composer.lock, page files, and thesystem/andvendor/folders to anyone who asked. The rules are now namedpath_regexpmatchers answering403directly, inside arouteblock so they run before the rewrite, and they were checked request by request against the.htaccessbehaviour.
v2.0.14 1 week ago
-
- Removed old JQuery
2.1.4. However2.2.4and3.7.1remain for legacy support
- Removed old JQuery
-
- [security] An administrator with account-management rights can no longer grant themselves super-admin access by saving it into a user group's permissions, a protection the account form already had (GHSA-xhfv-7758-r9hx).
- [security] The content security scan no longer reports a page as clean when it was unable to examine it, closing two ways a page editor could hide a script from it: a single invalid character anywhere in the content, and padding a tag out to several thousand characters (GHSA-q2j8-x8hf-63ch).
v2.0.13 2 weeks ago
-
- Added an
array_group_byTwig filter and function for grouping a list of items by one of their values (#4218).
- Added an
-
- [security] A configuration admin can no longer run code on the server by pointing a dynamic field's data provider at a built-in routine named as a class-and-method pair, a form that slipped past the safety check because it only inspected the single-string spelling; both forms are now vetted the same way (GHSA-r94f-hx44-8jqf).
- [security] A page editor without super-admin rights can no longer store an event-handler script that runs for site visitors by hiding it behind a
>placed inside a quoted HTML attribute; the content security scan now reads quoted attribute values the same way a browser does (GHSA-269c-h76q-8cxw). - [security] A backup profile's location is now confined to the site folder, so a profile pointing outside the Grav root can no longer pull external directories into the backup archive (GHSA-fch7-cpv4-w7hg).
- [security] Uploaded filenames may no longer contain the HTML characters
<,>, or", so a stored filename cannot carry markup that could run if it were later shown unescaped. - [security] The
findandsortTwig filters now reject a dangerous function name given as their callback, matching the protection already applied tomap,filter, andreduce, so template values cannot use them to run code (GHSA-xx48-97m4-h7qm). - The bundled
nginx.confsecurity rules are now anchored to the start of the path like the.htaccessrules already are, so the admin's Tools → Logs viewer works on nginx instead of being blocked (#4223). - On non-FastCGI setups Grav no longer sends an invalid
Content-Encoding: noneheader, which some strict HTTP clients rejected outright; it now closes the connection cleanly without the bogus value (#2619).
v2.0.12 3 weeks ago
-
- Added per-language fallbacks for unsupported browser languages during
HTTP_ACCEPT_LANGUAGEnegotiation, allowing them to resolve to supported languages without exposing additional language routes.
- Added per-language fallbacks for unsupported browser languages during
-
- The
read_file()Twig function can now read.cssfiles by default, so inline stylesheets can be embedded in a template without adjusting the security config (#4215). - Documented that the site-wide media object resolves lazily, so its inherited collection query methods need
media_directory()to filter or sort site media (#4210).
- The
-
- Browser language codes are now matched case-insensitively during
HTTP_ACCEPT_LANGUAGEfallback negotiation.
- Browser language codes are now matched case-insensitively during
v2.0.11 4 weeks ago
-
- You can now filter, sort, and group a page's media by the values in their
.meta.yamlmetafiles directly in Twig, with newfilterBy,where,findBy,sortBy,groupBy, andwithMetamethods onpage.media. Fixes getgrav/grav#4200.
- You can now filter, sort, and group a page's media by the values in their
-
- [security] A page editor can no longer read arbitrary files from the server by pointing an image watermark at a traversal path such as
carrier.png?watermark=../secret.png; an editor-supplied watermark path is now confined to the site's media, while operator-configured watermarks and stream URIs are unaffected (GHSA-w3f4-8pj2-599w). - [security] A page-edit account can no longer reach file-disclosure or secret-read functions by naming an arbitrary
Class::methodas a dynamic field's data provider; qualified providers are now limited to a known-safe allowlist, closing a bypass of the guard added in 2.0.7 and 2.0.9 (GHSA-7pgq-cr25-xvc8, GHSA-cxv3-5jj3-cpgr). - A page is no longer blanked when viewed just because a trusted plugin or shortcode on it outputs markup the content security scan flags, such as an embed, form, or icon; the check that guards against dangerous editor content now runs once when the page is saved rather than every time it is rendered (GHSA-2c4f-86xc-cr74).
- [security] A page editor can no longer read arbitrary files from the server by pointing an image watermark at a traversal path such as
-
- [security] Page content that uses Twig to assemble disallowed markup at render time, such as building an event handler or a
<script>tag from separate pieces, is now refused when you save the page instead of being allowed through to visitors. - The
rawTwig filter is no longer allowed inside editor-authored page content, so page content can no longer output unescaped dynamic values past the content security check; trusted theme templates are unaffected.
- [security] Page content that uses Twig to assemble disallowed markup at render time, such as building an event handler or a
v2.0.10 4 weeks ago
-
- A partial
system.pages.processoverride inuser/config/system.yaml(for example setting onlytwig: false) no longer silently turns off Markdown and leaves every page rendering its raw source. Becausepages.processis a single field in the blueprint, a partial override replaced the whole map and dropped the defaultmarkdown: true; core now re-applies that default, so an affected site recovers on update with no change to its config. An explicitmarkdown: falseis still honored.
- A partial
v2.0.15
Latest
4 days ago
-
- A plugin's blueprints can use the data providers that plugin ships again, instead of having every one of them refused by a check that only recognised the providers core itself registers (getgrav/grav-plugin-email#193). Fields defined in page frontmatter are held to the stricter rule instead, which is where the risk actually was.
- [security] A configuration admin can no longer reach an unvetted built-in routine by writing a blueprint field's data provider as a plain function name, a spelling that was still being checked against a list of known-bad names rather than the list of approved ones (GHSA-f8wv-xp27-6gq7).
- [security] The content security scan now reads an unpaired quote inside an unquoted attribute value the way a browser does, closing another way a page editor could hide a script from it (GHSA-vfmf-q6x9-cw96).
- [security] The media URL in an audio or video tag is now escaped, so a filename carrying markup can no longer add its own attributes to the player (GHSA-6qw9-4vv5-jr97).
- JSON responses no longer fail outright when the data contains invalid UTF-8.
json_encode()returnsfalseon malformed bytes, and the PSR-7 response body is type-hintedstring|resource|StreamInterface, so thatfalsecame back out as an unhandledTypeErrorfrom inside the vendor stream rather than as a response. AffectedcreateJsonResponse()and both JSON error responses inControllerResponseTrait, where an exception message carrying a bad byte would take out the error handler itself, plus the Clockwork data endpoint inDebugger. Bad bytes are now substituted, and the remaining structural failures (recursion depth,INF/NAN) raise a catchableJsonExceptioninstead of a silentfalse. Output for valid data is unchanged. - [security] The fast static asset server now keeps a request inside the directory the site published, instead of also allowing any neighbouring directory whose name starts with the same letters (GHSA-4v9q-p283-qc2m).
- [security] File uploads now reject a few more extensions that browsers run script from, or that a server may hand to PHP:
xhtml,xht,svgz,php7,php8,pht,phtmandphps(GHSA-66xf-ggf4-6hmc). - [security] The bundled
Caddyfileprotections did nothing. They were written as nginx-style regexes, which Caddy reads as literal paths that never match, and therespondthey redirected to ran after the catch-all rewrite had already claimed the request. A site served with this config handed outuser/accounts/,user/config/,logs/,composer.lock, page files, and thesystem/andvendor/folders to anyone who asked. The rules are now namedpath_regexpmatchers answering403directly, inside arouteblock so they run before the rewrite, and they were checked request by request against the.htaccessbehaviour.
v2.0.14 1 week ago
-
- Removed old JQuery
2.1.4. However2.2.4and3.7.1remain for legacy support
- Removed old JQuery
-
- [security] An administrator with account-management rights can no longer grant themselves super-admin access by saving it into a user group's permissions, a protection the account form already had (GHSA-xhfv-7758-r9hx).
- [security] The content security scan no longer reports a page as clean when it was unable to examine it, closing two ways a page editor could hide a script from it: a single invalid character anywhere in the content, and padding a tag out to several thousand characters (GHSA-q2j8-x8hf-63ch).
v2.0.13 2 weeks ago
-
- Added an
array_group_byTwig filter and function for grouping a list of items by one of their values (#4218).
- Added an
-
- [security] A configuration admin can no longer run code on the server by pointing a dynamic field's data provider at a built-in routine named as a class-and-method pair, a form that slipped past the safety check because it only inspected the single-string spelling; both forms are now vetted the same way (GHSA-r94f-hx44-8jqf).
- [security] A page editor without super-admin rights can no longer store an event-handler script that runs for site visitors by hiding it behind a
>placed inside a quoted HTML attribute; the content security scan now reads quoted attribute values the same way a browser does (GHSA-269c-h76q-8cxw). - [security] A backup profile's location is now confined to the site folder, so a profile pointing outside the Grav root can no longer pull external directories into the backup archive (GHSA-fch7-cpv4-w7hg).
- [security] Uploaded filenames may no longer contain the HTML characters
<,>, or", so a stored filename cannot carry markup that could run if it were later shown unescaped. - [security] The
findandsortTwig filters now reject a dangerous function name given as their callback, matching the protection already applied tomap,filter, andreduce, so template values cannot use them to run code (GHSA-xx48-97m4-h7qm). - The bundled
nginx.confsecurity rules are now anchored to the start of the path like the.htaccessrules already are, so the admin's Tools → Logs viewer works on nginx instead of being blocked (#4223). - On non-FastCGI setups Grav no longer sends an invalid
Content-Encoding: noneheader, which some strict HTTP clients rejected outright; it now closes the connection cleanly without the bogus value (#2619).
v2.0.12 3 weeks ago
-
- Added per-language fallbacks for unsupported browser languages during
HTTP_ACCEPT_LANGUAGEnegotiation, allowing them to resolve to supported languages without exposing additional language routes.
- Added per-language fallbacks for unsupported browser languages during
-
- The
read_file()Twig function can now read.cssfiles by default, so inline stylesheets can be embedded in a template without adjusting the security config (#4215). - Documented that the site-wide media object resolves lazily, so its inherited collection query methods need
media_directory()to filter or sort site media (#4210).
- The
-
- Browser language codes are now matched case-insensitively during
HTTP_ACCEPT_LANGUAGEfallback negotiation.
- Browser language codes are now matched case-insensitively during
v2.0.11 4 weeks ago
-
- You can now filter, sort, and group a page's media by the values in their
.meta.yamlmetafiles directly in Twig, with newfilterBy,where,findBy,sortBy,groupBy, andwithMetamethods onpage.media. Fixes getgrav/grav#4200.
- You can now filter, sort, and group a page's media by the values in their
-
- [security] A page editor can no longer read arbitrary files from the server by pointing an image watermark at a traversal path such as
carrier.png?watermark=../secret.png; an editor-supplied watermark path is now confined to the site's media, while operator-configured watermarks and stream URIs are unaffected (GHSA-w3f4-8pj2-599w). - [security] A page-edit account can no longer reach file-disclosure or secret-read functions by naming an arbitrary
Class::methodas a dynamic field's data provider; qualified providers are now limited to a known-safe allowlist, closing a bypass of the guard added in 2.0.7 and 2.0.9 (GHSA-7pgq-cr25-xvc8, GHSA-cxv3-5jj3-cpgr). - A page is no longer blanked when viewed just because a trusted plugin or shortcode on it outputs markup the content security scan flags, such as an embed, form, or icon; the check that guards against dangerous editor content now runs once when the page is saved rather than every time it is rendered (GHSA-2c4f-86xc-cr74).
- [security] A page editor can no longer read arbitrary files from the server by pointing an image watermark at a traversal path such as
-
- [security] Page content that uses Twig to assemble disallowed markup at render time, such as building an event handler or a
<script>tag from separate pieces, is now refused when you save the page instead of being allowed through to visitors. - The
rawTwig filter is no longer allowed inside editor-authored page content, so page content can no longer output unescaped dynamic values past the content security check; trusted theme templates are unaffected.
- [security] Page content that uses Twig to assemble disallowed markup at render time, such as building an event handler or a
v2.0.10 4 weeks ago
-
- A partial
system.pages.processoverride inuser/config/system.yaml(for example setting onlytwig: false) no longer silently turns off Markdown and leaves every page rendering its raw source. Becausepages.processis a single field in the blueprint, a partial override replaced the whole map and dropped the defaultmarkdown: true; core now re-applies that default, so an affected site recovers on update with no change to its config. An explicitmarkdown: falseis still honored.
- A partial