master
sephger 2024-04-15 16:00:49 +02:00
commit 45e66ab3a0
2143 changed files with 224562 additions and 0 deletions

21
.editorconfig 100644
View File

@ -0,0 +1,21 @@
# This file is for unifying the coding style for different editors and IDEs
# https://editorconfig.org/
# WordPress Coding Standards
# https://make.wordpress.org/core/handbook/coding-standards/
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = tab
[*.yml]
indent_style = space
indent_size = 2
[*.md]
trim_trailing_whitespace = false

57
.eslintrc 100644
View File

@ -0,0 +1,57 @@
{
"root": true,
"ignorePatterns": [
"*.min.js"
],
"overrides": [
{
"files": [
"*.js"
],
"extends": [
"eslint:recommended",
"prettier"
],
"env": {
"browser": true
},
"parserOptions": {
"ecmaVersion": "latest"
}
},
{
"files": [
"*.php"
],
"parser": "@angular-eslint/template-parser",
"plugins": [
"php-markup",
"tailwindcss"
],
"extends": [
"plugin:tailwindcss/recommended"
],
"rules": {
"tailwindcss/migration-from-tailwind-2": "off",
"tailwindcss/no-custom-classname": [
"warn",
{
"config": "./tailwind/tailwind.config.js",
"whitelist": [
"(page|entry|comment)\\-([-a-z]*)",
"vcard"
]
}
]
},
"settings": {
"tailwindcss": {
"config": "./tailwind/tailwind.config.js",
"cssFiles": [
"./theme/**/*.css"
]
}
}
}
]
}

17
.gitignore vendored 100644
View File

@ -0,0 +1,17 @@
# Ignore dependencies from npm and Composer:
/node_modules
/vendor
# Ignore generated JavaScript files:
*.min.js
# Ignore generated CSS files:
style.css
style-editor.css
style-editor-extra.css
# Ignore the generated zip file:
wowpress.zip
# Ignore .DS_Store files from macOS:
.DS_Store

10
.prettierignore 100644
View File

@ -0,0 +1,10 @@
# Ignore all files:
*.*
# Negate the above pattern for CSS files in the `tailwind` folder and for
# all JavaScript files:
!tailwind/**/*.css
!*.js
# Ignore minified JavaScript:
*.min.js

339
LICENSE 100644
View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{description}
Copyright (C) {year} {fullname}
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

55
README.md 100644
View File

@ -0,0 +1,55 @@
WowPress
========
A custom theme based on \_tw
## Quickstart
### Installation
1. Move this folder to `wp-content/themes` in your local development environment
2. Run `npm install && npm run dev` in this folder
3. Activate this theme in WordPress
### Development
4. Run `npm run watch`
5. Add [Tailwind utility classes](https://tailwindcss.com/docs/utility-first) with abandon
### Deployment
6. Run `npm run bundle`
7. Upload the resulting zip file to your site using the “Upload Theme” button on the “Add Themes” administration page
Or [deploy with the tool of your choice](https://underscoretw.com/docs/deployment/#h-other-deployment-options)!
## Full Documentation
### Fundamentals
* [Installation](https://underscoretw.com/docs/installation/)
Generate your custom theme, install it in WordPress and run your first Tailwind builds
* [Development](https://underscoretw.com/docs/development/)
Watch for changes, build for production and learn more about how _tw, WordPress and Tailwind work together
* [Deployment](https://underscoretw.com/docs/deployment/)
Share your new WordPress theme with the world
* [Troubleshooting](https://underscoretw.com/docs/troubleshooting/)
Find solutions to potential issues and answers to frequently asked questions
### In Depth
* [Using Tailwind Typography](https://underscoretw.com/docs/tailwind-typography/)
Customize front-end and back-end typographic styles
* [JavaScript Bundling with esbuild](https://underscoretw.com/docs/esbuild/)
Install and bundle JavaScript libraries (very quickly)
* [Linting and Code Formatting](https://underscoretw.com/docs/linting-code-formatting/)
Catch bugs and stop thinking about formatting
### Extras
* [On Tailwind and WordPress](https://underscoretw.com/docs/wordpress-tailwind/)
Understand how WordPress and Tailwind work together
* [Managing Styles for Custom Blocks](https://underscoretw.com/docs/custom-blocks/)
Learn strategies for using Tailwind in theme-specific custom blocks
* [Setting Up Browsersync](https://underscoretw.com/docs/browsersync/)
Add live reloads and synchronized cross-device testing to your workflow

25
composer.json 100644
View File

@ -0,0 +1,25 @@
{
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^1.0",
"phpcompatibility/phpcompatibility-wp": "^2.1",
"sirbrillig/phpcs-changed": "^2.11",
"sirbrillig/phpcs-variable-analysis": "^2.11",
"wp-cli/i18n-command": "^2.5",
"wp-coding-standards/wpcs": "^3.0"
},
"scripts": {
"php:lint": "vendor/bin/phpcs -p -s",
"php:lint:errors": "vendor/bin/phpcs -p -s --runtime-set ignore_warnings_on_exit 1",
"php:lint:autofix": "vendor/bin/phpcbf",
"php:lint:changed": "vendor/bin/phpcs-changed --git --git-unstaged",
"make-pot": "wp i18n make-pot . theme/languages/wowpress.pot"
},
"config": {
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
},
"require": {
"wenprise/eloquent": "^9.0"
}
}

3260
composer.lock generated 100644

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
{
"parserOptions": {
"sourceType": "module"
}
}

View File

@ -0,0 +1,33 @@
/* global wp */
/**
* Block editor modifications
*
* This file is loaded only by the block editor. Use it to modify the block
* editor via its APIs.
*
* The JavaScript code you place here will be processed by esbuild, and the
* output file will be created at `../theme/js/block-editor.min.js` and
* enqueued in `../theme/functions.php`.
*
* For esbuild documentation, please see:
* https://esbuild.github.io/
*/
wp.domReady(() => {
/**
* Add support for Tailwind Typographys `lead` class via a block style.
*/
wp.blocks.registerBlockStyle('core/paragraph', {
name: 'lead',
label: 'Lead',
});
// Add additional block editor modifications here. For example, you could
// register another block style:
//
// wp.blocks.registerBlockStyle( 'core/quote', {
// name: 'fancy-quote',
// label: 'Fancy Quote',
// } );
});

View File

@ -0,0 +1,10 @@
/**
* Front-end JavaScript
*
* The JavaScript code you place here will be processed by esbuild. The output
* file will be created at `../theme/js/script.min.js` and enqueued in
* `../theme/functions.php`.
*
* For esbuild documentation, please see:
* https://esbuild.github.io/
*/

View File

@ -0,0 +1,121 @@
/* global wp, tailwindTypographyClasses */
/**
* Tailwind Typography support from _tw
*
* The code below adds your front-end post title and Tailwind Typography
* classes to the block editor. It also adds some helper classes so you can
* access the post type when modifying the block editors appearance.
*
* You should not edit this file. If you would like to use JavaScript to
* modify the block editor, please use the `block-editor.js` file instead.
*
* The JavaScript code you place here will be processed by esbuild. The output
* file will be created at `../theme/js/tailwind-typography-classes.min.js` and
* enqueued in `../theme/functions.php`.
*
* For esbuild documentation, please see:
* https://esbuild.github.io/
*/
// Set our target classes and the classes well add to them.
var targetClasses = {
'edit-post-visual-editor__post-title-wrapper': ['entry-header'],
'wp-block-post-title': ['entry-title'],
'wp-block-post-content': ['entry-content', ...tailwindTypographyClasses],
};
wp.domReady(() => {
// Add the necessary Tailwind Typography classes to the block editor.
addTypographyClasses();
});
/**
* Get the class for the current post type from the `body` element. (We would
* use `wp.data`, but it doesn't work reliably both inside and outside of the
* post editor `iframe`.)
*/
function getCurrentPostTypeClass() {
let currentClass = null;
for (const classToCheck of document.body.classList) {
if (classToCheck.startsWith('post-type-')) {
currentClass = classToCheck;
break;
}
}
return currentClass;
}
/**
* Because Gutenbergs `isEditorReady` function remains unstable,
* well use an interval to watch for the arrival of the elements we need.
*/
function addTypographyClasses() {
const editorLoadedInterval = setInterval(function () {
// Wait until elements with all target classes are present.
if (
Object.keys(targetClasses).every(
(className) => document.getElementsByClassName(className).length
)
) {
if (getCurrentPostTypeClass()) {
// Add the post type class throughout.
Object.values(targetClasses).forEach((className) =>
className.push(getCurrentPostTypeClass())
);
}
// Add the classes before creating the mutation observer.
Object.entries(targetClasses).forEach(([targetClass, classes]) => {
document
.getElementsByClassName(targetClass)[0]
.classList.add(...classes);
});
// Add mutation observers to each element.
Object.keys(targetClasses).forEach((className) => {
mutationObserver.observe(
document.querySelector('.' + className),
{
attributes: true,
attributeFilter: ['class'],
}
);
});
// Stop the interval.
clearInterval(editorLoadedInterval);
} else if (document.getElementsByName('editor-canvas').length) {
// If the block editor has been loaded in an iframe, and this code
// is running outside of that iframe, stop the interval. (This code
// will run again inside the iframe.)
clearInterval(editorLoadedInterval);
}
}, 40);
}
/**
* We need to ensure the class names we add are added again if the React
* component is updated, removing them in the process. The mutation observer
* below will check for the needed classes and add them if theyve been
* removed.
*/
const mutationObserver = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
const classList = mutation.target.classList;
Object.entries(targetClasses).forEach(([targetClass, classes]) => {
if (classList.contains(targetClass)) {
// Check whether all added classes are present.
if (
!classes.every((className) => classList.contains(className))
) {
// Add them again if theyre not.
classList.add(...classes);
}
}
});
});
});

View File

@ -0,0 +1,11 @@
{
"parserOptions": {
"ecmaVersion": 2018
},
"env": {
"node": true
},
"rules": {
"no-console": "off"
}
}

View File

@ -0,0 +1,90 @@
#!/usr/bin/env node
/*
* Based upon the Archiver quickstart.
* @see: https://www.archiverjs.com/docs/quickstart
*/
// Require modules.
const AdmZip = require('adm-zip');
const archiver = require('archiver');
const fs = require('fs');
const args = process.argv.slice(2);
const slug = args[0];
if (slug) {
// Set the path for the ZIP file.
const zipFilePath = __dirname + '/../' + slug + '.zip';
// Create a file to stream archive data to.
const output = fs.createWriteStream(zipFilePath);
const archive = archiver('zip');
// Listen for all archive data to be written.
output.on('close', function () {
console.log(archive.pointer() + ' total bytes.');
console.log('Theme ZIP file created.');
// Read the zip file.
const zip = new AdmZip(zipFilePath);
// Load `./functions.php` from the zip file.
const entry = zip.getEntry(slug + '/functions.php');
if (entry) {
// Get the contents of `./functions.php`.
const originalContent = zip.readAsText(entry);
// Replace the version string with a date-based version string.
const updatedContent = originalContent.replace(
/(define\( '[A-Z0-9_]*_VERSION', ')(.*)(' \);)/g,
'$1' +
parseInt(Math.floor(Date.now() / 1000), 10).toString(36) +
'$3'
);
// Update the contents of `./functions.php`.
zip.updateFile(entry, Buffer.from(updatedContent));
// Write the changes back to the zip file.
zip.writeZip(zipFilePath);
console.log(
'Date-based versioning string successfully added to `./functions.php`.'
);
}
});
// This event is fired when the data source is drained no matter what was the data source.
// It is not part of this library but rather from the NodeJS Stream API.
// @see: https://nodejs.org/api/stream.html#stream_event_end
output.on('end', function () {
console.log('Data has been drained');
});
// Catch warnings.
archive.on('warning', function (err) {
if (err.code === 'ENOENT') {
// log warning
} else {
// throw error
throw err;
}
});
// Catch errors.
archive.on('error', function (err) {
throw err;
});
// Pipe archive data to the file.
archive.pipe(output);
// Append the entire contents of the theme directory to a directory with
// the theme slug.
archive.directory(__dirname + '/../theme/', slug);
// Finalize the archive.
archive.finalize();
}

4895
package-lock.json generated 100644

File diff suppressed because it is too large Load Diff

58
package.json 100644
View File

@ -0,0 +1,58 @@
{
"private": true,
"devDependencies": {
"@_tw/themejson": "^0.2.0",
"@_tw/typography": "^0.5.10",
"@angular-eslint/template-parser": "^17.1.1",
"@tailwindcss/aspect-ratio": "^0.4.2",
"@tailwindcss/container-queries": "^0.1.1",
"@tailwindcss/forms": "^0.5.7",
"@wordpress/prettier-config": "^3.5.0",
"adm-zip": "^0.5.10",
"archiver": "^6.0.1",
"chokidar-cli": "^3.0.0",
"cross-env": "^7.0.3",
"daisyui": "^4.7.2",
"esbuild": "^0.19.10",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-php-markup": "^6.0.0",
"eslint-plugin-tailwindcss": "^3.13.0",
"npm-run-all": "^4.1.5",
"postcss": "^8.4.32",
"postcss-import-ext-glob": "^2.1.1",
"prettier": "^3.2.5",
"prettier-plugin-tailwindcss": "^0.5.9",
"tailwindcss": "^3.4.0",
"touch": "^3.1.0"
},
"scripts": {
"development:tailwind:frontend": "npx tailwindcss --postcss -i ./tailwind/tailwind.css -c ./tailwind/tailwind.config.js -o ./theme/style.css",
"development:tailwind:editor": "cross-env _TW_TARGET=editor npx tailwindcss --postcss -i ./tailwind/tailwind.css -c ./tailwind/tailwind.config.js -o ./theme/style-editor.css",
"development:tailwind:editor:extra": "cross-env _TW_TARGET=editor npx tailwindcss --postcss -i tailwind/tailwind-editor-extra.css -c ./tailwind/tailwind.config.js -o ./theme/style-editor-extra.css",
"development:esbuild": "npx esbuild ./javascript/script.js ./javascript/block-editor.js ./javascript/tailwind-typography-classes.js --target=esnext --bundle --outdir=./theme/js --out-extension:.js=.min.js",
"development": "run-p \"development:**\"",
"dev": "npm run development",
"watch:tailwind:frontend": "npm run development:tailwind:frontend -- --watch",
"watch:tailwind:editor": "npm run development:tailwind:editor -- --watch",
"watch:tailwind:editor:extra": "npm run development:tailwind:editor:extra -- --watch",
"watch:tailwind:themejson": "chokidar \"./theme/theme.json\" -c \"nodetouch ./tailwind/tailwind.config.js\"",
"watch:esbuild": "npm run development:esbuild -- --watch",
"watch": "run-p \"watch:**\"",
"lint:eslint": "npx eslint theme/",
"lint:prettier": "npx prettier --check .",
"lint": "run-p \"lint:*\"",
"lint-fix:eslint": "npx eslint theme/ --fix",
"lint-fix:prettier": "npx prettier --write .",
"lint-fix": "run-p \"lint-fix:*\"",
"production:tailwind:frontend": "cross-env NODE_ENV=production npm run development:tailwind:frontend -- --minify",
"production:tailwind:editor": "cross-env NODE_ENV=production npm run development:tailwind:editor -- --minify",
"production:tailwind:editor:extra": "cross-env NODE_ENV=production npm run development:tailwind:editor:extra -- --minify",
"production:esbuild": "npm run development:esbuild -- --minify",
"production": "run-p \"production:**\"",
"prod": "npm run production",
"zip": "node node_scripts/zip.js wowpress",
"bundle": "run-s production zip"
},
"prettier": "@wordpress/prettier-config"
}

89
phpcs.xml.dist 100644
View File

@ -0,0 +1,89 @@
<?xml version="1.0"?>
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="WowPress" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/squizlabs/PHP_CodeSniffer/master/phpcs.xsd">
<description>A set of rules to check for a custom WordPress theme</description>
<!-- Based on the `phpcs.xml.dist.sample` file from the WordPress Coding Standards. -->
<!-- Pass some flags to PHPCS:
p flag: Show progress of the run.
s flag: Show sniff codes in all reports.
-->
<arg value="ps"/>
<!-- Strip the file paths down to the relevant bit. -->
<arg name="basepath" value="./"/>
<!-- Check up to 8 files simultaneously. -->
<arg name="parallel" value="8"/>
<!-- Check PHP files only. JavaScript and CSS files are checked separately. -->
<arg name="extensions" value="php"/>
<!-- Check all files in this directory and the directories below it. -->
<file>.</file>
<!-- Exclude patterns. -->
<exclude-pattern>/vendor/*</exclude-pattern>
<exclude-pattern>/node_modules/*</exclude-pattern>
<!-- Include the WordPress-Extra standard. -->
<rule ref="WordPress-Extra">
<!--
We may want a middle ground, though. The best way to do this is to add
the entire ruleset, then remove rules that don't suit a project. We can
do this by running `phpcs` with the '-s' flag, which allows us to see
the names of the sniffs reporting errors.
Once we know the sniff names, we can opt to exclude sniffs which don't
suit our project.
The examples below demonstrate how you can exclude rules. They are not
intended as advice about which sniffs to exclude.
-->
<!--
<exclude name="WordPress.WhiteSpace.ControlStructureSpacing"/>
<exclude name="WordPress.Security.EscapeOutput"/>
-->
</rule>
<!-- Let's also check that everything is properly documented. -->
<rule ref="WordPress-Docs"/>
<!-- Check for PHP cross-version compatibility. -->
<config name="testVersion" value="7.4-"/>
<rule ref="PHPCompatibilityWP"/>
<!--
To get the optimal benefits of using the WordPress Coding Standards, we
should add a couple of custom properties.
For information on additional custom properties available, check out
the wiki:
https://github.com/WordPress/WordPress-Coding-Standards/wiki/Customizable-sniff-properties
-->
<config name="minimum_supported_wp_version" value="6.2"/>
<rule ref="WordPress.WP.I18n">
<properties>
<property name="text_domain" type="array">
<element value="wowpress"/>
</property>
</properties>
</rule>
<rule ref="WordPress.NamingConventions.PrefixAllGlobals">
<properties>
<property name="prefixes" type="array">
<element value="wowpress"/>
</property>
</properties>
</rule>
<rule ref="WordPress.Files.FileName">
<properties>
<property name="is_theme" value="true"/>
</properties>
</rule>
</ruleset>

10
postcss.config.js 100644
View File

@ -0,0 +1,10 @@
/* eslint-env node */
module.exports = {
plugins: [
require('postcss-import-ext-glob'),
require('postcss-import'),
require('tailwindcss/nesting'),
require('tailwindcss'),
],
};

View File

@ -0,0 +1,5 @@
{
"env": {
"node": true
}
}

View File

@ -0,0 +1,16 @@
/**
* Custom styles to immediately follow Tailwinds `base` layer
*
* Add things like base typography styles [or] opinionated global resets.
*
* from https://tailwindcss.com/docs/plugins#adding-base-styles
*/
/**
* This uses the background and foreground colors declared in the
* `theme.json` file and is applied both to the frontend and in the block
* editor.
*/
body {
@apply bg-background text-foreground font-sans;
}

View File

@ -0,0 +1,49 @@
.btn{
@apply p-3 flex flex-row items-center justify-center gap-2 border;
border-color: white;
background-color: var(--btn-color);
color: white;
&:hover, &.current-menu-item, &.current-page-item, &.current-menu-ancestor ,&.current-menu-parent{
@apply bg-glass;
border-color: color-mix(in srgb, var(--btn-color) 80%, black);
}
}
.btn-outline{
@apply bg-glass;
border-color: var(--btn-color);
color: var(--btn-color);
&:hover, &.current-menu-item, &.current-page-item, &.current-menu-ancestor ,&.current-menu-parent{
border-color: color-mix(in srgb, var(--btn-color) 80%, white);
background-color: var(--btn-color);
color: black;
}
}
nav{
--btn-color: white;
}
.nav-btn{
@apply btn btn-outline;
}
.btn-druid{
--btn-color: var(--wp--preset--color--druid);
}
.btn-deathknight{
--btn-color: var(--wp--preset--color--deathknight);
}
.btn-shaman{
--btn-color: var(--wp--preset--color--shaman);
}
.btn-hunter{
--btn-color: var(--wp--preset--color--hunter);
}

View File

@ -0,0 +1,56 @@
/**
* Custom styles to immediately follow Tailwinds `components` layer
*
* Add more opinionated, complex classes like buttons, form controls, alerts,
* etc; the sort of pre-built components you often see in other frameworks that
* you might need to override with utility classes.
*
* from https://tailwindcss.com/docs/plugins#adding-components
*/
/**
* Post title styles
*
* These will be applied to all headings with a `page-title` or `entry-title`
* class on the frontend and to the post title in the block editor.
*
* The supplied styles are meant to match the default `h1` classes from
* Tailwind Typography.
*/
.page-title,
.entry-title {
@apply pt-2 mx-auto mb-6 text-3xl font-extrabold text-white;
}
/**
* Layout styles for centered content areas
*
* If you are controlling the width of your content area with styles applied
* to its container, you can delete the following styles whose selectors begin
* with `.page-content >` and `.entry-content >`. For more details, please see
* the following:
*
* https://make.wordpress.org/core/2021/06/29/on-layout-and-content-width-in-wordpress-5-8/
*/
.page-content > *,
.entry-content > * {
/* Content width from the `theme.json` file */
@apply mx-auto;
}
.entry-content > .alignwide {
/* Wide width from the `theme.json` file */
@apply max-w-wide;
}
.entry-content > .alignfull {
@apply max-w-none;
}
.entry-content > .alignleft {
@apply float-left mr-8;
}
.entry-content > .alignright {
@apply float-right ml-8;
}

View File

@ -0,0 +1,5 @@
article {
@apply bg-glass shadow;
}

View File

@ -0,0 +1,61 @@
.ribbon{
--color-ribbon : #fff;
@apply block;
span{
position: relative;
bottom: 0;
left: 0;
padding: .75em 1.25em .75em .75em;
margin-left: -.5em;
margin-right: -.5em;
background-color: var(--color-ribbon);
box-shadow: inset 0 .062em 0 var(--color-ribbon), 0 .125em .25em rgba(0, 0, 0, .2);
color: black;
box-shadow: 0 0 16px var(--color-ribbon);
text-shadow: 0 -.062em 0 rgba(0, 0, 0, .2);
text-align: center;
display: block;
border-radius: 0 .5em 0 .5em;
word-wrap: break-word;
}
span:before{
content: "";
position: absolute;
top: -1em;
left: 0;
width: .5em;
height: 3em;
border-radius: .5em 0 0 .5em;
background-color: var(--color-ribbon);
z-index: -1;
background-image: linear-gradient(to right, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0.4) 100%);
}
span:after{
content: "";
position: absolute;
top: 1em;
right: 0em;
width: .5em;
height: 3em;
border-radius: 0 .5em .5em 0;
background-color: var(--color-ribbon);
z-index: -1;
background-image: linear-gradient(to left, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0.4) 100%);
}
}
.ribbon-druid{
--color-ribbon : var(--color-druid)
}
.ribbon-deathknight{
--color-ribbon : var(--color-deathknight)
}
.ribbon-demonhunter{
--color-ribbon : var(--color-demonhunter)
}

View File

@ -0,0 +1,61 @@
.widget-wrapper {
display: flex;
flex-direction: column;
gap: var(--wowp-gap);
}
.top-widgets {
order: 1;
grid-area: 1 / 2 / 2 / 3;
}
.top-title {
order: 1;
grid-area: 1 / 2 / 2 / 3;
@apply bg-glass shadow text-4xl font-bold text-center p-2;
}
.content {
order: 3;
grid-area: 2 / 2 / 4 / 3;
}
#main {
display: flex;
flex-direction: column;
gap: var(--wowp-gap);
}
.left-widgets {
order: 4;
grid-area: 1 / 1 / 3 / 2;
@media screen(xl){
padding-left: var(--wowp-gap);
min-width: 420px;
max-width: 420px;
}
}
.right-widgets {
order:0;
grid-area: 1 / 3 / 3 / 6;
@media screen(xl){
padding-right: var(--wowp-gap);
min-width: 420px;
}
}
.bottom-widgets {
order: 5;
grid-area: 4 / 2 / 4 / 3;
}
.widget{
@apply bg-glass p-2 shadow text-center;
h3{
font-size: 1.3em;
font-weight: bold;
}
}

View File

@ -0,0 +1,23 @@
/*!
Theme Name: WowPress
Theme URI: https://underscoretw.com/
Author: underscoretw.com
Author URI: https://underscoretw.com/
Description: A custom theme based on _tw
Version: 0.1.0
Tested up to: 6.2
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: LICENSE
Text Domain: wowpress
Tags:
This theme, like WordPress, is licensed under the GPL.
Use it to make something cool, have fun, and share what you've learned.
WowPress is based on _tw https://underscoretw.com/, (C) 2021-2023 Greg Sullivan
_tw is distributed under the terms of the GNU GPL v2 or later.
_tw is based on Underscores https://underscores.me/ and Varia https://github.com/Automattic/themes/tree/master/varia, (C) 2012-2023 Automattic, Inc.
Underscores and Varia are distributed under the terms of the GNU GPL v2 or later.
*/

View File

@ -0,0 +1,5 @@
/**
* Custom `@font-face` rules
*
* These will be added immediately before Tailwinds `base` layer.
*/

View File

@ -0,0 +1,8 @@
/**
* Custom styles to immediately follow Tailwinds `utilities` layer
*
* Add your own utility classes to this theme. Complex utility classes should
* be added using Tailwinds plugin system:
*
* https://tailwindcss.com/docs/plugins#adding-utilities
*/

View File

@ -0,0 +1,22 @@
/**
* Additional styles applied only to the WordPress editor
*
* It is sometimes necessary to add additional styles for the WordPress block
* editor, generally to improve the editor experience. For example, you may
* want to tweak the appearance of the title area to better match your sites
* front end, or you may need to change the appearance of a block to better
* distinguish between its fields while editing.
*
* Those styles should be added in this file, and they will be added only to
* the block editor.
*/
.bg-glass{
background-color: rgba(0, 0, 50, 0.4);
backdrop-filter: blur(10px);
}
.entry-header,
.entry-content {
@apply px-8 bg-glass;
}

View File

@ -0,0 +1,160 @@
// Copied from Tailwind Typography.
const hexToRgb = (hex) => {
if (typeof hex !== 'string' || hex.length === 0) {
return hex;
}
hex = hex.replace('#', '');
hex = hex.length === 3 ? hex.replace(/./g, '$&$&') : hex;
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
return `${r} ${g} ${b}`;
};
module.exports = {
theme: {
extend: {
typography: (theme) => ({
/**
* Tailwind Typographys default styles are opinionated, and
* you may need to override them if you have mockups to
* replicate. You can view the default modifiers here:
*
* https://github.com/tailwindlabs/tailwindcss-typography/blob/master/src/styles.js
*/
DEFAULT: {
css: [
{
/**
* By default, max-width is set to 65 characters.
* This is a good default for readability, but
* often in conflict with client-supplied designs.
* A value of false removes the max-width property.
*/
maxWidth: false,
/**
* Tailwind Typography uses the font weights 400
* through 900. If youre not using a variable font,
* you may need to limit the number of supported
* weights. Below are all of the default weights,
* ready to be overridden.
*/
// a: {
// fontWeight: '500',
// },
// strong: {
// fontWeight: '600',
// },
// 'ol > li::marker': {
// fontWeight: '400',
// },
// dt: {
// fontWeight: '600',
// },
// blockquote: {
// fontWeight: '500',
// },
// h1: {
// fontWeight: '800',
// },
// 'h1 strong': {
// fontWeight: '900',
// },
// h2: {
// fontWeight: '700',
// },
// 'h2 strong': {
// fontWeight: '800',
// },
// h3: {
// fontWeight: '600',
// },
// 'h3 strong': {
// fontWeight: '700',
// },
// h4: {
// fontWeight: '600',
// },
// 'h4 strong': {
// fontWeight: '700',
// },
// kbd: {
// fontWeight: '500',
// },
// code: {
// fontWeight: '600',
// },
// pre: {
// fontWeight: '400',
// },
// 'thead th': {
// fontWeight: '600',
// },
},
],
},
/**
* By default, _tw uses Tailwind Typographys Neutral gray
* scale. If you are adapting an existing design and you need
* to set specific colors throughout, you can do so here. In
* your `./theme/functions.php file, you will need to replace
* `prose-neutral` with `prose-wowpress`.
*/
wowpress: {
css: {
'--tw-prose-body': theme('colors.foreground'),
'--tw-prose-headings': theme('colors.foreground'),
'--tw-prose-lead': theme('colors.foreground'),
'--tw-prose-links': theme('colors.primary'),
'--tw-prose-bold': theme('colors.foreground'),
'--tw-prose-counters': theme('colors.primary'),
'--tw-prose-bullets': theme('colors.primary'),
'--tw-prose-hr': theme('colors.foreground'),
'--tw-prose-quotes': theme('colors.foreground'),
'--tw-prose-quote-borders': theme('colors.primary'),
'--tw-prose-captions': theme('colors.foreground'),
'--tw-prose-kbd': theme('colors.foreground'),
'--tw-prose-kbd-shadows': hexToRgb(
theme('colors.foreground')
),
'--tw-prose-code': theme('colors.foreground'),
'--tw-prose-pre-code': theme('colors.background'),
'--tw-prose-pre-bg': theme('colors.foreground'),
'--tw-prose-th-borders': theme('colors.foreground'),
'--tw-prose-td-borders': theme('colors.foreground'),
'--tw-prose-invert-body': theme('colors.background'),
'--tw-prose-invert-headings':
theme('colors.background'),
'--tw-prose-invert-lead': theme('colors.background'),
'--tw-prose-invert-links': theme('colors.primary'),
'--tw-prose-invert-bold': theme('colors.background'),
'--tw-prose-invert-counters': theme('colors.primary'),
'--tw-prose-invert-bullets': theme('colors.primary'),
'--tw-prose-invert-hr': theme('colors.background'),
'--tw-prose-invert-quotes': theme('colors.background'),
'--tw-prose-invert-quote-borders':
theme('colors.primary'),
'--tw-prose-invert-captions':
theme('colors.background'),
'--tw-prose-invert-kbd': theme('colors.background'),
'--tw-prose-invert-kbd-shadows': hexToRgb(
theme('colors.background')
),
'--tw-prose-invert-code': theme('colors.foreground'),
'--tw-prose-invert-pre-code':
theme('colors.background'),
'--tw-prose-invert-pre-bg': 'rgb(0 0 0 / 50%)',
'--tw-prose-invert-th-borders':
theme('colors.background'),
'--tw-prose-invert-td-borders':
theme('colors.background'),
},
},
}),
},
},
};

View File

@ -0,0 +1,98 @@
// Set the Preflight flag based on the build target.
const includePreflight = 'editor' === process.env._TW_TARGET ? false : true;
import plugin from 'tailwindcss/plugin';
module.exports = {
presets: [
// Manage Tailwind Typography's configuration in a separate file.
require('./tailwind-typography.config.js'),
],
content: [
// Ensure changes to PHP files and `theme.json` trigger a rebuild.
'./theme/**/*.php',
],
darkMode: 'class',
theme: {
// Extend the default Tailwind theme.
extend: {
},
},
daisyui: {
themes: [
{
wowpress: {
"primary": "#a991f7",
"secondary": "#f6d860",
"accent": "#37cdbe",
"neutral": "#fff",
"base-100": "#ffffff",
"primary-content": "#fff",
"--rounded-box": "0rem", // border radius rounded-box utility class, used in card and other large boxes
"--rounded-btn": "0rem", // border radius rounded-btn utility class, used in buttons and similar element
"--rounded-badge": "0rem",
}
}
]
},
corePlugins: {
// Disable Preflight base styles in builds targeting the editor.
preflight: includePreflight,
},
plugins: [
// require('daisyui'),
// Add Tailwind Typography (via _tw fork).
require('@_tw/typography'),
// Extract colors and widths from `theme.json`.
require('@_tw/themejson'),
// Uncomment below to add additional first-party Tailwind plugins.
require('@tailwindcss/forms'),
require('@tailwindcss/aspect-ratio'),
require('@tailwindcss/container-queries'),
plugin(function({theme, addUtilities}) {
const colorUtilities={};
const colors = theme('colors');
for (const color in colors){
if(typeof colors[color] === 'object'){
colorUtilities[`.button-${color}`] = {
'background': colors[color]['400'],
'color': colors[color]['800'],
'border': '1px solid '+colors[color]['800'],
'outline': colors[color]['800'],
'&:hover': {
'background': colors[color]['300'],
'border': '1px solid'+ colors[color]['900']
}
}
colorUtilities[`.badge-${color}`] = {
'background': colors[color]['200'],
'color': colors[color]['800'],
'border-color': colors[color]['800'],
}
colorUtilities[`.alert-${color}`] = {
'background': colors[color]['200'],
'color': colors[color]['800'],
'border-color': colors[color]['800'],
}
colorUtilities[`.disabled-${color}`] = {
'--disabled-color' : colors[color]['500'],
}
colorUtilities[`.enabled-${color}`] = {
'--enabled-color' : colors[color]['500'],
}
}
}
addUtilities(colorUtilities);
})
],
safelist: [
{pattern: /button-+/},
{pattern: /badge-+/},
{pattern: /alert-+/},
{pattern: /bg-[^/]+-200$/},
{pattern: /text-+/},
{pattern: /border-[^/]+-700$/},
]
};

View File

@ -0,0 +1,238 @@
@import "./custom/file-header.css";
/**
* The line above injects the WordPress file header. It needs to be first,
* before this comment.
*/
/**
* This injects custom `@font-face` rules.
*/
@import "./custom/fonts.css";
/**
* This injects Tailwind's base styles and any base styles registered by
* plugins, then adds custom base styles.
*/
@import "tailwindcss/base";
@import "./custom/base.css";
/**
* This injects Tailwind's component classes and any component classes
* registered by plugins, then adds custom component classes.
*
* The `@import-glob` line imports all CSS files from the `components`
* directory (except for `components.css`, which is imported on the following
* line). This is meant to simplify the process of integrating styles from
* JavaScript components or WordPress plugins.
*/
@import "tailwindcss/components";
@import-glob "./custom/components/**/!(components).css";
@import "./custom/components/components.css";
/**
* This injects Tailwind's utility classes and any utility classes registered
* by plugins, then adds custom utility classes.
*/
@import "tailwindcss/utilities";
@import "./custom/utilities.css";
:root {
--wowp-gap: 1em;
--color-deathknight: #C41E3A;
--color-demonhunter: #A330C9;
--color-druid: #DD7C0A;
--color-evoker: #33937F;
--color-hunter: #AAD372;
--color-mage: #3FC7EB;
--color-monk: #00FF98;
--color-paladin: #F48CBA;
--color-priest: #FFFFFF;
--color-rogue: #FFF468;
--color-shaman: #0070DD;
--color-warlock: #8788EE;
--color-warrior: #C69B6D;
}
.p-auto{
padding: var(--wowp-gap);
}
body {
background-color: unset;
--body-bg: url('https://nebelkrieger.de/wp-content/uploads/2023/05/F8lCEpyWoAAFCFS-scaled.jpg');
position: relative;
z-index: -10;
}
.bg-glass {
background-color: rgba(0, 0, 50, 0.4);
backdrop-filter: blur(10px);
}
.shadow{
-webkit-box-shadow: 5px 5px 9px 0px rgba(0, 0, 0, 0.5);
box-shadow: 5px 5px 9px 0px rgba(0, 0, 0, 0.5);
}
body:before {
content: "";
display: block;
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: -1000;
background: var(--body-bg) no-repeat center center;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
pointer-events: none;
}
header#masthead {
@apply bg-glass;
}
.content-wrapper {
position: relative;
z-index: -1;
margin-block: var(--wowp-gap);
}
.content-wrapper {
display: flex;
flex-direction:column;
gap: var(--wowp-gap);
@media screen(xl) {
display: grid;
grid-column-gap: var(--wowp-gap);
grid-row-gap: var(--wowp-gap);
grid-template-columns: auto 1fr auto;
grid-template-rows: auto 1fr auto;
}
}
article{
margin-inline: var(--wowp-gap);
@media screen(xl){
margin-inline: unset;
}
}
.post-wrapper {
display: grid;
grid-template-columns: auto auto 1fr;
grid-template-rows: auto auto 1fr auto;
grid-column-gap: var(--wowp-gap);
grid-row-gap: var(--wowp-gap);
}
.post-title { grid-area: 1 / 1 / 2 / 4;
@apply text-center text-2xl py-2;
}
.post-content { grid-area: 3 / 1 / 4 / 4;
padding-inline: var(--wowp-gap);}
.post-category { grid-area: 2 / 1 / 3 / 4;
span{
@apply p-0;
&:before{
height: 1.5em;
}
&:after{
height: 1.5em;
}
@media screen(xl) {
padding: .75em 1.25em .75em .75em;
&:before{
height: 3em;
}
&:after{
height: 3em;
}
}
}
}
.post-author { grid-area: 4 / 3 / 5 / 4;
@apply text-end;
color: var(--author-class);
padding-right: var(--wowp-gap);
padding-bottom: var(--wowp-gap);
}
.post-day { grid-area: 4 / 1 / 5 / 2;
padding-left: var(--wowp-gap);
padding-bottom: var(--wowp-gap);
}
.post-month { grid-area: 4 / 2 / 5 / 3;
padding-bottom: var(--wowp-gap);
}
.post-avatar{
display:none;
}
@media screen(xl){
.post-wrapper {
display: grid;
grid-template-columns: 1fr 7fr;
grid-template-rows: auto auto 1fr auto auto 1fr auto;
grid-column-gap: var(--wowp-gap);
grid-row-gap: 0px;
}
.post-title { grid-area: 1 / 2 / 2 / 5;
@apply text-4xl text-left;
}
.post-content { grid-area: 2 / 2 / 8 / 5;
@apply prose prose-wowpress;
padding: unset;
padding-right: var(--wowp-gap);
}
.post-day { grid-area: 1 / 1 / 2 / 2;
@apply bg-shaman flex flex-row items-center justify-center text-4xl;
padding:unset;
}
.post-month {
@apply bg-slate-400 flex flex-row items-center justify-center text-xl;
padding: unset;
grid-area: 2 / 1 / 3 / 2;
}
.post-category { grid-area: 3 / 1 / 4 / 2;
@apply bg-glass;
margin-top: var(--wowp-gap);
}
.post-avatar {
@apply flex flex-col justify-end items-center bg-glass;
grid-area: 4 / 1 / 7 / 2;
img{
@apply rounded-md mb-4 outline shadow w-20;
outline-color: var(--author-class);
}
}
.post-author { grid-area: 7 / 1 / 8 / 2;
@apply flex flex-row items-center justify-center;
padding:unset;
background-color: var(--author-class);
color: black;
}
}

31
theme/404.php 100644
View File

@ -0,0 +1,31 @@
<?php
/**
* The template for displaying 404 pages (not found)
*
* @link https://codex.wordpress.org/Creating_an_Error_404_Page
*
* @package WowPress
*/
get_header();
?>
<section id="primary">
<main id="main">
<div>
<header class="page-header">
<h1 class="page-title"><?php esc_html_e( 'Page Not Found', 'wowpress' ); ?></h1>
</header><!-- .page-header -->
<div <?php wowpress_content_class( 'page-content' ); ?>>
<p><?php esc_html_e( 'This page could not be found. It might have been removed or renamed, or it may never have existed.', 'wowpress' ); ?></p>
<?php get_search_form(); ?>
</div><!-- .page-content -->
</div>
</main><!-- #main -->
</section><!-- #primary -->
<?php
get_footer();

45
theme/archive.php 100644
View File

@ -0,0 +1,45 @@
<?php
/**
* The template for displaying archive pages
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package WowPress
*/
get_header();
?>
<section id="primary">
<main id="main">
<?php if ( have_posts() ) : ?>
<header class="page-header">
<?php the_archive_title( '<h1 class="page-title">', '</h1>' ); ?>
</header><!-- .page-header -->
<?php
// Start the Loop.
while ( have_posts() ) :
the_post();
get_template_part( 'template-parts/content/content', 'excerpt' );
// End the loop.
endwhile;
// Previous/next page navigation.
wowpress_the_posts_navigation();
else :
// If no content, include the "No posts found" template.
get_template_part( 'template-parts/content/content', 'none' );
endif;
?>
</main><!-- #main -->
</section><!-- #primary -->
<?php
get_footer();

81
theme/comments.php 100644
View File

@ -0,0 +1,81 @@
<?php
/**
* The template for displaying comments
*
* This is the template that displays the area of the page that contains both
* the current comments and the comment form.
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package WowPress
*/
/*
* If the current post is protected by a password and the visitor has not yet
* entered the password we will return early without loading the comments.
*/
if ( post_password_required() ) {
return;
}
?>
<div id="comments">
<?php
if ( have_comments() ) :
?>
<h2>
<?php
$wowpress_comment_count = get_comments_number();
if ( '1' === $wowpress_comment_count ) {
// phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
printf(
/* translators: 1: title. */
esc_html__( 'One comment on &ldquo;%1$s&rdquo;', 'wowpress' ),
get_the_title()
);
// phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
} else {
// phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
printf(
/* translators: 1: comment count number, 2: title. */
esc_html( _nx( '%1$s comment on &ldquo;%2$s&rdquo;', '%1$s comments on &ldquo;%2$s&rdquo;', $wowpress_comment_count, 'comments title', 'wowpress' ) ),
number_format_i18n( $wowpress_comment_count ),
get_the_title()
);
// phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
}
?>
</h2>
<?php the_comments_navigation(); ?>
<ol>
<?php
wp_list_comments(
array(
'style' => 'ol',
'callback' => 'wowpress_html5_comment',
'short_ping' => true,
)
);
?>
</ol>
<?php
the_comments_navigation();
// If there are existing comments, but comments are closed, display a
// message.
if ( ! comments_open() ) :
?>
<p><?php esc_html_e( 'Comments are closed.', 'wowpress' ); ?></p>
<?php
endif;
endif;
comment_form();
?>
</div><!-- #comments -->

View File

@ -0,0 +1,10 @@
{
"require": {
"wenprise/eloquent": "^9.0"
},
"autoload": {
"psr-4": {
"WoWPress\\": "./wowpress/"
}
}
}

1953
theme/composer.lock generated 100644

File diff suppressed because it is too large Load Diff

48
theme/footer.php 100644
View File

@ -0,0 +1,48 @@
<?php
/**
* The template for displaying the footer
*
* Contains the closing of the `#content` element and all content thereafter.
*
* @link https://developer.wordpress.org/themes/basics/template-files/#template-partials
*
* @package WowPress
*/
?>
</div><!-- #content -->
<?php
if ($GLOBALS['wowpress']['widget_area']['right'] !== false) :
?>
<div class="widget-wrapper right-widgets">
<div id="demo-widget" class="widget">
<h3>Titel Right 1</h3>
</div>
<div id="demo-widget" class="widget">
<h3>Titel Right 2</h3>
</div>
</div>
<?php
endif;
if ($GLOBALS['wowpress']['widget_area']['bottom'] !== false) :
?>
<div class="widget-wrapper bottom-widgets">
<div id="demo-widget" class="widget">
<h3>Titel Bottom 1</h3>
</div>
<?php get_template_part('template-parts/layout/footer', 'content'); ?>
</div>
<?php
endif;
?>
</div> <!-- grid -->
<?php wp_footer(); ?>
</body>
</html>

387
theme/functions.php 100644
View File

@ -0,0 +1,387 @@
<?php
use WoWPress\Database\CreateCacheTable;
use WoWPress\Database\CreateCharacterTable;
use WoWPress\Models\Character;
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require_once('vendor/autoload.php');
/**
* WowPress functions and definitions
*
* @link https://developer.wordpress.org/themes/basics/theme-functions/
*
* @package WowPress
*/
if ( ! defined( 'WOWPRESS_VERSION' ) ) {
/*
* Set the themes version number.
*
* This is used primarily for cache busting. If you use `npm run bundle`
* to create your production build, the value below will be replaced in the
* generated zip file with a timestamp, converted to base 36.
*/
define( 'WOWPRESS_VERSION', '0.1.0' );
}
if ( ! defined( 'WOWPRESS_TYPOGRAPHY_CLASSES' ) ) {
/*
* Set Tailwind Typography classes for the front end, block editor and
* classic editor using the constant below.
*
* For the front end, these classes are added by the `wowpress_content_class`
* function. You will see that function used everywhere an `entry-content`
* or `page-content` class has been added to a wrapper element.
*
* For the block editor, these classes are converted to a JavaScript array
* and then used by the `./javascript/block-editor.js` file, which adds
* them to the appropriate elements in the block editor (and adds them
* again when theyre removed.)
*
* For the classic editor (and anything using TinyMCE, like Advanced Custom
* Fields), these classes are added to TinyMCEs body class when it
* initializes.
*/
define(
'WOWPRESS_TYPOGRAPHY_CLASSES',
'prose prose-wowpress max-w-none prose-a:text-primary'
);
}
if ( ! function_exists( 'wowpress_setup' ) ) :
/**
* Sets up theme defaults and registers support for various WordPress features.
*
* Note that this function is hooked into the after_setup_theme hook, which
* runs before the init hook. The init hook is too late for some features, such
* as indicating support for post thumbnails.
*/
function wowpress_setup() {
/*
* Make theme available for translation.
* Translations can be filed in the /languages/ directory.
* If you're building a theme based on WowPress, use a find and replace
* to change 'wowpress' to the name of your theme in all the template files.
*/
load_theme_textdomain( 'wowpress', get_template_directory() . '/languages' );
// Add default posts and comments RSS feed links to head.
add_theme_support( 'automatic-feed-links' );
/*
* Let WordPress manage the document title.
* By adding theme support, we declare that this theme does not use a
* hard-coded <title> tag in the document head, and expect WordPress to
* provide it for us.
*/
add_theme_support( 'title-tag' );
/*
* Enable support for Post Thumbnails on posts and pages.
*
* @link https://developer.wordpress.org/themes/functionality/featured-images-post-thumbnails/
*/
add_theme_support( 'post-thumbnails' );
// This theme uses wp_nav_menu() in two locations.
register_nav_menus(
array(
'menu-1' => __( 'Primary', 'wowpress' ),
'menu-2' => __( 'Footer Menu', 'wowpress' ),
)
);
/*
* Switch default core markup for search form, comment form, and comments
* to output valid HTML5.
*/
add_theme_support(
'html5',
array(
'search-form',
'comment-form',
'comment-list',
'gallery',
'caption',
'style',
'script',
)
);
// Add theme support for selective refresh for widgets.
add_theme_support( 'customize-selective-refresh-widgets' );
// Add support for editor styles.
add_theme_support( 'editor-styles' );
// Enqueue editor styles.
add_editor_style( 'style-editor.css' );
add_editor_style( 'style-editor-extra.css' );
// Add support for responsive embedded content.
add_theme_support( 'responsive-embeds' );
// Remove support for block templates.
remove_theme_support( 'block-templates' );
}
endif;
if ( ! function_exists( 'wowpress_database' ) ) :
function wowpress_database(){
global $wpdb;
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
dbDelta( [
CreateCharacterTable::sql(),
CreateCacheTable::sql(),
] );
}
endif;
add_action( 'after_setup_theme', 'wowpress_setup' );
add_action( 'after_switch_theme','wowpress_database');
/**
* Register widget area.
*
* @link https://developer.wordpress.org/themes/functionality/sidebars/#registering-a-sidebar
*/
function wowpress_widgets_init() {
register_sidebar(
array(
'name' => __( 'Footer', 'wowpress' ),
'id' => 'bottom-widgets',
'description' => __( 'Add widgets here to appear in your footer.', 'wowpress' ),
'before_widget' => '<section id="%1$s" class="widget %2$s">',
'after_widget' => '</section>',
'before_title' => '<h2 class="widget-title">',
'after_title' => '</h2>',
)
);
register_sidebar(
array(
'name' => __( 'Linke Seite', 'wowpress' ),
'id' => 'left-widgets',
'description' => __( 'Add widgets here to appear on the left side.', 'wowpress' ),
'before_widget' => '<section id="%1$s" class="widget %2$s">',
'after_widget' => '</section>',
'before_title' => '<h2 class="widget-title">',
'after_title' => '</h2>',
)
);
}
add_action( 'widgets_init', 'wowpress_widgets_init' );
/**
* Enqueue scripts and styles.
*/
function wowpress_scripts() {
wp_enqueue_style( 'wowpress-style', get_stylesheet_uri(), array(), WOWPRESS_VERSION );
wp_enqueue_script( 'wowpress-script', get_template_directory_uri() . '/js/script.min.js', array(), WOWPRESS_VERSION, true );
if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
wp_enqueue_script( 'comment-reply' );
}
}
add_action( 'wp_enqueue_scripts', 'wowpress_scripts' );
/**
* Enqueue the block editor script.
*/
function wowpress_enqueue_block_editor_script() {
wp_enqueue_script(
'wowpress-editor',
get_template_directory_uri() . '/js/block-editor.min.js',
array(
'wp-blocks',
'wp-edit-post',
),
WOWPRESS_VERSION,
true
);
}
add_action( 'enqueue_block_editor_assets', 'wowpress_enqueue_block_editor_script' );
/**
* Enqueue the script necessary to support Tailwind Typography in the block
* editor, using an inline script to create a JavaScript array containing the
* Tailwind Typography classes from WOWPRESS_TYPOGRAPHY_CLASSES.
*/
function wowpress_enqueue_typography_script() {
if ( is_admin() ) {
wp_enqueue_script(
'wowpress-typography',
get_template_directory_uri() . '/js/tailwind-typography-classes.min.js',
array(
'wp-blocks',
'wp-edit-post',
),
WOWPRESS_VERSION,
true
);
wp_add_inline_script( 'wowpress-typography', "tailwindTypographyClasses = '" . esc_attr( WOWPRESS_TYPOGRAPHY_CLASSES ) . "'.split(' ');", 'before' );
}
}
add_action( 'enqueue_block_assets', 'wowpress_enqueue_typography_script' );
/**
* Add the Tailwind Typography classes to TinyMCE.
*
* @param array $settings TinyMCE settings.
* @return array
*/
function wowpress_tinymce_add_class( $settings ) {
$settings['body_class'] = WOWPRESS_TYPOGRAPHY_CLASSES;
return $settings;
}
add_filter( 'tiny_mce_before_init', 'wowpress_tinymce_add_class' );
/**
* Custom template tags for this theme.
*/
require get_template_directory() . '/inc/template-tags.php';
/**
* Functions which enhance the theme by hooking into WordPress.
*/
require get_template_directory() . '/inc/template-functions.php';
require get_template_directory() . '/plugins/wowpress-navwalker.php';
require get_template_directory() . '/plugins/wowpress-icons.php';
/**
* Hide Admin Bar
*/
add_filter('show_admin_bar', '__return_false');
/**
* Variable initialization
*/
// Show Widgets
$GLOBALS['wowpress']['widget_area'] = [
'left' => true,
'right' => true,
'top' => true,
'bottom' => true,
];
// Colors
$GLOBALS['wowpress']['theme'] = json_decode( file_get_contents( get_template_directory() . "/theme.json"),true);
/**
* Custom rewrite rules
*/
add_filter( 'generate_rewrite_rules', function ( $wp_rewrite ){
$wp_rewrite->rules = array_merge(
['roster/?$' => 'index.php?wowpress_page=roster'],
$wp_rewrite->rules
);
} );
add_filter( 'query_vars', function( $query_vars ){
$query_vars[] = 'wowpress_page';
return $query_vars;
} );
add_action( 'template_redirect', function(){
$page = get_query_var( 'wowpress_page' );
switch($page){
case 'roster':
$GLOBALS['wowpress']['widget_area'] = [
'left' => false,
'right' => false,
'top' => false,
'bottom' => true,
];
$GLOBALS['wowpress']['page_title'] = "Gildenverzeichnis";
include plugin_dir_path( __FILE__ ) . 'pages/roster.php';
die;
break;
default:
// DO NOTHING
break;
}
} );
/**
* Neue Werte für Kategorien
*/
function wowpress_color_picker_scripts() {
wp_enqueue_style( 'wp-color-picker' );
wp_enqueue_script( 'cp-active', get_template_directory_uri()."/plugins/cp-active.js", array('wp-color-picker'), false, true );
}
add_action( 'admin_enqueue_scripts', 'wowpress_color_picker_scripts');
add_action( 'category_add_form_fields', 'wowpress_add_category_meta', 10, 2 );
function wowpress_add_category_meta($taxonomy) {
$colors = $GLOBALS['wowpress']['theme']['settings']['color']['palette'];
?><div class="form-field term-group">
<label for="color"><?php _e('Farbe', 'wowpress'); ?></label>
<input type="text" name="color" id="color" class="color-picker">
</div><?php
}
add_action( 'created_category', 'wowpress_save_category_meta', 10, 2 );
function wowpress_save_category_meta( $term_id, $tt_id ){
if( isset( $_POST['color'] ) && '' !== $_POST['color'] ){
$color = sanitize_title( $_POST['color'] );
add_term_meta( $term_id, 'color', $color, true );
}
}
add_action( 'category_edit_form_fields', 'wowpress_edit_category_meta', 10, 2 );
function wowpress_edit_category_meta( $term, $taxonomy ){
$colors = $GLOBALS['wowpress']['theme']['settings']['color']['palette'];
// get current group
$selected_color = get_term_meta( $term->term_id, 'color', true );
?><tr class="form-field term-group-wrap">
<th scope="row"><label for="color"><?php _e( 'Farbe', 'wowpress' ); ?></label></th>
<td>
<input type="text" name="color" id="color" class="color-picker" value="#<?=$selected_color?>">
</td>
</tr><?php
}
add_action( 'edited_category', 'wowpress_update_category_meta', 10, 2 );
function wowpress_update_category_meta( $term_id, $tt_id ){
if( isset( $_POST['color'] ) && '' !== $_POST['color'] ){
$color = sanitize_title( $_POST['color'] );
update_term_meta( $term_id, 'color', $color );
}
}
//* Theme Options Page **/
require_once ( get_stylesheet_directory() . '/options/options.php' );
/** Global Helper functions */
function translate_string($string,$lang="deu"){
$dict_path = get_template_directory()."/lang/$lang.json";
if(!file_exists($dict_path)) return $string;
$dict = json_decode(file_get_contents($dict_path),true);
if(key_exists($string,$dict)){
return $dict[$string];
}
return $string;
}

62
theme/header.php 100644
View File

@ -0,0 +1,62 @@
<?php
/**
* The header for our theme
*
* This is the template that displays the `head` element and everything up
* until the `#content` element.
*
* @link https://developer.wordpress.org/themes/basics/template-files/#template-partials
*
* @package WowPress
*/
?>
<!doctype html>
<html <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo('charset'); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="profile" href="https://gmpg.org/xfn/11">
<script src="<?= get_template_directory_uri() ?>/plugins/alpine.min.js" defer></script>
<?php wp_head(); ?>
</head>
<body <?php body_class('dark'); ?>>
<?php wp_body_open(); ?>
<?php get_template_part('template-parts/layout/header', 'content'); ?>
<div class="content-wrapper">
<?php
if ($GLOBALS['wowpress']['widget_area']['top'] !== false) :
?>
<div class="widget-wrapper top-widgets">
<div id="demo-widget" class="widget">
<h3>Titel Top 1</h3>
</div>
</div>
<?php
else :
?>
<div class="top-title">
<?= $GLOBALS['wowpress']['page_title'] ?>
</div>
<?php
endif;
if ($GLOBALS['wowpress']['widget_area']['left'] !== false) :
?>
<?php if (is_active_sidebar('left-widgets')) : ?>
<div class="widget-wrapper left-widgets">
<?php dynamic_sidebar('left-widgets'); ?>
</div>
<?php endif; ?>
<?php
endif;
?>
<div id="content" class="content">

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

View File

@ -0,0 +1,206 @@
<?php
/**
* Functions which enhance the theme by hooking into WordPress
*
* @package WowPress
*/
/**
* Add a pingback url auto-discovery header for single posts, pages, or attachments.
*/
function wowpress_pingback_header() {
if ( is_singular() && pings_open() ) {
printf( '<link rel="pingback" href="%s">', esc_url( get_bloginfo( 'pingback_url' ) ) );
}
}
add_action( 'wp_head', 'wowpress_pingback_header' );
/**
* Changes comment form default fields.
*
* @param array $defaults The default comment form arguments.
*
* @return array Returns the modified fields.
*/
function wowpress_comment_form_defaults( $defaults ) {
$comment_field = $defaults['comment_field'];
// Adjust height of comment form.
$defaults['comment_field'] = preg_replace( '/rows="\d+"/', 'rows="5"', $comment_field );
return $defaults;
}
add_filter( 'comment_form_defaults', 'wowpress_comment_form_defaults' );
/**
* Filters the default archive titles.
*/
function wowpress_get_the_archive_title() {
if ( is_category() ) {
$title = __( 'Category Archives: ', 'wowpress' ) . '<span>' . single_term_title( '', false ) . '</span>';
} elseif ( is_tag() ) {
$title = __( 'Tag Archives: ', 'wowpress' ) . '<span>' . single_term_title( '', false ) . '</span>';
} elseif ( is_author() ) {
$title = __( 'Author Archives: ', 'wowpress' ) . '<span>' . get_the_author_meta( 'display_name' ) . '</span>';
} elseif ( is_year() ) {
$title = __( 'Yearly Archives: ', 'wowpress' ) . '<span>' . get_the_date( _x( 'Y', 'yearly archives date format', 'wowpress' ) ) . '</span>';
} elseif ( is_month() ) {
$title = __( 'Monthly Archives: ', 'wowpress' ) . '<span>' . get_the_date( _x( 'F Y', 'monthly archives date format', 'wowpress' ) ) . '</span>';
} elseif ( is_day() ) {
$title = __( 'Daily Archives: ', 'wowpress' ) . '<span>' . get_the_date() . '</span>';
} elseif ( is_post_type_archive() ) {
$cpt = get_post_type_object( get_queried_object()->name );
$title = sprintf(
/* translators: %s: Post type singular name */
esc_html__( '%s Archives', 'wowpress' ),
$cpt->labels->singular_name
);
} elseif ( is_tax() ) {
$tax = get_taxonomy( get_queried_object()->taxonomy );
$title = sprintf(
/* translators: %s: Taxonomy singular name */
esc_html__( '%s Archives', 'wowpress' ),
$tax->labels->singular_name
);
} else {
$title = __( 'Archives:', 'wowpress' );
}
return $title;
}
add_filter( 'get_the_archive_title', 'wowpress_get_the_archive_title' );
/**
* Determines whether the post thumbnail can be displayed.
*/
function wowpress_can_show_post_thumbnail() {
return apply_filters( 'wowpress_can_show_post_thumbnail', ! post_password_required() && ! is_attachment() && has_post_thumbnail() );
}
/**
* Returns the size for avatars used in the theme.
*/
function wowpress_get_avatar_size() {
return 60;
}
/**
* Create the continue reading link
*
* @param string $more_string The string shown within the more link.
*/
function wowpress_continue_reading_link( $more_string ) {
if ( ! is_admin() ) {
$continue_reading = sprintf(
/* translators: %s: Name of current post. */
wp_kses( __( 'Continue reading %s', 'wowpress' ), array( 'span' => array( 'class' => array() ) ) ),
the_title( '<span class="sr-only">"', '"</span>', false )
);
$more_string = '<a href="' . esc_url( get_permalink() ) . '">' . $continue_reading . '</a>';
}
return $more_string;
}
// Filter the excerpt more link.
add_filter( 'excerpt_more', 'wowpress_continue_reading_link' );
// Filter the content more link.
add_filter( 'the_content_more_link', 'wowpress_continue_reading_link' );
/**
* Outputs a comment in the HTML5 format.
*
* This function overrides the default WordPress comment output in HTML5
* format, adding the required class for Tailwind Typography. Based on the
* `html5_comment()` function from WordPress core.
*
* @param WP_Comment $comment Comment to display.
* @param array $args An array of arguments.
* @param int $depth Depth of the current comment.
*/
function wowpress_html5_comment( $comment, $args, $depth ) {
$tag = ( 'div' === $args['style'] ) ? 'div' : 'li';
$commenter = wp_get_current_commenter();
$show_pending_links = ! empty( $commenter['comment_author'] );
if ( $commenter['comment_author_email'] ) {
$moderation_note = __( 'Your comment is awaiting moderation.', 'wowpress' );
} else {
$moderation_note = __( 'Your comment is awaiting moderation. This is a preview; your comment will be visible after it has been approved.', 'wowpress' );
}
?>
<<?php echo esc_attr( $tag ); ?> id="comment-<?php comment_ID(); ?>" <?php comment_class( $comment->has_children ? 'parent' : '', $comment ); ?>>
<article id="div-comment-<?php comment_ID(); ?>" class="comment-body">
<footer class="comment-meta">
<div class="comment-author vcard">
<?php
if ( 0 !== $args['avatar_size'] ) {
echo get_avatar( $comment, $args['avatar_size'] );
}
?>
<?php
$comment_author = get_comment_author_link( $comment );
if ( '0' === $comment->comment_approved && ! $show_pending_links ) {
$comment_author = get_comment_author( $comment );
}
printf(
/* translators: %s: Comment author link. */
wp_kses_post( __( '%s <span class="says">says:</span>', 'wowpress' ) ),
sprintf( '<b class="fn">%s</b>', wp_kses_post( $comment_author ) )
);
?>
</div><!-- .comment-author -->
<div class="comment-metadata">
<?php
printf(
'<a href="%s"><time datetime="%s">%s</time></a>',
esc_url( get_comment_link( $comment, $args ) ),
esc_attr( get_comment_time( 'c' ) ),
esc_html(
sprintf(
/* translators: 1: Comment date, 2: Comment time. */
__( '%1$s at %2$s', 'wowpress' ),
get_comment_date( '', $comment ),
get_comment_time()
)
)
);
edit_comment_link( __( 'Edit', 'wowpress' ), ' <span class="edit-link">', '</span>' );
?>
</div><!-- .comment-metadata -->
<?php if ( '0' === $comment->comment_approved ) : ?>
<em class="comment-awaiting-moderation"><?php echo esc_html( $moderation_note ); ?></em>
<?php endif; ?>
</footer><!-- .comment-meta -->
<div <?php wowpress_content_class( 'comment-content' ); ?>>
<?php comment_text(); ?>
</div><!-- .comment-content -->
<?php
if ( '1' === $comment->comment_approved || $show_pending_links ) {
comment_reply_link(
array_merge(
$args,
array(
'add_below' => 'div-comment',
'depth' => $depth,
'max_depth' => $args['max_depth'],
'before' => '<div class="reply">',
'after' => '</div>',
)
)
);
}
?>
</article><!-- .comment-body -->
<?php
}

View File

@ -0,0 +1,306 @@
<?php
/**
* Custom template tags for this theme
*
* Eventually, some functionality here could be replaced by core features.
*
* @package WowPress
*/
if ( ! function_exists( 'wowpress_posted_on' ) ) :
/**
* Prints HTML with meta information for the current post-date/time.
*/
function wowpress_posted_on() {
$time_string = '<time datetime="%1$s">%2$s</time>';
if ( get_the_time( 'U' ) !== get_the_modified_time( 'U' ) ) {
$time_string = '<time datetime="%1$s">%2$s</time><time datetime="%3$s">%4$s</time>';
}
$time_string = sprintf(
$time_string,
esc_attr( get_the_date( DATE_W3C ) ),
esc_html( get_the_date() ),
esc_attr( get_the_modified_date( DATE_W3C ) ),
esc_html( get_the_modified_date() )
);
printf(
'<a href="%1$s" rel="bookmark">%2$s</a>',
esc_url( get_permalink() ),
$time_string // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
);
}
endif;
if ( ! function_exists( 'wowpress_posted_by' ) ) :
/**
* Prints HTML with meta information about theme author.
*/
function wowpress_posted_by() {
printf(
/* translators: 1: posted by label, only visible to screen readers. 2: author link. 3: post author. */
'<span class="sr-only">%1$s</span><span class="author vcard"><a class="url fn n" href="%2$s">%3$s</a></span>',
esc_html__( 'Posted by', 'wowpress' ),
esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ),
esc_html( get_the_author() )
);
}
endif;
if ( ! function_exists( 'wowpress_comment_count' ) ) :
/**
* Prints HTML with the comment count for the current post.
*/
function wowpress_comment_count() {
if ( ! post_password_required() && ( comments_open() || get_comments_number() ) ) {
/* translators: %s: Name of current post. Only visible to screen readers. */
comments_popup_link( sprintf( __( 'Leave a comment<span class="sr-only"> on %s</span>', 'wowpress' ), get_the_title() ) );
}
}
endif;
if ( ! function_exists( 'wowpress_entry_meta' ) ) :
/**
* Prints HTML with meta information for the categories, tags and comments.
* This template tag is used in the entry header.
*/
function wowpress_entry_meta() {
// Hide author, post date, category and tag text for pages.
if ( 'post' === get_post_type() ) {
// Posted by.
wowpress_posted_by();
// Posted on.
wowpress_posted_on();
/* translators: used between list items, there is a space after the comma. */
$categories_list = get_the_category_list( __( ', ', 'wowpress' ) );
if ( $categories_list ) {
printf(
/* translators: 1: posted in label, only visible to screen readers. 2: list of categories. */
'<span class="sr-only">%1$s</span>%2$s',
esc_html__( 'Posted in', 'wowpress' ),
$categories_list // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
);
}
/* translators: used between list items, there is a space after the comma. */
$tags_list = get_the_tag_list( '', __( ', ', 'wowpress' ) );
if ( $tags_list ) {
printf(
/* translators: 1: tags label, only visible to screen readers. 2: list of tags. */
'<span class="sr-only">%1$s</span>%2$s',
esc_html__( 'Tags:', 'wowpress' ),
$tags_list // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
);
}
}
// Comment count.
if ( ! is_singular() ) {
wowpress_comment_count();
}
// Edit post link.
edit_post_link(
sprintf(
wp_kses(
/* translators: %s: Name of current post. Only visible to screen readers. */
__( 'Edit <span class="sr-only">%s</span>', 'wowpress' ),
array(
'span' => array(
'class' => array(),
),
)
),
get_the_title()
)
);
}
endif;
if ( ! function_exists( 'wowpress_entry_footer' ) ) :
/**
* Prints HTML with meta information for the categories, tags and comments.
*/
function wowpress_entry_footer() {
// Hide author, post date, category and tag text for pages.
if ( 'post' === get_post_type() ) {
// Posted by.
wowpress_posted_by();
// Posted on.
wowpress_posted_on();
/* translators: used between list items, there is a space after the comma. */
$categories_list = get_the_category_list( __( ', ', 'wowpress' ) );
if ( $categories_list ) {
printf(
/* translators: 1: posted in label, only visible to screen readers. 2: list of categories. */
'<span class="sr-only">%1$s</span>%2$s',
esc_html__( 'Posted in', 'wowpress' ),
$categories_list // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
);
}
/* translators: used between list items, there is a space after the comma. */
$tags_list = get_the_tag_list( '', __( ', ', 'wowpress' ) );
if ( $tags_list ) {
printf(
/* translators: 1: tags label, only visible to screen readers. 2: list of tags. */
'<span class="sr-only">%1$s</span>%2$s',
esc_html__( 'Tags:', 'wowpress' ),
$tags_list // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
);
}
}
// Comment count.
if ( ! is_singular() ) {
wowpress_comment_count();
}
// Edit post link.
edit_post_link(
sprintf(
wp_kses(
/* translators: %s: Name of current post. Only visible to screen readers. */
__( 'Edit <span class="sr-only">%s</span>', 'wowpress' ),
array(
'span' => array(
'class' => array(),
),
)
),
get_the_title()
)
);
}
endif;
if ( ! function_exists( 'wowpress_post_thumbnail' ) ) :
/**
* Displays an optional post thumbnail, wrapping the post thumbnail in an
* anchor element except when viewing a single post.
*/
function wowpress_post_thumbnail() {
if ( ! wowpress_can_show_post_thumbnail() ) {
return;
}
if ( is_singular() ) :
?>
<figure>
<?php the_post_thumbnail(); ?>
</figure><!-- .post-thumbnail -->
<?php
else :
?>
<figure>
<a href="<?php the_permalink(); ?>" aria-hidden="true" tabindex="-1">
<?php the_post_thumbnail(); ?>
</a>
</figure>
<?php
endif; // End is_singular().
}
endif;
if ( ! function_exists( 'wowpress_comment_avatar' ) ) :
/**
* Returns the HTML markup to generate a user avatar.
*
* @param mixed $id_or_email The Gravatar to retrieve. Accepts a user_id, gravatar md5 hash,
* user email, WP_User object, WP_Post object, or WP_Comment object.
*/
function wowpress_get_user_avatar_markup( $id_or_email = null ) {
if ( ! isset( $id_or_email ) ) {
$id_or_email = get_current_user_id();
}
return sprintf( '<div class="vcard">%s</div>', get_avatar( $id_or_email, wowpress_get_avatar_size() ) );
}
endif;
if ( ! function_exists( 'wowpress_discussion_avatars_list' ) ) :
/**
* Displays a list of avatars involved in a discussion for a given post.
*
* @param array $comment_authors Comment authors to list as avatars.
*/
function wowpress_discussion_avatars_list( $comment_authors ) {
if ( empty( $comment_authors ) ) {
return;
}
echo '<ol>', "\n";
foreach ( $comment_authors as $id_or_email ) {
printf(
"<li>%s</li>\n",
wowpress_get_user_avatar_markup( $id_or_email ) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
);
}
echo '</ol>', "\n";
}
endif;
if ( ! function_exists( 'wowpress_the_posts_navigation' ) ) :
/**
* Wraps `the_posts_pagination` for use throughout the theme.
*/
function wowpress_the_posts_navigation() {
the_posts_pagination(
array(
'mid_size' => 2,
'prev_text' => __( 'Newer posts', 'wowpress' ),
'next_text' => __( 'Older posts', 'wowpress' ),
)
);
}
endif;
if ( ! function_exists( 'wowpress_content_class' ) ) :
/**
* Displays the class names for the post content wrapper.
*
* This allows us to add Tailwind Typographys modifier classes throughout
* the theme without repeating them in multiple files. (They can be edited
* at the top of the `../functions.php` file via the
* WOWPRESS_TYPOGRAPHY_CLASSES constant.)
*
* Based on WordPress cores `body_class` and `get_body_class` functions.
*
* @param array $classes Space-separated string or array of class names to
* add to the class list.
*/
function wowpress_content_class( $classes = '' ) {
$all_classes = array( $classes, WOWPRESS_TYPOGRAPHY_CLASSES );
foreach ( $all_classes as &$class_groups ) {
if ( ! empty( $class_groups ) ) {
if ( ! is_array( $class_groups ) ) {
$class_groups = preg_split( '#\s+#', $class_groups );
}
} else {
// Ensure that we always coerce class to being an array.
$class_groups = array();
}
}
$combined_classes = array_merge( $all_classes[0], $all_classes[1] );
$combined_classes = array_map( 'esc_attr', $combined_classes );
// Separates class names with a single space, preparing them for the
// post content wrapper.
echo 'class="' . esc_attr( implode( ' ', $combined_classes ) ) . '"';
}
endif;

52
theme/index.php 100644
View File

@ -0,0 +1,52 @@
<?php
/**
* The main template file
*
* This is the most generic template file in a WordPress theme
* and one of the two required files for a theme (the other being style.css).
* It is used to display a page when nothing more specific matches a query.
* E.g., it puts together the home page when no `home.php` file exists.
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package WowPress
*/
get_header();
?>
<section id="primary">
<main id="main">
<?php
if ( have_posts() ) {
if ( is_home() && ! is_front_page() ) :
?>
<header class="entry-header">
<h1 class="entry-title"><?php single_post_title(); ?></h1>
</header><!-- .entry-header -->
<?php
endif;
// Load posts loop.
while ( have_posts() ) {
the_post();
get_template_part( 'template-parts/content/content' );
}
// Previous/next page navigation.
wowpress_the_posts_navigation();
} else {
// If no content, include the "No posts found" template.
get_template_part( 'template-parts/content/content', 'none' );
}
?>
</main><!-- #main -->
</section><!-- #primary -->
<?php
get_footer();

View File

@ -0,0 +1,11 @@
The three JavaScript files at `../../javascript` will be processed by esbuild,
and the output files will be created in this folder with `.min.js` extensions.
The files `script.min.js`, `block-editor.min.js` and
`tailwind-typography-classes.js` are enqueued by default in `../functions.php`.
If you would like to add new files to be processed by esbuild, add them to the
`../../javascript` folder and then add them to the `development:esbuild` key in
your `package.json` file.
DO NOT directly edit `*.min.js` files, as these files are ignored by git and
will be overwritten the next time esbuild runs.

View File

@ -0,0 +1,6 @@
{
"Warlock" : "Hexenmeister",
"Destruction": "Zerstörung",
"Evoker" : "Rufer",
"Devastation" : "Verheerung"
}

View File

@ -0,0 +1,7 @@
Place your themes language files in this directory.
Please visit the following links to learn more about translating WordPress themes:
https://make.wordpress.org/polyglots/teams/
https://developer.wordpress.org/themes/functionality/localization/
https://developer.wordpress.org/reference/functions/load_theme_textdomain/

View File

@ -0,0 +1,63 @@
<?php
/* ------------------ */
/* theme options page */
/* ------------------ */
add_action( 'admin_init', 'theme_options_init' );
add_action( 'admin_menu', 'theme_options_add_page' );
// Einstellungen registrieren (http://codex.wordpress.org/Function_Reference/register_setting)
function theme_options_init(){
register_setting( 'wowpress_options', 'wowpress_api', 'kb_validate_options' );
}
// Seite in der Dashboard-Navigation erstellen
function theme_options_add_page() {
add_theme_page('API-Einstellungen', 'API-Einstellungen', 'edit_theme_options', 'api_options', 'wowpress_api_options_page' ); // Seitentitel, Titel in der Navi, Berechtigung zum Editieren (http://codex.wordpress.org/Roles_and_Capabilities) , Slug, Funktion
}
// Optionen-Seite erstellen
function wowpress_api_options_page() {
global $select_options, $radio_options;
if ( ! isset( $_REQUEST['settings-updated'] ) )
$_REQUEST['settings-updated'] = false; ?>
<div class="wrap">
<?php screen_icon(); ?><h2>API-Optionen für <?php bloginfo('name'); ?></h2>
<?php if ( false !== $_REQUEST['settings-updated'] ) : ?>
<div class="updated fade">
<p><strong>Einstellungen gespeichert!</strong></p>
</div>
<?php endif; ?>
<form method="post" action="options.php">
<?php settings_fields( 'wowpress_options' ); ?>
<?php $options = get_option( 'wowpress_api' ); ?>
<table class="form-table">
<tr valign="top">
<th scope="row">BattleNet - Identifier</th>
<td><input id="wowpress_api[bnet][id]" class="regular-text" type="text" name="wowpress_api[bnet][id]" value="<?php esc_attr_e( $options['bnet']['id'] ); ?>" /></td>
</tr>
<tr valign="top">
<th scope="row">BattleNet - Key</th>
<td><input id="wowpress_api[bnet][key]" class="regular-text" type="text" name="wowpress_api[bnet][key]" value="<?php esc_attr_e( $options['bnet']['key'] ); ?>" /></td>
</tr>
</table>
<!-- submit -->
<p class="submit"><input type="submit" class="button-primary" value="Einstellungen speichern" /></p>
</form>
</div>
<?php }
// Strip HTML-Code:
// Hier kann definiert werden, ob HTML-Code in einem Eingabefeld
// automatisch entfernt werden soll. Soll beispielsweise im
// Copyright-Feld KEIN HTML-Code erlaubt werden, kommentiert die Zeile
// unten wieder ein. http://codex.wordpress.org/Function_Reference/wp_filter_nohtml_kses
function kb_validate_options( $input ) {
// $input['copyright'] = wp_filter_nohtml_kses( $input['copyright'] );
return $input;
}

41
theme/page.php 100644
View File

@ -0,0 +1,41 @@
<?php
/**
* The template for displaying all pages
*
* This is the template that displays all pages by default. Please note that
* this is the WordPress construct of pages: specifically, posts with a post
* type of `page`.
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package WowPress
*/
get_header();
?>
<section id="primary">
<main id="main">
<?php
/* Start the Loop */
while ( have_posts() ) :
the_post();
get_template_part( 'template-parts/content/content', 'page' );
// If comments are open, or we have at least one comment, load
// the comment template.
if ( comments_open() || get_comments_number() ) {
comments_template();
}
endwhile; // End of the loop.
?>
</main><!-- #main -->
</section><!-- #primary -->
<?php
get_footer();

Some files were not shown because too many files have changed in this diff Show More