diff --git a/README.md b/README.md index 04240463..477a623d 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ This repository is dedicated to exploring how WordPress themes can best leverage | Theme | Updated For | | --- | --- | | [Ambitious](https://github.com/WordPress/theme-experiments/tree/master/ambitious) | Gutenberg 7.6 | +| [Empty Theme](https://github.com/WordPress/theme-experiments/tree/master/emptytheme) | Gutenberg 9.5 | | [Gutenberg Starter Theme Blocks](https://github.com/WordPress/theme-experiments/tree/master/gutenberg-starter-theme-blocks) | Gutenberg 8.6 | | [Twenty Nineteen Blocks](https://github.com/WordPress/theme-experiments/tree/master/twentynineteen-blocks) | Gutenberg 8.6 | | [Twenty Twenty Blocks](https://github.com/WordPress/theme-experiments/tree/master/twentytwenty-blocks) | Gutenberg 8.6 | @@ -45,6 +46,12 @@ Here are some resources that may be useful context for learning more about block - [Full site editing development in the Gutenberg repo](https://github.com/WordPress/gutenberg/labels/%5BFeature%5D%20Full%20Site%20Editing) - [Global styles development in the Gutenberg repo](https://github.com/WordPress/gutenberg/issues?q=is%3Aissue+is%3Aopen+label%3A%22Global+Styles%22) +## Generating your own starter theme + +We have included a script so you can generate a theme based on a starter boilerplate with the minimum necessary to build your own block-based theme. You will need to have php installed to run it using: + +`php new-empty-theme.php` + ## Questions or Improvements? If you'd like to propose improvements to this repository, feel free to open an [issue](https://github.com/WordPress/theme-experiments/issues) or [PR](https://github.com/WordPress/theme-experiments/pulls). diff --git a/emptytheme/assets/alignments-front.css b/emptytheme/assets/alignments-front.css new file mode 100644 index 00000000..9867ab1f --- /dev/null +++ b/emptytheme/assets/alignments-front.css @@ -0,0 +1,79 @@ +/* + * Alignments, loaded in the front-end only. + */ + +body { + margin: 0; +} + +* { + box-sizing: border-box; +} + +.wp-site-blocks, +.wp-block-template-part.alignfull { + padding: 0 var(--wp--custom--margin--horizontal); +} + +.wp-site-blocks > *:not(.wp-block-post-content), +.wp-site-blocks .wp-block-post-content > * { + max-width: var(--wp--custom--width--default); + margin-left: auto; + margin-right: auto; +} + +.wp-site-blocks .alignwide { + width: var(--wp--custom--width--wide); + max-width: 100%; + margin-left: auto; + margin-right: auto; +} + +.wp-site-blocks .alignfull { + transform: translateX(calc(0px - var(--wp--custom--margin--horizontal))); + width: calc(100% + (2 * var(--wp--custom--margin--horizontal))); + max-width: calc(100% + (2 * var(--wp--custom--margin--horizontal))); + margin-left: 0; + margin-right: 0; + box-sizing: content-box; +} + +.wp-site-blocks .wp-block-template-part.alignfull { + width: 100%; + max-width: 100%; +} + +.wp-site-blocks .wp-block-columns.alignfull { + width: 100%; + max-width: 100%; +} + +.aligncenter { + text-align: center; +} + +.wp-site-blocks .alignleft { + float: left; + margin-right: 2em; + max-width: 360px; +} + +.wp-site-blocks .alignright { + float: right; + margin-left: 2em; + max-width: 360px; +} + +@media screen and (min-width: 1290px) { + + .wp-site-blocks, + .wp-block-template-part.alignfull { + padding: 0; + } + + .wp-site-blocks .alignfull { + transform: translateX(0px); + width: 100% + var(--wp--custom--margin--horizontal)); + max-width: calc(100% + var(--wp--custom--margin--horizontal)); + } +} \ No newline at end of file diff --git a/emptytheme/block-template-parts/header.html b/emptytheme/block-template-parts/header.html new file mode 100644 index 00000000..388c2232 --- /dev/null +++ b/emptytheme/block-template-parts/header.html @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/emptytheme/block-templates/index.html b/emptytheme/block-templates/index.html new file mode 100644 index 00000000..591f9012 --- /dev/null +++ b/emptytheme/block-templates/index.html @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/emptytheme/block-templates/singular.html b/emptytheme/block-templates/singular.html new file mode 100644 index 00000000..69eef0a7 --- /dev/null +++ b/emptytheme/block-templates/singular.html @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/emptytheme/experimental-theme.json b/emptytheme/experimental-theme.json new file mode 100644 index 00000000..eeeadfda --- /dev/null +++ b/emptytheme/experimental-theme.json @@ -0,0 +1,32 @@ +{ + "global": { + "settings": { + "color": { + "gradients": [ ], + "link": true, + "palette": [ ] + }, + "typography": { + "customLineHeight": true, + "fontFamilies": [ ], + "fontSizes": [ ], + "spacing": { + "customPadding": true + } + }, + "custom": { + "width": { + "default": "840px", + "wide": "1100px" + }, + "margin": { + "horizontal": "14px" + } + } + }, + "styles": { + "color": { }, + "typography": { } + } + } +} diff --git a/emptytheme/functions.php b/emptytheme/functions.php new file mode 100644 index 00000000..d47a7c3b --- /dev/null +++ b/emptytheme/functions.php @@ -0,0 +1,38 @@ +get( 'Version' ) ); + + // Enqueue alignments stylesheet. + wp_enqueue_style( 'emptytheme-alignments-style', get_template_directory_uri() . '/assets/alignments-front.css', array(), wp_get_theme()->get( 'Version' ) ); +} +add_action( 'wp_enqueue_scripts', 'emptytheme_scripts' ); diff --git a/emptytheme/index.php b/emptytheme/index.php new file mode 100644 index 00000000..e69de29b diff --git a/emptytheme/style.css b/emptytheme/style.css new file mode 100644 index 00000000..dbdb11f3 --- /dev/null +++ b/emptytheme/style.css @@ -0,0 +1,15 @@ +/* +Theme Name: Empty Theme +Theme URI: https://github.com/wordpress/theme-experiments/ +Author: Kjell Reigstad +Description: The base for a block-based theme. +Requires at least: 5.3 +Tested up to: 5.5 +Requires PHP: 5.6 +Version: 1.0 +License: GNU General Public License v2 or later +License URI: LICENSE +Text Domain: emptytheme + +Empty Theme is distributed under the terms of the GNU GPL. +*/ diff --git a/new-empty-theme.php b/new-empty-theme.php new file mode 100644 index 00000000..54a60682 --- /dev/null +++ b/new-empty-theme.php @@ -0,0 +1,202 @@ +theme = array( + 'name' => $this->old_themename, + 'slug' => $this->old_themeslug, + 'uri' => 'https://github.com/wordpress/theme-experiments/', + 'author' => 'Kjell Reigstad', + 'description' => 'The base for a block-based theme.', + ); + $this->get_theme_info(); + $this->create_folder(); + } + + function get_theme_info() { + + echo "Please provide the following information: "; + echo "\n"; + echo "Theme name: "; + $input = fopen ("php://stdin","r"); + $this->theme['name'] = trim(fgets($input)); + if($this->theme['name'] === ''){ + echo "ABORTING!\n"; + exit; + } + $this->theme['slug'] = $this->sanitize_title_with_dashes($this->theme['name']); + $this->theme['functions_slug'] = str_replace( '-', '_', $this->theme['slug'] ); + + echo "Description: "; + $input = fopen ("php://stdin","r"); + $this->theme['description'] = trim(fgets($input)); + + echo "Author: "; + $input = fopen ("php://stdin","r"); + $this->theme['author'] = trim(fgets($input)); + + echo "Theme URI: "; + $input = fopen ("php://stdin","r"); + $this->theme['uri'] = trim(fgets($input)); + } + + function create_folder() { + + $dir = $this->theme['slug']; + + if( is_dir($dir) === false ) { + + mkdir($dir); + $prototype_dir = $this->old_themeslug . '/'; + $exclude_files = array( '.travis.yml', 'codesniffer.ruleset.xml', '.jscsrc', '.jshintignore', 'CONTRIBUTING.md', '.git', '.svn', '.DS_Store', '.gitignore', '.', '..' ); + $exclude_directories = array( '.git', '.svn', '.github', '.', '..' ); + + foreach ( $iterator = new \RecursiveIteratorIterator( new \RecursiveDirectoryIterator($prototype_dir, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST) as $item ) { + if ( in_array( $iterator->getSubPathName(), $exclude_files ) || in_array( $iterator->getSubPathName(), $exclude_directories ) ){ + continue; + } + + if ($item->isDir()) { + mkdir($dir . DIRECTORY_SEPARATOR . $iterator->getSubPathName()); + } else { + $contents = file_get_contents( $prototype_dir . $iterator->getSubPathName() ); + $file = fopen( $dir . '/' . $iterator->getSubPathName(),"w" ); + fwrite( $file, $this->replace_theme_name($contents, $iterator->getSubPathName()) ); + fclose( $file ); + } + } + echo "\n"; + echo "Your new theme is ready!\n"; + } else { + echo "\n"; + echo "This theme already exists\n"; + } + } + + function replace_theme_name($contents, $filename) { + + // Replace only text files, skip png's and other stuff. + $valid_extensions = array( 'php', 'css', 'scss', 'js', 'txt' ); + $valid_extensions_regex = implode( '|', $valid_extensions ); + if ( ! preg_match( "/\.({$valid_extensions_regex})$/", $filename ) ) + return $contents; + + // Special treatment for style.css + if ( 'style.css' === $filename ) { + $theme_headers = array( + 'Theme Name' => $this->theme['name'], + 'Text Domain' => $this->theme['slug'], + 'Theme URI' => $this->theme['uri'], + 'Description' => $this->theme['description'], + 'Author' => $this->theme['author'], + ); + + foreach ( $theme_headers as $key => $value ) { + $contents = preg_replace( '/(' . preg_quote( $key ) . ':)\s?(.+)/', '\\1 ' . $value, $contents ); + } + + $contents = str_replace( $this->old_themename, $this->theme['name'], $contents ); + return $contents; + } + + // Special treatment for functions.php + if ( 'functions.php' === $filename ) { + $contents = str_replace( $this->old_themeslug, $this->theme['functions_slug'], $contents ); + return $contents; + } + + return $contents; + } + + function sanitize_title_with_dashes( $title, $raw_title = '', $context = 'display' ) { + $title = strip_tags( $title ); + // Preserve escaped octets. + $title = preg_replace( '|%([a-fA-F0-9][a-fA-F0-9])|', '---$1---', $title ); + // Remove percent signs that are not part of an octet. + $title = str_replace( '%', '', $title ); + // Restore octets. + $title = preg_replace( '|---([a-fA-F0-9][a-fA-F0-9])---|', '%$1', $title ); + + $title = strtolower( $title ); + + if ( 'save' === $context ) { + // Convert  , &ndash, and &mdash to hyphens. + $title = str_replace( array( '%c2%a0', '%e2%80%93', '%e2%80%94' ), '-', $title ); + // Convert  , &ndash, and &mdash HTML entities to hyphens. + $title = str_replace( array( ' ', ' ', '–', '–', '—', '—' ), '-', $title ); + // Convert forward slash to hyphen. + $title = str_replace( '/', '-', $title ); + + // Strip these characters entirely. + $title = str_replace( + array( + // Soft hyphens. + '%c2%ad', + // ¡ and ¿. + '%c2%a1', + '%c2%bf', + // Angle quotes. + '%c2%ab', + '%c2%bb', + '%e2%80%b9', + '%e2%80%ba', + // Curly quotes. + '%e2%80%98', + '%e2%80%99', + '%e2%80%9c', + '%e2%80%9d', + '%e2%80%9a', + '%e2%80%9b', + '%e2%80%9e', + '%e2%80%9f', + // Bullet. + '%e2%80%a2', + // ©, ®, °, &hellip, and &trade. + '%c2%a9', + '%c2%ae', + '%c2%b0', + '%e2%80%a6', + '%e2%84%a2', + // Acute accents. + '%c2%b4', + '%cb%8a', + '%cc%81', + '%cd%81', + // Grave accent, macron, caron. + '%cc%80', + '%cc%84', + '%cc%8c', + ), + '', + $title + ); + + // Convert × to 'x'. + $title = str_replace( '%c3%97', 'x', $title ); + } + + // Kill entities. + $title = preg_replace( '/&.+?;/', '', $title ); + $title = str_replace( '.', '-', $title ); + + $title = preg_replace( '/[^%a-z0-9 _-]/', '', $title ); + $title = preg_replace( '/\s+/', '-', $title ); + $title = preg_replace( '|-+|', '-', $title ); + $title = trim( $title, '-' ); + + return $title; + } +} + +new Generate_Theme; +?> \ No newline at end of file