✨feature: Initial commit
This commit is contained in:
@@ -0,0 +1,12 @@
|
|||||||
|
# EditorConfig is awesome: https://EditorConfig.org
|
||||||
|
|
||||||
|
# top-most EditorConfig file
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
LOCALHOST_URL=http://domain.local
|
||||||
|
BROWSERSYNC_PORT=5000
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
name: PHPCS check
|
||||||
|
on:
|
||||||
|
# push:
|
||||||
|
pull_request:
|
||||||
|
# Allow manually triggering the workflow.
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
# Cancel all previous workflow runs for the same branch that have not yet completed.
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
phpcs:
|
||||||
|
name: PHPCS
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Setup PHP
|
||||||
|
uses: "shivammathur/setup-php@v2"
|
||||||
|
with:
|
||||||
|
php-version: "8.2"
|
||||||
|
ini-values: "memory_limit=1G"
|
||||||
|
coverage: none
|
||||||
|
tools: cs2pr
|
||||||
|
- name: Install Composer dependencies
|
||||||
|
uses: "ramsey/composer-install@v3"
|
||||||
|
- name: Run PHPCS checks
|
||||||
|
continue-on-error: true
|
||||||
|
run: vendor/bin/phpcs --standard=.phpcs.xml --report-full --report-checkstyle=./phpcs-report.xml .
|
||||||
|
- name: Show PHPCS results in PR
|
||||||
|
run: cs2pr ./phpcs-report.xml
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
name: Sync TODOs with Issues
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
sync_todos:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Sync TODOs
|
||||||
|
uses: Solo-Web-Works/TODO-Sync@v2
|
||||||
|
with:
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
summary_file: TODO_SUMMARY.md
|
||||||
|
dry_run: false
|
||||||
|
commit: false
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
name: Deploy to WPEngine
|
||||||
|
on:
|
||||||
|
workflow_dispatch
|
||||||
|
# Remove "workflow_dispatch" above and uncomment the lines below to enable deploy on push
|
||||||
|
# only do this once you're actually ready to start deploying to Flywheel
|
||||||
|
# push:
|
||||||
|
# branches:
|
||||||
|
# - main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: ${{ !contains(github.event.head_commit.message, '#skipGA') }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Get Composer Cache Directory
|
||||||
|
id: composer-cache
|
||||||
|
run: |
|
||||||
|
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: ${{ steps.composer-cache.outputs.dir }}
|
||||||
|
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-composer-
|
||||||
|
|
||||||
|
- name: Install PHP Composer
|
||||||
|
uses: php-actions/composer@v6
|
||||||
|
with:
|
||||||
|
php_version: "8.2"
|
||||||
|
|
||||||
|
- name: Cache node modules
|
||||||
|
id: cache-npm
|
||||||
|
uses: actions/cache@v3
|
||||||
|
env:
|
||||||
|
cache-name: cache-node-modules
|
||||||
|
with:
|
||||||
|
# npm cache files are stored in `~/.npm` on Linux/macOS
|
||||||
|
path: ~/.npm
|
||||||
|
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-build-${{ env.cache-name }}-
|
||||||
|
${{ runner.os }}-build-
|
||||||
|
${{ runner.os }}-
|
||||||
|
|
||||||
|
- name: Install npm dependencies
|
||||||
|
run: npm install
|
||||||
|
|
||||||
|
- name: Run build task
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
- name: Clean up node modules (not needed to deploy)
|
||||||
|
run: rm -rf node_modules
|
||||||
|
|
||||||
|
- name: Deploy to WPE
|
||||||
|
uses: wpengine/github-action-wpe-site-deploy@v3
|
||||||
|
with:
|
||||||
|
WPE_SSHG_KEY_PRIVATE: ${{ secrets.WPE_SSHG_KEY_PRIVATE }}
|
||||||
|
WPE_ENV: vdiv5
|
||||||
|
FLAGS: '-azvr --inplace --delete --exclude=".*"'
|
||||||
|
REMOTE_PATH: "wp-content/themes/vdi-v5"
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
*~
|
||||||
|
.DS_Store
|
||||||
|
vendor
|
||||||
|
node_modules
|
||||||
|
static/dist/
|
||||||
|
.env
|
||||||
|
bak/
|
||||||
|
testimonials.class.php
|
||||||
|
resource-filter/
|
||||||
|
phpcs-results.txt
|
||||||
|
|
||||||
|
# Playwright
|
||||||
|
/test-results/
|
||||||
|
/playwright-report/
|
||||||
|
/blob-report/
|
||||||
|
/playwright/.cache/
|
||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<ruleset name="Coding Style Checks">
|
||||||
|
<description>Coding Style Checks.</description>
|
||||||
|
<ini name="error_reporting" value="E_ALL & ~E_DEPRECATED" />
|
||||||
|
|
||||||
|
<arg value="sp"/>
|
||||||
|
<arg name="colors"/>
|
||||||
|
<arg name="extensions" value="php,html"/>
|
||||||
|
<arg name="parallel" value="2048"/>
|
||||||
|
|
||||||
|
<exclude-pattern>vendor/</exclude-pattern>
|
||||||
|
<exclude-pattern>node_modules/</exclude-pattern>
|
||||||
|
|
||||||
|
<rule ref="WordPress">
|
||||||
|
<exclude name="Generic.WhiteSpace.DisallowSpaceIndent.SpacesUsed"/>
|
||||||
|
<exclude name="Generic.Functions.CallTimePassByReference"/>
|
||||||
|
<exclude name="Universal.WhiteSpace.PrecisionAlignment.Found"/>
|
||||||
|
<exclude name="WordPress.WP.I18n.NonSingularStringLiteralText"/>
|
||||||
|
<exclude name="WordPress.WP.I18n.NonSingularStringLiteralDomain"/>
|
||||||
|
<exclude name="WordPress.WP.I18n.NoEmptyStrings"/>
|
||||||
|
<exclude name="WordPress.WP.EnqueuedResourceParameters.MissingVersion"/>
|
||||||
|
<exclude name="WordPress.PHP.YodaConditions.NotYoda"/>
|
||||||
|
<exclude name="WordPress.PHP.NoSilencedErrors.Discouraged"/>
|
||||||
|
<exclude name="WordPress.Files.FileName.NotHyphenatedLowercase"/>
|
||||||
|
<exclude name="WordPress.Files.FileName.InvalidClassFileName"/>
|
||||||
|
<exclude name="WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase"/>
|
||||||
|
<exclude name="WordPress.NamingConventions.ValidVariableName.InterpolatedVariableNotSnakeCase"/>
|
||||||
|
<exclude name="WordPress.NamingConventions.ValidVariableName.PropertyNotSnakeCase"/>
|
||||||
|
<exclude name="WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase"/>
|
||||||
|
<exclude name="WordPress.NamingConventions.ValidHookName.NotLowercase"/>
|
||||||
|
<exclude name="WordPress.NamingConventions.ValidHookName.UseUnderscores"/>
|
||||||
|
<exclude name="WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid"/>
|
||||||
|
<exclude name="WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid"/>
|
||||||
|
<exclude name="WordPress.DB.SlowDBQuery.slow_db_query_tax_query"/>
|
||||||
|
<exclude name="WordPress.DB.SlowDBQuery.slow_db_query_meta_query"/>
|
||||||
|
<exclude name="WordPress.Security.NonceVerification.Recommended"/>
|
||||||
|
<exclude name="Squiz.Commenting.FileComment.MissingPackageTag"/>
|
||||||
|
<exclude name="Squiz.Commenting.FileComment.Missing"/>
|
||||||
|
<exclude name="Squiz.Commenting.FileComment.WrongStyle"/>
|
||||||
|
<exclude name="Squiz.Commenting.InlineComment.InvalidEndChar"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule ref="Internal.NoCodeFound">
|
||||||
|
<severity>0</severity>
|
||||||
|
</rule>
|
||||||
|
</ruleset>
|
||||||
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"workbench.colorCustomizations": {
|
||||||
|
"tree.indentGuidesStroke": "#3d92ec",
|
||||||
|
"activityBar.background": "#213309",
|
||||||
|
"titleBar.activeBackground": "#2E470C",
|
||||||
|
"titleBar.activeForeground": "#F6FCEE",
|
||||||
|
"titleBar.inactiveBackground": "#213209",
|
||||||
|
"titleBar.inactiveForeground": "#F7FCEF",
|
||||||
|
"statusBar.background": "#213209",
|
||||||
|
"statusBar.foreground": "#F7FCEF",
|
||||||
|
"statusBar.debuggingBackground": "#213209",
|
||||||
|
"statusBar.debuggingForeground": "#F7FCEF",
|
||||||
|
"statusBar.noFolderBackground": "#213209",
|
||||||
|
"statusBar.noFolderForeground": "#F7FCEF"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Page Not Found
|
||||||
|
*
|
||||||
|
* @package BasicWP
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace BasicWP;
|
||||||
|
|
||||||
|
get_header();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<section class="error-404 container">
|
||||||
|
<h2>Page Not Found</h2>
|
||||||
|
<h3>Sorry, the page you're looking for doesn't exist.</h3>
|
||||||
|
|
||||||
|
<p>It might have been removed, had its name changed, or is temporarily unavailable.</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<form role="search" method="get" class="search-form" action="<?php echo esc_url( home_url( '/' ) ); ?>">
|
||||||
|
<label>
|
||||||
|
<span class="screen-reader-text"><?php echo esc_html__( 'Search for:', 'label' ); ?></span>
|
||||||
|
Try searching for it: <input type="search" class="search-field border border-secondary px-2 rounded-md" placeholder="<?php echo esc_attr_x( 'Search …', 'placeholder' ); ?>" value="<?php echo get_search_query(); ?>" name="s" title="<?php echo esc_attr__( 'Search for:', 'label' ); ?>" />
|
||||||
|
</label>
|
||||||
|
<x-button
|
||||||
|
btnClasses="search-submit button text-center"
|
||||||
|
element="button"
|
||||||
|
type="submit"
|
||||||
|
title="<?php echo esc_attr__( 'Search', 'submit button' ); ?>"
|
||||||
|
color="primary"
|
||||||
|
variant="default"
|
||||||
|
size="small"
|
||||||
|
width="auto"
|
||||||
|
></x-button>
|
||||||
|
</form>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>Or check out the links below:</p>
|
||||||
|
<ul class="list-inside">
|
||||||
|
<li><a href="<?php echo esc_url( home_url( '/' ) ); ?>">Home</a></li>
|
||||||
|
<li><a href="<?php echo esc_url( home_url( '/news' ) ); ?>">Posts</a></li>
|
||||||
|
<li>If all else fails, <a href="<?php echo esc_url( home_url( '/contact' ) ); ?>">Contact Us</a></li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<?php get_footer(); ?>
|
||||||
@@ -0,0 +1,488 @@
|
|||||||
|
# VDI WordPress Theme Starter v5
|
||||||
|
|
||||||
|
VDI WordPress Theme Starter v5 is a minimal WordPress theme designed as a starting point for custom theme development. It focuses on modern development approaches with a lean architecture that avoids the overhead of theme frameworks.
|
||||||
|
|
||||||
|
Repo: [https://github.com/Vincent-Design-Inc/VDI-Starter-v5](https://github.com/Vincent-Design-Inc/VDI-Starter-v5)
|
||||||
|
AC Bug/Issue Tracking: [https://next-app.activecollab.com/119590/projects/4553?modal=Task-98192-4553](https://next-app.activecollab.com/119590/projects/4553?modal=Task-98192-4553)
|
||||||
|
|
||||||
|
## Key Features
|
||||||
|
|
||||||
|
- Tailwind CSS
|
||||||
|
- Namespaced PHP for isolation
|
||||||
|
- Built-in support for ACF blocks
|
||||||
|
- Fast development workflow with watch and compile functions
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
VDI-Starter-v5/
|
||||||
|
├── acf/ # ACF field group JSON definitions
|
||||||
|
├── bin/ # Build scripts
|
||||||
|
├── content/ # Sample page and post content for testing
|
||||||
|
├── lib/ # PHP library files
|
||||||
|
│ ├── class-breadcrumbs.php # Breadcrumb generation
|
||||||
|
│ ├── class-acf.php # ACF integration
|
||||||
|
│ ├── class-enqueue.php # Assets enqueuing
|
||||||
|
│ ├── class-menuitems.php # Navigation menu builder
|
||||||
|
│ ├── class-resources.php # Custom Resources post type
|
||||||
|
│ ├── extras.php # Miscellaneous theme functions
|
||||||
|
│ ├── helpers.php # Helper functions
|
||||||
|
│ ├── hooks.php # WordPress hooks and filters
|
||||||
|
│ ├── search-features.php # Enhanced search functionality
|
||||||
|
│ └── show-template.php # Script to show which template is used for the current page
|
||||||
|
├── static/ # Static assets
|
||||||
|
│ ├── dist/ # Compiled assets
|
||||||
|
│ ├── img/ # Static theme images
|
||||||
|
│ └── js/ # JavaScript files
|
||||||
|
│ ├── components/ # JS components
|
||||||
|
│ │ └── button.js # Button custom component
|
||||||
|
│ ├── modules/ # JS theme modules
|
||||||
|
│ │ ├── GetHeaderHeight.js # Calculate header height and set it as a CSS variable
|
||||||
|
│ │ ├── Navigation.js # Script controlling navigation behavior
|
||||||
|
│ │ └── TagExternalLinks.js # Tags external links with appropriate attributes
|
||||||
|
│ ├── admin.js # Admin-specific JS
|
||||||
|
│ └── theme.js # Main theme JS
|
||||||
|
├── styles/ # CSS styles
|
||||||
|
│ ├── backend/ # Admin styles
|
||||||
|
│ ├── base/ # Base styles
|
||||||
|
│ ├── blocks/ # Block styles
|
||||||
|
│ ├── components/ # Component styles
|
||||||
|
│ ├── fonts/ # Font styles
|
||||||
|
│ └── theme.css # Main CSS entry point
|
||||||
|
├── tests/ # Automated Playwright tests
|
||||||
|
│ └── site-a11y.spec.js # Site Accessibility tests
|
||||||
|
├── views/ # Template views
|
||||||
|
│ ├── blocks/ # Custom ACF blocks
|
||||||
|
│ ├── icons/ # SVG icons
|
||||||
|
│ ├── forms/ # Form templates
|
||||||
|
│ └── partials/ # Reusable template parts
|
||||||
|
├── 404.php # 404 error template
|
||||||
|
├── footer.php # Footer template
|
||||||
|
├── front-page.php # Front page template
|
||||||
|
├── functions.php # Main functions file
|
||||||
|
├── header.php # Header template
|
||||||
|
├── index.php # Main template
|
||||||
|
├── page.php # Page template
|
||||||
|
├── search.php # Search results template
|
||||||
|
├── sidebar.php # Main sidebar template
|
||||||
|
├── sidebar-page.php # Page sidebar template
|
||||||
|
├── single.php # Single post template
|
||||||
|
├── style.css # Theme metadata
|
||||||
|
└── whitelist.php # Tailwind class whitelist
|
||||||
|
```
|
||||||
|
|
||||||
|
## Core Files and Templates
|
||||||
|
|
||||||
|
### Theme Core Files
|
||||||
|
|
||||||
|
- **style.css**: Contains theme metadata and registration information
|
||||||
|
- **functions.php**: Initializes the theme and loads necessary dependencies
|
||||||
|
- **class-acf.php**: Handles Advanced Custom Fields (ACF) functionality
|
||||||
|
- **class-breadcrumbs.php**: Generates breadcrumb navigation for the site
|
||||||
|
- **class-enqueue.php**: Manages script and style enqueuing for frontend and backend
|
||||||
|
- **class-menuitems.php**: Builder for the navigation menus
|
||||||
|
- **class-resources.php**: Custom post type management for "Resources", included as an example of CPT usage
|
||||||
|
- **extras.php**: Miscellaneous theme functions, including sidebar and page header checks
|
||||||
|
- **helpers.php**: Utility functions for common tasks
|
||||||
|
- **hooks.php**: Contains WordPress hooks and filters for theme functionality
|
||||||
|
- **search-features.php**: Enhances search functionality with custom queries and filters
|
||||||
|
- **show-template.php**: Outputs the current template file being used for debugging
|
||||||
|
- **whitelist.php**: Contains Tailwind CSS class whitelist for styles used in WordPress editor
|
||||||
|
|
||||||
|
### Template Files
|
||||||
|
|
||||||
|
- **header.php**: Defines the site header with primary navigation
|
||||||
|
- **footer.php**: Defines the site footer with widget areas and copyright
|
||||||
|
- **front-page.php**: Template for the front page of the site
|
||||||
|
- **page.php**: Displays individual static pages with optional sidebar
|
||||||
|
- **index.php**: Main template file that displays the blog posts list
|
||||||
|
- **single.php**: Displays individual posts with author and category information
|
||||||
|
- **search.php**: Displays search results with pagination
|
||||||
|
- **404.php**: Custom "Page Not Found" template with search form
|
||||||
|
- **sidebar.php**: Primary sidebar template
|
||||||
|
- **sidebar-page.php**: Page-specific sidebar template
|
||||||
|
- **views/forms/search.php** - Search form template for use in various locations
|
||||||
|
|
||||||
|
### Included Blocks
|
||||||
|
|
||||||
|
- **Boilerplate**: Example block for custom development
|
||||||
|
- **Accordion**: Collapsible content sections
|
||||||
|
- **Buttons**: Group of buttons
|
||||||
|
- **Button**: Configurable button element
|
||||||
|
- **Grid**: Flexible grid layout system
|
||||||
|
- **Grid Cell**: Individual grid item
|
||||||
|
- **Homepage Hero**: Hero section typically used on homepage
|
||||||
|
- **Media Text**: Image or video with accompanying text
|
||||||
|
- **Media Text with Inner Blocks**: Media-text with nested block support
|
||||||
|
- **Page Children**: Displays child pages of current page
|
||||||
|
- **Section**: Container block with background and width (contained and full-screen width) options
|
||||||
|
|
||||||
|
## Library Functions and Classes
|
||||||
|
|
||||||
|
### helpers.php
|
||||||
|
|
||||||
|
```php
|
||||||
|
getFieldValue($field_path)
|
||||||
|
```
|
||||||
|
|
||||||
|
- Retrieves a nested value from an ACF field using dot notation
|
||||||
|
- **Parameters**: `$field_path` - The dot-notated path to the value (e.g., `contact_info.phone`)
|
||||||
|
- **Returns**: The value at the specified path
|
||||||
|
|
||||||
|
```php
|
||||||
|
customMenuOrder($menu_ord)
|
||||||
|
```
|
||||||
|
|
||||||
|
- Customizes the order of admin menu items in WordPress dashboard
|
||||||
|
- Add other admin menu URLs to the array to change their order
|
||||||
|
- **Parameters**: `$menu_ord` - The existing menu order array
|
||||||
|
- **Returns**: Array specifying the custom menu order, or true for default order
|
||||||
|
|
||||||
|
```php
|
||||||
|
blockCategories($categories)
|
||||||
|
```
|
||||||
|
|
||||||
|
- Adds custom block category for theme blocks
|
||||||
|
- **Parameters**: `$categories` - The existing block categories
|
||||||
|
- **Returns**: Modified array of categories
|
||||||
|
|
||||||
|
```php
|
||||||
|
consoleLog($data)
|
||||||
|
```
|
||||||
|
|
||||||
|
- Utility function to print a variable to the console for debugging
|
||||||
|
- **Parameters**: `$data` - The data to print to the console
|
||||||
|
|
||||||
|
### search-features.php
|
||||||
|
|
||||||
|
```php
|
||||||
|
pageSearch($query)
|
||||||
|
```
|
||||||
|
|
||||||
|
- Modifies the WordPress query for page search functionality
|
||||||
|
- **Parameters**: `$query` - The WordPress query object
|
||||||
|
- **Returns**: void
|
||||||
|
|
||||||
|
```php
|
||||||
|
postSort($key)
|
||||||
|
```
|
||||||
|
|
||||||
|
- Returns a sorting function for WP_Post objects in reverse order
|
||||||
|
- **Parameters**: `$key` - WP_Post object property used for sorting
|
||||||
|
- **Returns**: Sorting function
|
||||||
|
|
||||||
|
```php
|
||||||
|
dedupe($posts, $key)
|
||||||
|
```
|
||||||
|
|
||||||
|
- Removes duplicate posts based on a specified key
|
||||||
|
- **Parameters**:
|
||||||
|
- `$posts` - Array of posts
|
||||||
|
- `$key` - Key to check for duplicates
|
||||||
|
- **Returns**: Filtered array of posts
|
||||||
|
|
||||||
|
```php
|
||||||
|
searchResultFilter($posts, $query)
|
||||||
|
```
|
||||||
|
|
||||||
|
- Filters and processes search results
|
||||||
|
- **Parameters**:
|
||||||
|
- `$posts` - Array of posts
|
||||||
|
- `$query` - The search query
|
||||||
|
- **Returns**: Filtered array of posts
|
||||||
|
|
||||||
|
### extras.php
|
||||||
|
|
||||||
|
```php
|
||||||
|
getChildrenPages()
|
||||||
|
```
|
||||||
|
|
||||||
|
- Gets child pages of the current page
|
||||||
|
- **Returns**: Array of child pages or empty array
|
||||||
|
|
||||||
|
```php
|
||||||
|
hasSidebar()
|
||||||
|
```
|
||||||
|
|
||||||
|
- Checks if sidebar should be rendered
|
||||||
|
- **Returns**: Boolean indicating sidebar presence
|
||||||
|
|
||||||
|
```php
|
||||||
|
hasPageHeader()
|
||||||
|
```
|
||||||
|
|
||||||
|
- Checks if the page should render a page header
|
||||||
|
- **Returns**: Boolean indicating page header presence
|
||||||
|
|
||||||
|
```php
|
||||||
|
createOwnerRole()
|
||||||
|
```
|
||||||
|
|
||||||
|
- Creates a new WordPress role named "Owner" with admin capabilities minus plugin/theme management
|
||||||
|
- **Returns**: void
|
||||||
|
|
||||||
|
```php
|
||||||
|
getTheTitle()
|
||||||
|
```
|
||||||
|
|
||||||
|
- Gets the title based on the current context (archive, search, etc.)
|
||||||
|
- **Returns**: Appropriate title string
|
||||||
|
|
||||||
|
```php
|
||||||
|
divWrapper($content)
|
||||||
|
```
|
||||||
|
|
||||||
|
- Wraps iframes and embeds in a div with the class "embed"
|
||||||
|
- **Parameters**: `$content` - The content to process
|
||||||
|
- **Returns**: Modified content
|
||||||
|
|
||||||
|
### Class: Resources (class-resources.php)
|
||||||
|
|
||||||
|
Custom post type and taxonomy management for "Resources"
|
||||||
|
|
||||||
|
### Class: Enqueue (class-enqueue.php)
|
||||||
|
|
||||||
|
Manages script and style enqueueing
|
||||||
|
|
||||||
|
```php
|
||||||
|
enqFEAssets()
|
||||||
|
```
|
||||||
|
|
||||||
|
- Enqueues frontend CSS and JS files
|
||||||
|
- **Returns**: void
|
||||||
|
|
||||||
|
```php
|
||||||
|
enqBEAssets()
|
||||||
|
```
|
||||||
|
|
||||||
|
- Enqueues backend (admin/editor) CSS and JS files
|
||||||
|
- **Returns**: void
|
||||||
|
|
||||||
|
### Class: ACF (class-acf.php)
|
||||||
|
|
||||||
|
Handles ACF (Advanced Custom Fields) functionality
|
||||||
|
|
||||||
|
```php
|
||||||
|
saveJson($path)
|
||||||
|
```
|
||||||
|
|
||||||
|
- Sets the path for saving ACF field groups as JSON
|
||||||
|
- **Parameters**: `$path` - The default path
|
||||||
|
- **Returns**: Modified path
|
||||||
|
|
||||||
|
```php
|
||||||
|
loadJson($paths)
|
||||||
|
```
|
||||||
|
|
||||||
|
- Sets the path for loading ACF field groups from JSON
|
||||||
|
- **Parameters**: `$paths` - The default paths
|
||||||
|
- **Returns**: Modified paths array
|
||||||
|
|
||||||
|
### Class: Breadcrumbs (class-breadcrumbs.php)
|
||||||
|
|
||||||
|
Generates and displays breadcrumb navigation
|
||||||
|
|
||||||
|
```php
|
||||||
|
generate()
|
||||||
|
```
|
||||||
|
|
||||||
|
- Generates breadcrumb data based on the current page
|
||||||
|
- **Returns**: Array of breadcrumb items
|
||||||
|
|
||||||
|
```php
|
||||||
|
render()
|
||||||
|
```
|
||||||
|
|
||||||
|
- Renders breadcrumb HTML with schema.org markup
|
||||||
|
- **Returns**: void (echoes HTML)
|
||||||
|
|
||||||
|
The class also includes other helper methods for different page types:
|
||||||
|
|
||||||
|
- `getHomeBreadcrumb()`
|
||||||
|
- `getBlogPostsIndexBreadcrumb()`
|
||||||
|
- `getSinglePostBreadcrumbs()`
|
||||||
|
- `getCustomPostTypeBreadcrumbs()`
|
||||||
|
- `getStaticPageBreadcrumbs($post)`
|
||||||
|
- `getTaxonomyArchiveBreadcrumb()`
|
||||||
|
- `getPostTypeArchiveBreadcrumb()`
|
||||||
|
- `getDateArchiveBreadcrumbs()`
|
||||||
|
- `getMonthArchiveBreadcrumb()`
|
||||||
|
- `getYearArchiveBreadcrumb()`
|
||||||
|
- `getAuthorArchiveBreadcrumb()`
|
||||||
|
- `getSearchBreadcrumb()`
|
||||||
|
- `get404Breadcrumb()`
|
||||||
|
|
||||||
|
## ACF Blocks System
|
||||||
|
|
||||||
|
The theme implements a custom block system using Advanced Custom Fields. Blocks are registered automatically in functions.php via the `regACFBlocks()` function.
|
||||||
|
|
||||||
|
See `views/blocks/boilerplate/` for a starting point for custom blocks.
|
||||||
|
|
||||||
|
### Block Structure
|
||||||
|
|
||||||
|
Each block consists of:
|
||||||
|
|
||||||
|
- PHP template file (block rendering)
|
||||||
|
- CSS file (block-specific styles)
|
||||||
|
- block.json file (block configuration)
|
||||||
|
|
||||||
|
See the [ACF Blocks Documentation](https://www.advancedcustomfields.com/resources/#acf-blocks) for more details on creating custom blocks.
|
||||||
|
|
||||||
|
## JavaScript Components
|
||||||
|
|
||||||
|
The theme utilizes custom web components for enhanced functionality.
|
||||||
|
|
||||||
|
### ButtonComponent
|
||||||
|
|
||||||
|
A custom HTML element for creating buttons with various configurations:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
class ButtonComponent extends HTMLElement {
|
||||||
|
// Attributes:
|
||||||
|
// - btnClasses: Additional CSS classes
|
||||||
|
// - element: The element to use (`a` or `button`)
|
||||||
|
// - type: Button type (for non-anchor elements)
|
||||||
|
// - url: The URL for links
|
||||||
|
// - target: Target attribute for links
|
||||||
|
// - title: Button text
|
||||||
|
// - color: Button color
|
||||||
|
// - variant: Button style variant
|
||||||
|
// - size: Button size
|
||||||
|
// - width: Button width
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<x-button
|
||||||
|
btnClasses="button text-center"
|
||||||
|
element="a"
|
||||||
|
url="https://example.com"
|
||||||
|
target="_blank"
|
||||||
|
title="Click Me"
|
||||||
|
color="primary"
|
||||||
|
variant="default"
|
||||||
|
size="medium"
|
||||||
|
width="auto"
|
||||||
|
></x-button>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Asset Management
|
||||||
|
|
||||||
|
### CSS
|
||||||
|
|
||||||
|
The theme uses Tailwind CSS for styling with custom utilities:
|
||||||
|
|
||||||
|
- Base styles in `views/styles/base`
|
||||||
|
- Component styles in `views/styles/components`
|
||||||
|
- Block-specific styles in individual block folders and `views/styles/blocks`
|
||||||
|
- Admin/editor styles in `views/styles/backend`
|
||||||
|
|
||||||
|
### JavaScript
|
||||||
|
|
||||||
|
- **theme.js**: Main frontend JavaScript
|
||||||
|
- **admin.js**: Admin-specific JavaScript
|
||||||
|
- **components**: JavaScript components
|
||||||
|
- **modules**: JavaScript modules for specific functionality (e.g., navigation, focus styling)
|
||||||
|
|
||||||
|
### Build System
|
||||||
|
|
||||||
|
The theme includes a simple build system in the bin directory:
|
||||||
|
|
||||||
|
- **.build.js**: Production build script that compiles Tailwind CSS
|
||||||
|
- **.watch.js**: Development watch script with BrowserSync for live reloading
|
||||||
|
- **.utils.js**: Shared utility functions for the build process
|
||||||
|
|
||||||
|
## Development Workflow
|
||||||
|
|
||||||
|
### Setup
|
||||||
|
|
||||||
|
1. Create a new repo using this one as a template.
|
||||||
|
2. Clone the repo to your local dev folder.
|
||||||
|
3. Install dependencies (if asked to overwrite, choose "no"):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install theme dependencies
|
||||||
|
composer install
|
||||||
|
npm i
|
||||||
|
|
||||||
|
# Configure playwright for testing
|
||||||
|
npm init playwright@latest --yes "--" . '--quiet' '--browser=chromium' '--browser=firefox' '--browser=webkit' '--lang=js'
|
||||||
|
|
||||||
|
# Perform initial build
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Create .env file from .env.example and set:
|
||||||
|
|
||||||
|
- `LOCALHOST_URL`: Local development URL.
|
||||||
|
- `BROWSERSYNC_PORT`: Port for BrowserSync (default: 5000).
|
||||||
|
|
||||||
|
5. Start building your project.
|
||||||
|
|
||||||
|
- Run `npm run start` to start the development server with live reloading.
|
||||||
|
- Activate the theme in your WordPress admin.
|
||||||
|
- (Optional) Import the sample content from `content`.
|
||||||
|
|
||||||
|
### Sart Development Server
|
||||||
|
|
||||||
|
- Run `npm run watch` or `npm run start` to start development server with live reloading.
|
||||||
|
- Changes to PHP, CSS, and JS files will trigger automatic reload.
|
||||||
|
|
||||||
|
### Production
|
||||||
|
|
||||||
|
- Run `npm run build` to compile and optimize CSS for production (normally handled by GitHub Actions).
|
||||||
|
|
||||||
|
### Deployment
|
||||||
|
|
||||||
|
- Deployment is handled via GitHub Actions.
|
||||||
|
- Ensure you update `.github/workflows/wpengine,yml` with the correct WP Engine deployment configuration (environment and theme folder).
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
The theme includes a suite of testing tools to ensure code quality and functionality.
|
||||||
|
|
||||||
|
Accessibility tests using Playwright and Axe:
|
||||||
|
|
||||||
|
- Test files located in `tests`.
|
||||||
|
- Run via the [VSCode Playwright extension](https://marketplace.visualstudio.com/items/?itemName=ms-playwright.playwright) or with `npx playwright test --ui` in your terminal for the dedicated Playwright window.
|
||||||
|
- Tests include:
|
||||||
|
- `site-a11y.spec.js`: Accessibility tests for the site.
|
||||||
|
- Generates reports in `playwright-report` and screenshots in `test-results`.
|
||||||
|
|
||||||
|
Code linting for modified WordPress coding standards using phpcs:
|
||||||
|
|
||||||
|
- Run `composer lint` in your terminal to check PHP files for coding standards violations
|
||||||
|
- Test results are saved in `phpcs-results.txt`. Review the file for error details.
|
||||||
|
- Automated fixes noted in the results can be done using `composer fix` in your terminal.
|
||||||
|
|
||||||
|
### Files
|
||||||
|
|
||||||
|
- `404.php` - Displays a custom "Page Not Found" message when a visitor tries to access a page that doesn't exist.
|
||||||
|
- `archive.php` - Displays a list of posts from a particular archive, such as a category, date, or tag archive.
|
||||||
|
- `author.php` - Displays a list of posts by a specific author, along with the author's information.
|
||||||
|
- `category.php` - Displays a list of posts from a specific category.
|
||||||
|
- `footer.php` - Contains the footer section of the theme, typically including closing HTML tags and widgets or navigation in the footer area.
|
||||||
|
- `front-page.php` - The template used for the front page of the site, either static or a blog, depending on the site settings.
|
||||||
|
- `functions.php` - Imports custom functionality for the theme. **Should not be edited**, all changes/additions should live in the `lib` directory.
|
||||||
|
- `header.php` - Contains the header section of the theme, typically including the site's title, meta tags, and navigation menu.
|
||||||
|
- `index.php` - The fallback template for all WordPress pages, used if no other more specific template (like `category.php` or `single.php`) is available.
|
||||||
|
- `page.php` - Displays individual static pages, such as "About" or "Contact" pages.
|
||||||
|
- `screenshot.png` - An image of the theme’s design, shown in the WordPress theme selector to give users a preview of the theme's appearance.
|
||||||
|
- `search.php` - Displays the results of a search query, showing posts or pages that match the search terms entered by the user.
|
||||||
|
- `single.php` - Displays individual posts, often used for blog posts or custom post types.
|
||||||
|
- `tag.php` - Displays a list of posts associated with a specific tag.
|
||||||
|
|
||||||
|
### Folders
|
||||||
|
|
||||||
|
- `acf` - Storage for ACF field group JSON files. You shouldn't edit anything here manually.
|
||||||
|
- `bin` - Helper files for the dev and build processes.
|
||||||
|
- `lib` - Main library for the theme, including the Twig engine and other helper functions.
|
||||||
|
- `static` - Static assets for the theme, including CSS, JS, and images. The rendered stylesheet is stored here.
|
||||||
|
- `styles` - The raw CSS files compiled by Tailwind into the final CSS file.
|
||||||
|
- `views` - Twig view templates for the theme. This is where you will do most of your work.
|
||||||
|
- `blocks` - ACF block templates.
|
||||||
|
- `boilerplate` - Example ACF block template. Used to build your own blocks (more on this below).
|
||||||
|
- `icons` - Icon templates for SVG icons.
|
||||||
|
- `partials` - Partial templates for the page hero, breadcrumb, and social media sections.
|
||||||
@@ -0,0 +1,217 @@
|
|||||||
|
{
|
||||||
|
"key": "group_5f7f85a2a3e13",
|
||||||
|
"title": "Button",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"key": "field_67d5cd1108a6e",
|
||||||
|
"label": "Element",
|
||||||
|
"name": "element",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "radio",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 1,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"choices": {
|
||||||
|
"a": "<a> Element",
|
||||||
|
"button": "<button> Element"
|
||||||
|
},
|
||||||
|
"default_value": "a",
|
||||||
|
"return_format": "value",
|
||||||
|
"allow_null": 0,
|
||||||
|
"other_choice": 0,
|
||||||
|
"allow_in_bindings": 0,
|
||||||
|
"layout": "horizontal",
|
||||||
|
"save_other_choice": 0,
|
||||||
|
"wpml_cf_preferences": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_5f7f85a71151d",
|
||||||
|
"label": "Link",
|
||||||
|
"name": "link",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "link",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 1,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"return_format": "array",
|
||||||
|
"wpml_cf_preferences": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_5f7f85bd1151e",
|
||||||
|
"label": "Color",
|
||||||
|
"name": "color",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "select",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"choices": {
|
||||||
|
"primary": "Primary",
|
||||||
|
"secondary": "Secondary",
|
||||||
|
"white": "White",
|
||||||
|
"black": "Black"
|
||||||
|
},
|
||||||
|
"default_value": "primary",
|
||||||
|
"return_format": "value",
|
||||||
|
"multiple": 0,
|
||||||
|
"allow_null": 0,
|
||||||
|
"allow_in_bindings": 1,
|
||||||
|
"ui": 0,
|
||||||
|
"ajax": 0,
|
||||||
|
"placeholder": "",
|
||||||
|
"create_options": 0,
|
||||||
|
"save_options": 0,
|
||||||
|
"wpml_cf_preferences": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_5f7f85e41151f",
|
||||||
|
"label": "Variant",
|
||||||
|
"name": "variant",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "select",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"choices": {
|
||||||
|
"default": "Default",
|
||||||
|
"outline": "Outline"
|
||||||
|
},
|
||||||
|
"default_value": "default",
|
||||||
|
"allow_null": 0,
|
||||||
|
"multiple": 0,
|
||||||
|
"ui": 0,
|
||||||
|
"return_format": "value",
|
||||||
|
"ajax": 0,
|
||||||
|
"placeholder": "",
|
||||||
|
"create_options": 0,
|
||||||
|
"save_options": 0,
|
||||||
|
"wpml_cf_preferences": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_5f807a47dd2a8",
|
||||||
|
"label": "Size",
|
||||||
|
"name": "size",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "select",
|
||||||
|
"instructions": "Controls the padding of the buttons",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"choices": {
|
||||||
|
"small": "Small",
|
||||||
|
"medium": "Medium",
|
||||||
|
"large": "Large"
|
||||||
|
},
|
||||||
|
"default_value": "medium",
|
||||||
|
"return_format": "value",
|
||||||
|
"multiple": 0,
|
||||||
|
"allow_null": 0,
|
||||||
|
"allow_in_bindings": 1,
|
||||||
|
"ui": 0,
|
||||||
|
"ajax": 0,
|
||||||
|
"placeholder": "",
|
||||||
|
"create_options": 0,
|
||||||
|
"save_options": 0,
|
||||||
|
"wpml_cf_preferences": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_605924972a98a",
|
||||||
|
"label": "Width",
|
||||||
|
"name": "width",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "select",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"choices": {
|
||||||
|
"auto": "Auto",
|
||||||
|
"small": "Small",
|
||||||
|
"wide": "Wide",
|
||||||
|
"full": "Full Width"
|
||||||
|
},
|
||||||
|
"default_value": "auto",
|
||||||
|
"return_format": "value",
|
||||||
|
"multiple": 0,
|
||||||
|
"allow_null": 0,
|
||||||
|
"allow_in_bindings": 1,
|
||||||
|
"ui": 0,
|
||||||
|
"ajax": 0,
|
||||||
|
"placeholder": "",
|
||||||
|
"create_options": 0,
|
||||||
|
"save_options": 0,
|
||||||
|
"wpml_cf_preferences": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_6924c83e85da9",
|
||||||
|
"label": "ARIA Label",
|
||||||
|
"name": "aria_label",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "text",
|
||||||
|
"instructions": "Used to give the link an accessible name if using \"Read more\" as the title",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"wpml_cf_preferences": 0,
|
||||||
|
"default_value": "",
|
||||||
|
"maxlength": "",
|
||||||
|
"allow_in_bindings": 0,
|
||||||
|
"placeholder": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"location": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"param": "block",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "acf\/button"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"menu_order": 0,
|
||||||
|
"position": "normal",
|
||||||
|
"style": "default",
|
||||||
|
"label_placement": "top",
|
||||||
|
"instruction_placement": "label",
|
||||||
|
"hide_on_screen": "",
|
||||||
|
"active": true,
|
||||||
|
"description": "",
|
||||||
|
"show_in_rest": 0,
|
||||||
|
"display_title": "",
|
||||||
|
"acfml_field_group_mode": "translation",
|
||||||
|
"modified": 1764018311
|
||||||
|
}
|
||||||
@@ -0,0 +1,459 @@
|
|||||||
|
{
|
||||||
|
"key": "group_5fd3e006e5da5",
|
||||||
|
"title": "Global Fields",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"key": "field_5fd3e0137bfed",
|
||||||
|
"label": "Contact Info",
|
||||||
|
"name": "contact_info",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "group",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"layout": "row",
|
||||||
|
"sub_fields": [
|
||||||
|
{
|
||||||
|
"key": "field_5fd3e0277bfee",
|
||||||
|
"label": "Email",
|
||||||
|
"name": "email",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "email",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"placeholder": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_5fd3e02f7bfef",
|
||||||
|
"label": "Phone",
|
||||||
|
"name": "phone",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "text",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"placeholder": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": "",
|
||||||
|
"maxlength": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_684ad36ebaf40",
|
||||||
|
"label": "Fax",
|
||||||
|
"name": "fax",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "text",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"maxlength": "",
|
||||||
|
"allow_in_bindings": 1,
|
||||||
|
"placeholder": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_5fd3e0437bff0",
|
||||||
|
"label": "Address",
|
||||||
|
"name": "address",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "textarea",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"placeholder": "",
|
||||||
|
"maxlength": "",
|
||||||
|
"rows": 3,
|
||||||
|
"new_lines": "br"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_60381dcb082b5",
|
||||||
|
"label": "Hours",
|
||||||
|
"name": "hours",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "textarea",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"placeholder": "",
|
||||||
|
"maxlength": "",
|
||||||
|
"rows": 3,
|
||||||
|
"new_lines": "br"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_677bf0e692d37",
|
||||||
|
"label": "Social Media",
|
||||||
|
"name": "social_media",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "group",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"layout": "row",
|
||||||
|
"sub_fields": [
|
||||||
|
{
|
||||||
|
"key": "field_677bf0e692d3c",
|
||||||
|
"label": "Facebook",
|
||||||
|
"name": "facebook",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "url",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"allow_in_bindings": 1,
|
||||||
|
"placeholder": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_677bf0e692d3e",
|
||||||
|
"label": "Instagram",
|
||||||
|
"name": "instagram",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "url",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"allow_in_bindings": 1,
|
||||||
|
"placeholder": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_677bf0e692d3d",
|
||||||
|
"label": "X\/Twitter",
|
||||||
|
"name": "twitter",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "url",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"allow_in_bindings": 1,
|
||||||
|
"placeholder": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_677bf0e692d41",
|
||||||
|
"label": "LinkedIn",
|
||||||
|
"name": "linkedin",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "url",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"allow_in_bindings": 1,
|
||||||
|
"placeholder": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_677bf0e692d40",
|
||||||
|
"label": "Youtube",
|
||||||
|
"name": "youtube",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "url",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"allow_in_bindings": 1,
|
||||||
|
"placeholder": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_677bf0e692d3f",
|
||||||
|
"label": "Pinterest",
|
||||||
|
"name": "pinterest",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "url",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"allow_in_bindings": 1,
|
||||||
|
"placeholder": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_60302ebb3604d",
|
||||||
|
"label": "Header",
|
||||||
|
"name": "header",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "group",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"layout": "row",
|
||||||
|
"sub_fields": [
|
||||||
|
{
|
||||||
|
"key": "field_60cbbb8fc100a",
|
||||||
|
"label": "Header Logo",
|
||||||
|
"name": "header_logo",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "image",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"return_format": "array",
|
||||||
|
"preview_size": "medium",
|
||||||
|
"library": "all",
|
||||||
|
"min_width": "",
|
||||||
|
"min_height": "",
|
||||||
|
"min_size": "",
|
||||||
|
"max_width": "",
|
||||||
|
"max_height": "",
|
||||||
|
"max_size": "",
|
||||||
|
"mime_types": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_61df32ca33bc0",
|
||||||
|
"label": "Footer",
|
||||||
|
"name": "footer",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "group",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"layout": "block",
|
||||||
|
"sub_fields": [
|
||||||
|
{
|
||||||
|
"key": "field_61df32e833bc1",
|
||||||
|
"label": "Footer Logo",
|
||||||
|
"name": "footer_logo",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "image",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"return_format": "array",
|
||||||
|
"preview_size": "medium",
|
||||||
|
"library": "all",
|
||||||
|
"min_width": "",
|
||||||
|
"min_height": "",
|
||||||
|
"min_size": "",
|
||||||
|
"max_width": "",
|
||||||
|
"max_height": "",
|
||||||
|
"max_size": "",
|
||||||
|
"mime_types": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_64761ea8cb0dd",
|
||||||
|
"label": "Footer Description",
|
||||||
|
"name": "footer_description",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "wysiwyg",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"tabs": "all",
|
||||||
|
"toolbar": "full",
|
||||||
|
"media_upload": 1,
|
||||||
|
"delay": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_61df3348c3795",
|
||||||
|
"label": "Copyright Text",
|
||||||
|
"name": "copyright_text",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "text",
|
||||||
|
"instructions": "Use '%Y' to display the current year.",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "© %Y. All rights reserved.",
|
||||||
|
"maxlength": "",
|
||||||
|
"allow_in_bindings": 1,
|
||||||
|
"placeholder": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_684af923d5f68",
|
||||||
|
"label": "Credit Text",
|
||||||
|
"name": "credit_text",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "text",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "Web Design & Development by <a href=\"https:\/\/vincentdesign.ca\/\"><strong>Vincent Design<\/strong><\/a>",
|
||||||
|
"maxlength": "",
|
||||||
|
"allow_in_bindings": 1,
|
||||||
|
"placeholder": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_60cbbba3c100b",
|
||||||
|
"label": "Admin",
|
||||||
|
"name": "admin",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "group",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"layout": "row",
|
||||||
|
"sub_fields": [
|
||||||
|
{
|
||||||
|
"key": "field_60cbbbb2c100c",
|
||||||
|
"label": "404 Page",
|
||||||
|
"name": "404_page",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "post_object",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"post_type": [
|
||||||
|
"page"
|
||||||
|
],
|
||||||
|
"taxonomy": "",
|
||||||
|
"allow_null": 0,
|
||||||
|
"multiple": 0,
|
||||||
|
"return_format": "object",
|
||||||
|
"ui": 1,
|
||||||
|
"bidirectional_target": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"location": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"param": "options_page",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "global-fields"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"menu_order": 0,
|
||||||
|
"position": "normal",
|
||||||
|
"style": "default",
|
||||||
|
"label_placement": "top",
|
||||||
|
"instruction_placement": "label",
|
||||||
|
"hide_on_screen": "",
|
||||||
|
"active": true,
|
||||||
|
"description": "",
|
||||||
|
"show_in_rest": 0,
|
||||||
|
"modified": 1749744328
|
||||||
|
}
|
||||||
@@ -0,0 +1,362 @@
|
|||||||
|
{
|
||||||
|
"key": "group_600f5a9e242c3",
|
||||||
|
"title": "Grid",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"key": "field_6010666abf912",
|
||||||
|
"label": "Grid Settings",
|
||||||
|
"name": "",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "accordion",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"open": 1,
|
||||||
|
"multi_expand": 1,
|
||||||
|
"endpoint": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_600f6ea6251d4",
|
||||||
|
"label": "Columns",
|
||||||
|
"name": "columns",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "range",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"min": 1,
|
||||||
|
"max": 12,
|
||||||
|
"step": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_600f6ee1251d6",
|
||||||
|
"label": "Columns (sm)",
|
||||||
|
"name": "columns_sm",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "range",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"field": "field_60106fa83e9ae",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "sm"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"min": 1,
|
||||||
|
"max": 12,
|
||||||
|
"step": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_600f6f41251d7",
|
||||||
|
"label": "Columns (md)",
|
||||||
|
"name": "columns_md",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "range",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"field": "field_60106fa83e9ae",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "md"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"min": 1,
|
||||||
|
"max": 12,
|
||||||
|
"step": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_600f6f4d251d8",
|
||||||
|
"label": "Columns (lg)",
|
||||||
|
"name": "columns_lg",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "range",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"field": "field_60106fa83e9ae",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "lg"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"min": 1,
|
||||||
|
"max": 12,
|
||||||
|
"step": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_600f6f57251d9",
|
||||||
|
"label": "Columns (xl)",
|
||||||
|
"name": "columns_xl",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "range",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"field": "field_60106fa83e9ae",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "xl"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"min": 1,
|
||||||
|
"max": 12,
|
||||||
|
"step": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_600f6f66251da",
|
||||||
|
"label": "Columns (2xl)",
|
||||||
|
"name": "columns_2xl",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "range",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"field": "field_60106fa83e9ae",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "2xl"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"min": 1,
|
||||||
|
"max": 12,
|
||||||
|
"step": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_60106fa83e9ae",
|
||||||
|
"label": "Breakpoints",
|
||||||
|
"name": "columns_breakpoints",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "checkbox",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"choices": {
|
||||||
|
"sm": "sm (640px)",
|
||||||
|
"md": "md (768px)",
|
||||||
|
"lg": "lg (1024px)",
|
||||||
|
"xl": "xl (1280px)",
|
||||||
|
"2xl": "2xl (1536px)"
|
||||||
|
},
|
||||||
|
"allow_custom": 0,
|
||||||
|
"default_value": [],
|
||||||
|
"layout": "vertical",
|
||||||
|
"toggle": 0,
|
||||||
|
"return_format": "value",
|
||||||
|
"save_custom": 0,
|
||||||
|
"custom_choice_button_text": "Add new choice"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_600f5d3ec8e30",
|
||||||
|
"label": "Gap X",
|
||||||
|
"name": "gap_x",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "select",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"choices": {
|
||||||
|
"0": "0",
|
||||||
|
"1": "1",
|
||||||
|
"2": "2",
|
||||||
|
"3": "3",
|
||||||
|
"4": "4",
|
||||||
|
"5": "5",
|
||||||
|
"6": "6",
|
||||||
|
"7": "7",
|
||||||
|
"8": "8",
|
||||||
|
"9": "9",
|
||||||
|
"10": "10",
|
||||||
|
"11": "11",
|
||||||
|
"12": "12",
|
||||||
|
"14": "14",
|
||||||
|
"16": "16",
|
||||||
|
"18": "18",
|
||||||
|
"20": "20",
|
||||||
|
"24": "24",
|
||||||
|
"28": "28",
|
||||||
|
"32": "32",
|
||||||
|
"36": "36",
|
||||||
|
"40": "40",
|
||||||
|
"48": "48",
|
||||||
|
"56": "56",
|
||||||
|
"64": "64",
|
||||||
|
"72": "72",
|
||||||
|
"80": "80",
|
||||||
|
"88": "88",
|
||||||
|
"96": "96"
|
||||||
|
},
|
||||||
|
"default_value": 0,
|
||||||
|
"allow_null": 0,
|
||||||
|
"multiple": 0,
|
||||||
|
"ui": 0,
|
||||||
|
"return_format": "value",
|
||||||
|
"ajax": 0,
|
||||||
|
"placeholder": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_60dca39d232a1",
|
||||||
|
"label": "Gap Y",
|
||||||
|
"name": "gap_y",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "select",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"choices": {
|
||||||
|
"0": "0",
|
||||||
|
"1": "1",
|
||||||
|
"2": "2",
|
||||||
|
"3": "3",
|
||||||
|
"4": "4",
|
||||||
|
"5": "5",
|
||||||
|
"6": "6",
|
||||||
|
"7": "7",
|
||||||
|
"8": "8",
|
||||||
|
"9": "9",
|
||||||
|
"10": "10",
|
||||||
|
"11": "11",
|
||||||
|
"12": "12",
|
||||||
|
"14": "14",
|
||||||
|
"16": "16",
|
||||||
|
"18": "18",
|
||||||
|
"20": "20",
|
||||||
|
"24": "24",
|
||||||
|
"28": "28",
|
||||||
|
"32": "32",
|
||||||
|
"36": "36",
|
||||||
|
"40": "40",
|
||||||
|
"48": "48",
|
||||||
|
"56": "56",
|
||||||
|
"64": "64",
|
||||||
|
"72": "72",
|
||||||
|
"80": "80",
|
||||||
|
"88": "88",
|
||||||
|
"96": "96"
|
||||||
|
},
|
||||||
|
"default_value": 0,
|
||||||
|
"allow_null": 0,
|
||||||
|
"multiple": 0,
|
||||||
|
"ui": 0,
|
||||||
|
"return_format": "value",
|
||||||
|
"ajax": 0,
|
||||||
|
"placeholder": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_60106e64bf91c",
|
||||||
|
"label": "Grid Settings End",
|
||||||
|
"name": "",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "accordion",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"open": 0,
|
||||||
|
"multi_expand": 0,
|
||||||
|
"endpoint": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"location": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"param": "block",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "acf\/grid"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"menu_order": 0,
|
||||||
|
"position": "normal",
|
||||||
|
"style": "default",
|
||||||
|
"label_placement": "top",
|
||||||
|
"instruction_placement": "label",
|
||||||
|
"hide_on_screen": "",
|
||||||
|
"active": true,
|
||||||
|
"description": "",
|
||||||
|
"show_in_rest": 0,
|
||||||
|
"modified": 1744581665
|
||||||
|
}
|
||||||
@@ -0,0 +1,256 @@
|
|||||||
|
{
|
||||||
|
"key": "group_60106ed700da3",
|
||||||
|
"title": "Grid Cell",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"key": "field_60106ed7117ef",
|
||||||
|
"label": "Col Span",
|
||||||
|
"name": "",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "accordion",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"open": 1,
|
||||||
|
"multi_expand": 1,
|
||||||
|
"endpoint": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_60106ed7117f7",
|
||||||
|
"label": "Default",
|
||||||
|
"name": "col_span",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "range",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "hide-top-label",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"min": 1,
|
||||||
|
"max": 12,
|
||||||
|
"step": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_60106ed711802",
|
||||||
|
"label": "(sm)",
|
||||||
|
"name": "col_span_sm",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "range",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"field": "field_60106ed711830",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "sm"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"min": 1,
|
||||||
|
"max": 12,
|
||||||
|
"step": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_60106ed71180a",
|
||||||
|
"label": "(md)",
|
||||||
|
"name": "col_span_md",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "range",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"field": "field_60106ed711830",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "md"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"min": 1,
|
||||||
|
"max": 12,
|
||||||
|
"step": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_60106ed711811",
|
||||||
|
"label": "(lg)",
|
||||||
|
"name": "col_span_lg",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "range",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"field": "field_60106ed711830",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "lg"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"min": 1,
|
||||||
|
"max": 12,
|
||||||
|
"step": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_60106ed71181d",
|
||||||
|
"label": "(xl)",
|
||||||
|
"name": "col_span_xl",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "range",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"field": "field_60106ed711830",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "xl"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"min": 1,
|
||||||
|
"max": 12,
|
||||||
|
"step": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_60106ed711825",
|
||||||
|
"label": "(2xl)",
|
||||||
|
"name": "col_span_2xl",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "range",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"field": "field_60106ed711830",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "2xl"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"min": 1,
|
||||||
|
"max": 12,
|
||||||
|
"step": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_60106ed711830",
|
||||||
|
"label": "Breakpoints",
|
||||||
|
"name": "col_span_breakpoints",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "checkbox",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"choices": {
|
||||||
|
"sm": "sm (640px)",
|
||||||
|
"md": "md (768px)",
|
||||||
|
"lg": "lg (1024px)",
|
||||||
|
"xl": "xl (1280px)",
|
||||||
|
"2xl": "2xl (1536px)"
|
||||||
|
},
|
||||||
|
"allow_custom": 0,
|
||||||
|
"default_value": [],
|
||||||
|
"layout": "vertical",
|
||||||
|
"toggle": 0,
|
||||||
|
"return_format": "value",
|
||||||
|
"save_custom": 0,
|
||||||
|
"custom_choice_button_text": "Add new choice"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_60106ed711838",
|
||||||
|
"label": "Col Span End",
|
||||||
|
"name": "",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "accordion",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"open": 0,
|
||||||
|
"multi_expand": 0,
|
||||||
|
"endpoint": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"location": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"param": "block",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "acf\/grid-cell"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"menu_order": 0,
|
||||||
|
"position": "normal",
|
||||||
|
"style": "default",
|
||||||
|
"label_placement": "top",
|
||||||
|
"instruction_placement": "label",
|
||||||
|
"hide_on_screen": "",
|
||||||
|
"active": true,
|
||||||
|
"description": "",
|
||||||
|
"show_in_rest": 0,
|
||||||
|
"modified": 1697125043
|
||||||
|
}
|
||||||
@@ -0,0 +1,192 @@
|
|||||||
|
{
|
||||||
|
"key": "group_60bfb84ae973c",
|
||||||
|
"title": "Page Heading",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"key": "field_60bfda53dc0f2",
|
||||||
|
"label": "Hero Style",
|
||||||
|
"name": "hero_style",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "select",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"choices": {
|
||||||
|
"default": "Default",
|
||||||
|
"none": "None"
|
||||||
|
},
|
||||||
|
"default_value": false,
|
||||||
|
"allow_null": 0,
|
||||||
|
"multiple": 0,
|
||||||
|
"ui": 0,
|
||||||
|
"return_format": "value",
|
||||||
|
"ajax": 0,
|
||||||
|
"placeholder": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_6478f669004aa",
|
||||||
|
"label": "Background Color",
|
||||||
|
"name": "background_color",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "color_picker",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"enable_opacity": 0,
|
||||||
|
"return_format": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_6478f68c004ab",
|
||||||
|
"label": "Is Dark?",
|
||||||
|
"name": "is_dark",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "true_false",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"message": "",
|
||||||
|
"default_value": 1,
|
||||||
|
"ui": 0,
|
||||||
|
"ui_on_text": "",
|
||||||
|
"ui_off_text": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_60bfb8534a41f",
|
||||||
|
"label": "Heading",
|
||||||
|
"name": "heading",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "text",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"field": "field_60bfda53dc0f2",
|
||||||
|
"operator": "!=",
|
||||||
|
"value": "none"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"placeholder": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": "",
|
||||||
|
"maxlength": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_60bfb85a4a420",
|
||||||
|
"label": "Intro",
|
||||||
|
"name": "intro",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "textarea",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"field": "field_60bfda53dc0f2",
|
||||||
|
"operator": "!=",
|
||||||
|
"value": "none"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"placeholder": "",
|
||||||
|
"maxlength": "",
|
||||||
|
"rows": "",
|
||||||
|
"new_lines": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_60bfb8614a421",
|
||||||
|
"label": "Call to Actions",
|
||||||
|
"name": "call_to_actions",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "repeater",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": false,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"collapsed": "",
|
||||||
|
"min": 0,
|
||||||
|
"max": 0,
|
||||||
|
"layout": "table",
|
||||||
|
"button_label": "Add Call to Action",
|
||||||
|
"rows_per_page": 20,
|
||||||
|
"sub_fields": [
|
||||||
|
{
|
||||||
|
"key": "field_60bfb86e4a422",
|
||||||
|
"label": "Link",
|
||||||
|
"name": "link",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "link",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"return_format": "array",
|
||||||
|
"parent_repeater": "field_60bfb8614a421"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"location": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"param": "post_type",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "page"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"param": "post_type",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "post"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"menu_order": 1,
|
||||||
|
"position": "side",
|
||||||
|
"style": "default",
|
||||||
|
"label_placement": "top",
|
||||||
|
"instruction_placement": "label",
|
||||||
|
"hide_on_screen": "",
|
||||||
|
"active": true,
|
||||||
|
"description": "",
|
||||||
|
"show_in_rest": 0,
|
||||||
|
"modified": 1746895738
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
{
|
||||||
|
"key": "group_60bfdb328901d",
|
||||||
|
"title": "Homepage Hero",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"key": "field_60bfdb328cfae",
|
||||||
|
"label": "Heading",
|
||||||
|
"name": "heading",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "text",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"placeholder": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": "",
|
||||||
|
"maxlength": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_60bfdb328cfb9",
|
||||||
|
"label": "Intro",
|
||||||
|
"name": "intro",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "wysiwyg",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"tabs": "all",
|
||||||
|
"toolbar": "full",
|
||||||
|
"media_upload": 1,
|
||||||
|
"delay": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_60bfdb328cfc0",
|
||||||
|
"label": "Calls to Action",
|
||||||
|
"name": "calls_to_action",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "repeater",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"layout": "table",
|
||||||
|
"pagination": 0,
|
||||||
|
"min": 0,
|
||||||
|
"max": 0,
|
||||||
|
"collapsed": "",
|
||||||
|
"button_label": "Add Call to Action",
|
||||||
|
"rows_per_page": 20,
|
||||||
|
"sub_fields": [
|
||||||
|
{
|
||||||
|
"key": "field_60bfdb3294667",
|
||||||
|
"label": "Link",
|
||||||
|
"name": "link",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "link",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"return_format": "array",
|
||||||
|
"parent_repeater": "field_60bfdb328cfc0"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"location": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"param": "block",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "acf\/homepage-hero"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"menu_order": 0,
|
||||||
|
"position": "normal",
|
||||||
|
"style": "default",
|
||||||
|
"label_placement": "top",
|
||||||
|
"instruction_placement": "label",
|
||||||
|
"hide_on_screen": "",
|
||||||
|
"active": true,
|
||||||
|
"description": "",
|
||||||
|
"show_in_rest": 0,
|
||||||
|
"modified": 1742332828
|
||||||
|
}
|
||||||
@@ -0,0 +1,556 @@
|
|||||||
|
{
|
||||||
|
"key": "group_6261bc658dd80",
|
||||||
|
"title": "Section",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"key": "field_6262e24ce0672",
|
||||||
|
"label": "Background",
|
||||||
|
"name": "",
|
||||||
|
"type": "accordion",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"open": 0,
|
||||||
|
"multi_expand": 1,
|
||||||
|
"endpoint": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_6262df5194500",
|
||||||
|
"label": "Background Color",
|
||||||
|
"name": "background_color",
|
||||||
|
"type": "color_picker",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"enable_opacity": 0,
|
||||||
|
"return_format": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_6261bc723d308",
|
||||||
|
"label": "Background Image",
|
||||||
|
"name": "background_image",
|
||||||
|
"type": "image",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"return_format": "array",
|
||||||
|
"preview_size": "medium",
|
||||||
|
"library": "all",
|
||||||
|
"min_width": "",
|
||||||
|
"min_height": "",
|
||||||
|
"min_size": "",
|
||||||
|
"max_width": "",
|
||||||
|
"max_height": "",
|
||||||
|
"max_size": "",
|
||||||
|
"mime_types": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_62a9e85035329",
|
||||||
|
"label": "Background Position",
|
||||||
|
"name": "background_position",
|
||||||
|
"type": "group",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"field": "field_6261bc723d308",
|
||||||
|
"operator": "!=empty"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"layout": "block",
|
||||||
|
"sub_fields": [
|
||||||
|
{
|
||||||
|
"key": "field_62a9e87c3532a",
|
||||||
|
"label": "Size",
|
||||||
|
"name": "size",
|
||||||
|
"type": "select",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"choices": {
|
||||||
|
"cover": "Cover",
|
||||||
|
"contain": "Contain",
|
||||||
|
"custom": "Custom"
|
||||||
|
},
|
||||||
|
"default_value": false,
|
||||||
|
"allow_null": 0,
|
||||||
|
"multiple": 0,
|
||||||
|
"ui": 0,
|
||||||
|
"return_format": "value",
|
||||||
|
"ajax": 0,
|
||||||
|
"placeholder": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_62a9e8ef3532b",
|
||||||
|
"label": "Scale",
|
||||||
|
"name": "scale",
|
||||||
|
"type": "range",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"field": "field_62a9e87c3532a",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "custom"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": 100,
|
||||||
|
"min": "",
|
||||||
|
"max": 200,
|
||||||
|
"step": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": "%"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_62a9e92e3532c",
|
||||||
|
"label": "X",
|
||||||
|
"name": "x",
|
||||||
|
"type": "range",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": 50,
|
||||||
|
"min": "",
|
||||||
|
"max": "",
|
||||||
|
"step": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": "%"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_62a9e98c3532d",
|
||||||
|
"label": "Y",
|
||||||
|
"name": "y",
|
||||||
|
"type": "range",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": 50,
|
||||||
|
"min": "",
|
||||||
|
"max": "",
|
||||||
|
"step": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": "%"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_6262df6394501",
|
||||||
|
"label": "Background End",
|
||||||
|
"name": "",
|
||||||
|
"type": "accordion",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"open": 0,
|
||||||
|
"multi_expand": 0,
|
||||||
|
"endpoint": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_6262df8794502",
|
||||||
|
"label": "Overlay",
|
||||||
|
"name": "",
|
||||||
|
"type": "accordion",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"open": 0,
|
||||||
|
"multi_expand": 1,
|
||||||
|
"endpoint": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_6261bfcb2d09c",
|
||||||
|
"label": "Overlay Color",
|
||||||
|
"name": "overlay_color",
|
||||||
|
"type": "color_picker",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"enable_opacity": 0,
|
||||||
|
"return_format": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_6262df9994503",
|
||||||
|
"label": "Overlay Image",
|
||||||
|
"name": "overlay_image",
|
||||||
|
"type": "image",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"return_format": "array",
|
||||||
|
"preview_size": "medium",
|
||||||
|
"library": "all",
|
||||||
|
"min_width": "",
|
||||||
|
"min_height": "",
|
||||||
|
"min_size": "",
|
||||||
|
"max_width": "",
|
||||||
|
"max_height": "",
|
||||||
|
"max_size": "",
|
||||||
|
"mime_types": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_6261c02e08b7f",
|
||||||
|
"label": "Overlay Opacity",
|
||||||
|
"name": "overlay_opacity",
|
||||||
|
"type": "range",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"field": "field_6261bfcb2d09c",
|
||||||
|
"operator": "!=empty"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"field": "field_6262df9994503",
|
||||||
|
"operator": "!=empty"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"min": "",
|
||||||
|
"max": "",
|
||||||
|
"step": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": "%"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_62a9e9ab3532e",
|
||||||
|
"label": "Overlay Position",
|
||||||
|
"name": "overlay_position",
|
||||||
|
"type": "group",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"field": "field_6262df9994503",
|
||||||
|
"operator": "!=empty"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"layout": "block",
|
||||||
|
"sub_fields": [
|
||||||
|
{
|
||||||
|
"key": "field_62a9e9ab3532f",
|
||||||
|
"label": "Size",
|
||||||
|
"name": "size",
|
||||||
|
"type": "select",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"choices": {
|
||||||
|
"cover": "Cover",
|
||||||
|
"contain": "Contain",
|
||||||
|
"custom": "Custom"
|
||||||
|
},
|
||||||
|
"default_value": false,
|
||||||
|
"allow_null": 0,
|
||||||
|
"multiple": 0,
|
||||||
|
"ui": 0,
|
||||||
|
"return_format": "value",
|
||||||
|
"ajax": 0,
|
||||||
|
"placeholder": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_62a9e9ab35330",
|
||||||
|
"label": "Scale",
|
||||||
|
"name": "scale",
|
||||||
|
"type": "range",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"field": "field_62a9e9ab3532f",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "custom"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": 100,
|
||||||
|
"min": "",
|
||||||
|
"max": 200,
|
||||||
|
"step": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_62a9e9ab35331",
|
||||||
|
"label": "X",
|
||||||
|
"name": "x",
|
||||||
|
"type": "range",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": 50,
|
||||||
|
"min": "",
|
||||||
|
"max": "",
|
||||||
|
"step": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": "%"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_62a9e9ab35332",
|
||||||
|
"label": "Y",
|
||||||
|
"name": "y",
|
||||||
|
"type": "range",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": 50,
|
||||||
|
"min": "",
|
||||||
|
"max": "",
|
||||||
|
"step": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": "%"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_6262e26be0673",
|
||||||
|
"label": "Overlay End",
|
||||||
|
"name": "",
|
||||||
|
"type": "accordion",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"open": 0,
|
||||||
|
"multi_expand": 0,
|
||||||
|
"endpoint": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_6262dfbb94504",
|
||||||
|
"label": "Theme",
|
||||||
|
"name": "",
|
||||||
|
"type": "accordion",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"open": 0,
|
||||||
|
"multi_expand": 1,
|
||||||
|
"endpoint": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_6261c14931371",
|
||||||
|
"label": "Is Dark",
|
||||||
|
"name": "is_dark",
|
||||||
|
"type": "true_false",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"message": "",
|
||||||
|
"default_value": 0,
|
||||||
|
"ui": 0,
|
||||||
|
"ui_on_text": "",
|
||||||
|
"ui_off_text": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_6262e2b1e0674",
|
||||||
|
"label": "Theme End",
|
||||||
|
"name": "",
|
||||||
|
"type": "accordion",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"open": 0,
|
||||||
|
"multi_expand": 0,
|
||||||
|
"endpoint": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_6262eadf25dae",
|
||||||
|
"label": "Content",
|
||||||
|
"name": "",
|
||||||
|
"type": "accordion",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"open": 0,
|
||||||
|
"multi_expand": 1,
|
||||||
|
"endpoint": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_6262eb0025db0",
|
||||||
|
"label": "Content Width",
|
||||||
|
"name": "content_width",
|
||||||
|
"type": "select",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"choices": {
|
||||||
|
"default": "Default",
|
||||||
|
"full": "Full Width"
|
||||||
|
},
|
||||||
|
"default_value": "default",
|
||||||
|
"allow_null": 0,
|
||||||
|
"multiple": 0,
|
||||||
|
"ui": 0,
|
||||||
|
"return_format": "value",
|
||||||
|
"ajax": 0,
|
||||||
|
"placeholder": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_6262eaeb25daf",
|
||||||
|
"label": "Content End",
|
||||||
|
"name": "",
|
||||||
|
"type": "accordion",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"open": 0,
|
||||||
|
"multi_expand": 0,
|
||||||
|
"endpoint": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"location": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"param": "block",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "acf\/section"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"menu_order": 0,
|
||||||
|
"position": "normal",
|
||||||
|
"style": "default",
|
||||||
|
"label_placement": "top",
|
||||||
|
"instruction_placement": "label",
|
||||||
|
"hide_on_screen": "",
|
||||||
|
"active": true,
|
||||||
|
"description": "",
|
||||||
|
"show_in_rest": 0,
|
||||||
|
"modified": 1655311426
|
||||||
|
}
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
{
|
||||||
|
"key": "group_645e51f721207",
|
||||||
|
"title": "Accordion Block",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"key": "field_64639b159080f",
|
||||||
|
"label": "First Item Open?",
|
||||||
|
"name": "open",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "true_false",
|
||||||
|
"instructions": "Should the first accordion item be open on page load?",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"message": "",
|
||||||
|
"default_value": 0,
|
||||||
|
"ui": 0,
|
||||||
|
"ui_on_text": "",
|
||||||
|
"ui_off_text": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_67fabc2185ea0",
|
||||||
|
"label": "Item Group Name",
|
||||||
|
"name": "group_items",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "text",
|
||||||
|
"instructions": "Enables single expansion mode – closes previously open items when opening a new one.",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"maxlength": "",
|
||||||
|
"allow_in_bindings": 0,
|
||||||
|
"placeholder": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_645e52e3e0ac2",
|
||||||
|
"label": "Accordion Items",
|
||||||
|
"name": "accordion_items",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "repeater",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"layout": "row",
|
||||||
|
"pagination": 0,
|
||||||
|
"min": 0,
|
||||||
|
"max": 0,
|
||||||
|
"collapsed": "",
|
||||||
|
"button_label": "Add Row",
|
||||||
|
"rows_per_page": 20,
|
||||||
|
"sub_fields": [
|
||||||
|
{
|
||||||
|
"key": "field_645e51f7eadcb",
|
||||||
|
"label": "Title",
|
||||||
|
"name": "title",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "text",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"maxlength": "",
|
||||||
|
"placeholder": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": "",
|
||||||
|
"parent_repeater": "field_645e52e3e0ac2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_645e523feadcc",
|
||||||
|
"label": "Content",
|
||||||
|
"name": "content",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "wysiwyg",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"tabs": "all",
|
||||||
|
"toolbar": "full",
|
||||||
|
"media_upload": 1,
|
||||||
|
"delay": 0,
|
||||||
|
"parent_repeater": "field_645e52e3e0ac2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"location": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"param": "block",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "acf\/accordion"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"menu_order": 0,
|
||||||
|
"position": "normal",
|
||||||
|
"style": "default",
|
||||||
|
"label_placement": "top",
|
||||||
|
"instruction_placement": "label",
|
||||||
|
"hide_on_screen": "",
|
||||||
|
"active": true,
|
||||||
|
"description": "",
|
||||||
|
"show_in_rest": 0,
|
||||||
|
"modified": 1744493675
|
||||||
|
}
|
||||||
@@ -0,0 +1,389 @@
|
|||||||
|
{
|
||||||
|
"key": "group_645e7cf448e66",
|
||||||
|
"title": "Media With Text Block",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"key": "field_645e7cf4c6700",
|
||||||
|
"label": "Background Color",
|
||||||
|
"name": "background_color",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "color_picker",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"enable_opacity": 0,
|
||||||
|
"return_format": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_645e7d22c6701",
|
||||||
|
"label": "Is Dark",
|
||||||
|
"name": "is_dark",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "true_false",
|
||||||
|
"instructions": "If the background is dark, check this so text will remain legible",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"message": "",
|
||||||
|
"default_value": 0,
|
||||||
|
"ui": 0,
|
||||||
|
"ui_on_text": "",
|
||||||
|
"ui_off_text": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_645e7df0c6702",
|
||||||
|
"label": "Media Type",
|
||||||
|
"name": "media_type",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "select",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"choices": {
|
||||||
|
"image": "Image",
|
||||||
|
"video": "Video"
|
||||||
|
},
|
||||||
|
"default_value": false,
|
||||||
|
"return_format": "value",
|
||||||
|
"multiple": 0,
|
||||||
|
"allow_null": 0,
|
||||||
|
"ui": 0,
|
||||||
|
"ajax": 0,
|
||||||
|
"placeholder": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_645e7e2cc6703",
|
||||||
|
"label": "Image",
|
||||||
|
"name": "image",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "image",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"field": "field_645e7df0c6702",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "image"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"return_format": "array",
|
||||||
|
"library": "all",
|
||||||
|
"min_width": "",
|
||||||
|
"min_height": "",
|
||||||
|
"min_size": "",
|
||||||
|
"max_width": "",
|
||||||
|
"max_height": "",
|
||||||
|
"max_size": "",
|
||||||
|
"mime_types": "",
|
||||||
|
"preview_size": "medium"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_645e7e60c6704",
|
||||||
|
"label": "Video",
|
||||||
|
"name": "video",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "oembed",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"field": "field_645e7df0c6702",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "video"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"width": "",
|
||||||
|
"height": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_645e7f04c6705",
|
||||||
|
"label": "Media on Left",
|
||||||
|
"name": "media_on_left",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "true_false",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"message": "",
|
||||||
|
"default_value": 0,
|
||||||
|
"ui": 0,
|
||||||
|
"ui_on_text": "",
|
||||||
|
"ui_off_text": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_645e7f26c6706",
|
||||||
|
"label": "Heading",
|
||||||
|
"name": "heading",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "text",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"maxlength": "",
|
||||||
|
"placeholder": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_645e7f3dc6707",
|
||||||
|
"label": "Subheading",
|
||||||
|
"name": "subheading",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "text",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"maxlength": "",
|
||||||
|
"placeholder": "",
|
||||||
|
"prepend": "",
|
||||||
|
"append": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_645e7f49c6708",
|
||||||
|
"label": "Content",
|
||||||
|
"name": "content",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "wysiwyg",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"default_value": "",
|
||||||
|
"tabs": "all",
|
||||||
|
"toolbar": "full",
|
||||||
|
"media_upload": 1,
|
||||||
|
"delay": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_645e7f85c6709",
|
||||||
|
"label": "Calls To Action",
|
||||||
|
"name": "calls_to_action",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "repeater",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"layout": "block",
|
||||||
|
"pagination": 0,
|
||||||
|
"min": 0,
|
||||||
|
"max": 0,
|
||||||
|
"collapsed": "",
|
||||||
|
"button_label": "Add Row",
|
||||||
|
"rows_per_page": 20,
|
||||||
|
"sub_fields": [
|
||||||
|
{
|
||||||
|
"key": "field_645e7f93c670a",
|
||||||
|
"label": "Link",
|
||||||
|
"name": "link",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "link",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"return_format": "array",
|
||||||
|
"parent_repeater": "field_645e7f85c6709"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_646500c05f6da",
|
||||||
|
"label": "Color",
|
||||||
|
"name": "color",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "select",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"choices": {
|
||||||
|
"primary": "Primary",
|
||||||
|
"secondary": "Secondary",
|
||||||
|
"white": "White",
|
||||||
|
"gray": "Gray"
|
||||||
|
},
|
||||||
|
"default_value": "primary",
|
||||||
|
"return_format": "value",
|
||||||
|
"multiple": 0,
|
||||||
|
"allow_null": 0,
|
||||||
|
"ui": 0,
|
||||||
|
"ajax": 0,
|
||||||
|
"placeholder": "",
|
||||||
|
"parent_repeater": "field_645e7f85c6709"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_646501305f6db",
|
||||||
|
"label": "Variant",
|
||||||
|
"name": "variant",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "select",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"choices": {
|
||||||
|
"default": "Default",
|
||||||
|
"outline": "Outline"
|
||||||
|
},
|
||||||
|
"default_value": "default",
|
||||||
|
"return_format": "value",
|
||||||
|
"multiple": 0,
|
||||||
|
"allow_null": 0,
|
||||||
|
"ui": 0,
|
||||||
|
"ajax": 0,
|
||||||
|
"placeholder": "",
|
||||||
|
"parent_repeater": "field_645e7f85c6709"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_646501565f6dc",
|
||||||
|
"label": "Size",
|
||||||
|
"name": "size",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "select",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"choices": {
|
||||||
|
"small": "Small",
|
||||||
|
"medium": "Medium",
|
||||||
|
"large": "Large"
|
||||||
|
},
|
||||||
|
"default_value": "medium",
|
||||||
|
"return_format": "value",
|
||||||
|
"multiple": 0,
|
||||||
|
"allow_null": 0,
|
||||||
|
"ui": 0,
|
||||||
|
"ajax": 0,
|
||||||
|
"placeholder": "",
|
||||||
|
"parent_repeater": "field_645e7f85c6709"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "field_646501735f6dd",
|
||||||
|
"label": "Width",
|
||||||
|
"name": "width",
|
||||||
|
"aria-label": "",
|
||||||
|
"type": "select",
|
||||||
|
"instructions": "",
|
||||||
|
"required": 0,
|
||||||
|
"conditional_logic": 0,
|
||||||
|
"wrapper": {
|
||||||
|
"width": "",
|
||||||
|
"class": "",
|
||||||
|
"id": ""
|
||||||
|
},
|
||||||
|
"choices": {
|
||||||
|
"auto": "Auto",
|
||||||
|
"small": "Small",
|
||||||
|
"wide": "Wide",
|
||||||
|
"full": "Full Width"
|
||||||
|
},
|
||||||
|
"default_value": "auto",
|
||||||
|
"return_format": "value",
|
||||||
|
"multiple": 0,
|
||||||
|
"allow_null": 0,
|
||||||
|
"allow_in_bindings": 1,
|
||||||
|
"ui": 0,
|
||||||
|
"ajax": 0,
|
||||||
|
"placeholder": "",
|
||||||
|
"parent_repeater": "field_645e7f85c6709"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"location": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"param": "block",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "acf\/media-text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"param": "block",
|
||||||
|
"operator": "==",
|
||||||
|
"value": "acf\/media-text-innerblocks"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"menu_order": 0,
|
||||||
|
"position": "normal",
|
||||||
|
"style": "default",
|
||||||
|
"label_placement": "top",
|
||||||
|
"instruction_placement": "label",
|
||||||
|
"hide_on_screen": "",
|
||||||
|
"active": true,
|
||||||
|
"description": "",
|
||||||
|
"show_in_rest": 0,
|
||||||
|
"modified": 1742680440
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
require("dotenv").config();
|
||||||
|
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
const distDir = path.resolve(`static/dist`);
|
||||||
|
const { tailwindToCSS } = require(`./.utils`);
|
||||||
|
const start = performance.now();
|
||||||
|
|
||||||
|
// Tailwind to CSS
|
||||||
|
try {
|
||||||
|
// Ensure the output directory exists
|
||||||
|
if (!fs.existsSync(distDir)) {
|
||||||
|
fs.mkdirSync(distDir, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compile Tailwind
|
||||||
|
tailwindToCSS();
|
||||||
|
|
||||||
|
const end = performance.now();
|
||||||
|
const runtime = (end - start).toFixed(3);
|
||||||
|
console.log(`Production build successfully run in ${runtime}ms`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error processing CSS files:", error);
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* Utility functions shared between builds
|
||||||
|
*/
|
||||||
|
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
const distDir = path.resolve(`static/dist`);
|
||||||
|
const debounce = require("lodash.debounce");
|
||||||
|
|
||||||
|
require("dotenv").config();
|
||||||
|
|
||||||
|
// Theme root as working directory
|
||||||
|
const cwd = path.resolve("..");
|
||||||
|
|
||||||
|
// Compile Tailwind
|
||||||
|
module.exports.tailwindToCSS = debounce(() => {
|
||||||
|
try {
|
||||||
|
require("child_process").execSync(
|
||||||
|
`npx @tailwindcss/cli -i styles/theme.css -o static/dist/theme.css`,
|
||||||
|
{ stdio: "inherit" }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(`Error compiling Tailwind to CSS:`, error);
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
require("dotenv").config();
|
||||||
|
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
const browserSync = require("browser-sync").create();
|
||||||
|
const { tailwindToCSS } = require(`./.utils`);
|
||||||
|
|
||||||
|
// Theme root as working directory
|
||||||
|
const cwd = path.resolve("../");
|
||||||
|
|
||||||
|
// Initialize BrowserSync
|
||||||
|
browserSync.init({
|
||||||
|
proxy: process.env.LOCALHOST_URL,
|
||||||
|
port: process.env.BROWSERSYNC_PORT,
|
||||||
|
cors: true,
|
||||||
|
cwd: cwd,
|
||||||
|
logLevel: `warn`,
|
||||||
|
minify: false,
|
||||||
|
open: false,
|
||||||
|
ui: false,
|
||||||
|
ghostMode: false,
|
||||||
|
reloadOnRestart: true,
|
||||||
|
notify: false,
|
||||||
|
watch: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Reload JS during development
|
||||||
|
browserSync.watch(`static/js/*.js`, (event, file) => {
|
||||||
|
if (event !== "change") return;
|
||||||
|
|
||||||
|
const start = performance.now();
|
||||||
|
try {
|
||||||
|
browserSync.stream();
|
||||||
|
const end = performance.now();
|
||||||
|
const runtime = (end - start).toFixed(3);
|
||||||
|
console.log(`JS re-injected successfully in ${runtime}ms`);
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Error compiling JS:", error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Compile tailwind to css and reload on changes
|
||||||
|
browserSync.watch(["**/*.css", "**/*.php"], (event, file) => {
|
||||||
|
if (event !== "change") return;
|
||||||
|
|
||||||
|
tailwindToCSS();
|
||||||
|
browserSync.reload();
|
||||||
|
});
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"name": "vincentdesigninc/basic-wp",
|
||||||
|
"description": "Minimal custom WordPress theme with modern templating, a lightning fast build process, and no tom foolery.",
|
||||||
|
"type": "project",
|
||||||
|
"license": "MIT",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Keith Solomon",
|
||||||
|
"email": "keith@vincentdesign.ca"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require-dev": {
|
||||||
|
"squizlabs/php_codesniffer": "^3.12",
|
||||||
|
"wp-coding-standards/wpcs": "^3.1"
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"allow-plugins": {
|
||||||
|
"dealerdirect/phpcodesniffer-composer-installer": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"lint": [
|
||||||
|
"phpcs --report-full=./phpcs-results.txt ."
|
||||||
|
],
|
||||||
|
"fix": [
|
||||||
|
"phpcbf --standard=.phpcs.xml ."
|
||||||
|
],
|
||||||
|
"phpcs-config": [
|
||||||
|
"phpcs --config-show"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
+417
@@ -0,0 +1,417 @@
|
|||||||
|
{
|
||||||
|
"_readme": [
|
||||||
|
"This file locks the dependencies of your project to a known state",
|
||||||
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
|
"This file is @generated automatically"
|
||||||
|
],
|
||||||
|
"content-hash": "2c997c41672ef92cfa6b4d04f9c9097a",
|
||||||
|
"packages": [],
|
||||||
|
"packages-dev": [
|
||||||
|
{
|
||||||
|
"name": "dealerdirect/phpcodesniffer-composer-installer",
|
||||||
|
"version": "v1.0.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/PHPCSStandards/composer-installer.git",
|
||||||
|
"reference": "4be43904336affa5c2f70744a348312336afd0da"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/4be43904336affa5c2f70744a348312336afd0da",
|
||||||
|
"reference": "4be43904336affa5c2f70744a348312336afd0da",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"composer-plugin-api": "^1.0 || ^2.0",
|
||||||
|
"php": ">=5.4",
|
||||||
|
"squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"composer/composer": "*",
|
||||||
|
"ext-json": "*",
|
||||||
|
"ext-zip": "*",
|
||||||
|
"php-parallel-lint/php-parallel-lint": "^1.3.1",
|
||||||
|
"phpcompatibility/php-compatibility": "^9.0",
|
||||||
|
"yoast/phpunit-polyfills": "^1.0"
|
||||||
|
},
|
||||||
|
"type": "composer-plugin",
|
||||||
|
"extra": {
|
||||||
|
"class": "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Franck Nijhof",
|
||||||
|
"email": "franck.nijhof@dealerdirect.com",
|
||||||
|
"homepage": "http://www.frenck.nl",
|
||||||
|
"role": "Developer / IT Manager"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Contributors",
|
||||||
|
"homepage": "https://github.com/PHPCSStandards/composer-installer/graphs/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PHP_CodeSniffer Standards Composer Installer Plugin",
|
||||||
|
"homepage": "http://www.dealerdirect.com",
|
||||||
|
"keywords": [
|
||||||
|
"PHPCodeSniffer",
|
||||||
|
"PHP_CodeSniffer",
|
||||||
|
"code quality",
|
||||||
|
"codesniffer",
|
||||||
|
"composer",
|
||||||
|
"installer",
|
||||||
|
"phpcbf",
|
||||||
|
"phpcs",
|
||||||
|
"plugin",
|
||||||
|
"qa",
|
||||||
|
"quality",
|
||||||
|
"standard",
|
||||||
|
"standards",
|
||||||
|
"style guide",
|
||||||
|
"stylecheck",
|
||||||
|
"tests"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/PHPCSStandards/composer-installer/issues",
|
||||||
|
"source": "https://github.com/PHPCSStandards/composer-installer"
|
||||||
|
},
|
||||||
|
"time": "2023-01-05T11:28:13+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "phpcsstandards/phpcsextra",
|
||||||
|
"version": "1.3.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/PHPCSStandards/PHPCSExtra.git",
|
||||||
|
"reference": "46d08eb86eec622b96c466adec3063adfed280dd"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/PHPCSStandards/PHPCSExtra/zipball/46d08eb86eec622b96c466adec3063adfed280dd",
|
||||||
|
"reference": "46d08eb86eec622b96c466adec3063adfed280dd",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.4",
|
||||||
|
"phpcsstandards/phpcsutils": "^1.0.9",
|
||||||
|
"squizlabs/php_codesniffer": "^3.12.1"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"php-parallel-lint/php-console-highlighter": "^1.0",
|
||||||
|
"php-parallel-lint/php-parallel-lint": "^1.3.2",
|
||||||
|
"phpcsstandards/phpcsdevcs": "^1.1.6",
|
||||||
|
"phpcsstandards/phpcsdevtools": "^1.2.1",
|
||||||
|
"phpunit/phpunit": "^4.5 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0"
|
||||||
|
},
|
||||||
|
"type": "phpcodesniffer-standard",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-stable": "1.x-dev",
|
||||||
|
"dev-develop": "1.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"LGPL-3.0-or-later"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Juliette Reinders Folmer",
|
||||||
|
"homepage": "https://github.com/jrfnl",
|
||||||
|
"role": "lead"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Contributors",
|
||||||
|
"homepage": "https://github.com/PHPCSStandards/PHPCSExtra/graphs/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A collection of sniffs and standards for use with PHP_CodeSniffer.",
|
||||||
|
"keywords": [
|
||||||
|
"PHP_CodeSniffer",
|
||||||
|
"phpcbf",
|
||||||
|
"phpcodesniffer-standard",
|
||||||
|
"phpcs",
|
||||||
|
"standards",
|
||||||
|
"static analysis"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/PHPCSStandards/PHPCSExtra/issues",
|
||||||
|
"security": "https://github.com/PHPCSStandards/PHPCSExtra/security/policy",
|
||||||
|
"source": "https://github.com/PHPCSStandards/PHPCSExtra"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/PHPCSStandards",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/jrfnl",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://opencollective.com/php_codesniffer",
|
||||||
|
"type": "open_collective"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://thanks.dev/u/gh/phpcsstandards",
|
||||||
|
"type": "thanks_dev"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-04-20T23:35:32+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "phpcsstandards/phpcsutils",
|
||||||
|
"version": "1.0.12",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/PHPCSStandards/PHPCSUtils.git",
|
||||||
|
"reference": "87b233b00daf83fb70f40c9a28692be017ea7c6c"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/PHPCSStandards/PHPCSUtils/zipball/87b233b00daf83fb70f40c9a28692be017ea7c6c",
|
||||||
|
"reference": "87b233b00daf83fb70f40c9a28692be017ea7c6c",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"dealerdirect/phpcodesniffer-composer-installer": "^0.4.1 || ^0.5 || ^0.6.2 || ^0.7 || ^1.0",
|
||||||
|
"php": ">=5.4",
|
||||||
|
"squizlabs/php_codesniffer": "^3.10.0 || 4.0.x-dev@dev"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"ext-filter": "*",
|
||||||
|
"php-parallel-lint/php-console-highlighter": "^1.0",
|
||||||
|
"php-parallel-lint/php-parallel-lint": "^1.3.2",
|
||||||
|
"phpcsstandards/phpcsdevcs": "^1.1.6",
|
||||||
|
"yoast/phpunit-polyfills": "^1.1.0 || ^2.0.0"
|
||||||
|
},
|
||||||
|
"type": "phpcodesniffer-standard",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-stable": "1.x-dev",
|
||||||
|
"dev-develop": "1.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"classmap": [
|
||||||
|
"PHPCSUtils/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"LGPL-3.0-or-later"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Juliette Reinders Folmer",
|
||||||
|
"homepage": "https://github.com/jrfnl",
|
||||||
|
"role": "lead"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Contributors",
|
||||||
|
"homepage": "https://github.com/PHPCSStandards/PHPCSUtils/graphs/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A suite of utility functions for use with PHP_CodeSniffer",
|
||||||
|
"homepage": "https://phpcsutils.com/",
|
||||||
|
"keywords": [
|
||||||
|
"PHP_CodeSniffer",
|
||||||
|
"phpcbf",
|
||||||
|
"phpcodesniffer-standard",
|
||||||
|
"phpcs",
|
||||||
|
"phpcs3",
|
||||||
|
"standards",
|
||||||
|
"static analysis",
|
||||||
|
"tokens",
|
||||||
|
"utility"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"docs": "https://phpcsutils.com/",
|
||||||
|
"issues": "https://github.com/PHPCSStandards/PHPCSUtils/issues",
|
||||||
|
"security": "https://github.com/PHPCSStandards/PHPCSUtils/security/policy",
|
||||||
|
"source": "https://github.com/PHPCSStandards/PHPCSUtils"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/PHPCSStandards",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/jrfnl",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://opencollective.com/php_codesniffer",
|
||||||
|
"type": "open_collective"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-05-20T13:34:27+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "squizlabs/php_codesniffer",
|
||||||
|
"version": "3.12.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git",
|
||||||
|
"reference": "6d4cf6032d4b718f168c90a96e36c7d0eaacb2aa"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/6d4cf6032d4b718f168c90a96e36c7d0eaacb2aa",
|
||||||
|
"reference": "6d4cf6032d4b718f168c90a96e36c7d0eaacb2aa",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-simplexml": "*",
|
||||||
|
"ext-tokenizer": "*",
|
||||||
|
"ext-xmlwriter": "*",
|
||||||
|
"php": ">=5.4.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4"
|
||||||
|
},
|
||||||
|
"bin": [
|
||||||
|
"bin/phpcbf",
|
||||||
|
"bin/phpcs"
|
||||||
|
],
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "3.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"BSD-3-Clause"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Greg Sherwood",
|
||||||
|
"role": "Former lead"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Juliette Reinders Folmer",
|
||||||
|
"role": "Current lead"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Contributors",
|
||||||
|
"homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
|
||||||
|
"homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer",
|
||||||
|
"keywords": [
|
||||||
|
"phpcs",
|
||||||
|
"standards",
|
||||||
|
"static analysis"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues",
|
||||||
|
"security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy",
|
||||||
|
"source": "https://github.com/PHPCSStandards/PHP_CodeSniffer",
|
||||||
|
"wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/PHPCSStandards",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/jrfnl",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://opencollective.com/php_codesniffer",
|
||||||
|
"type": "open_collective"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://thanks.dev/u/gh/phpcsstandards",
|
||||||
|
"type": "thanks_dev"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-04-13T04:10:18+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "wp-coding-standards/wpcs",
|
||||||
|
"version": "3.1.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/WordPress/WordPress-Coding-Standards.git",
|
||||||
|
"reference": "9333efcbff231f10dfd9c56bb7b65818b4733ca7"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/9333efcbff231f10dfd9c56bb7b65818b4733ca7",
|
||||||
|
"reference": "9333efcbff231f10dfd9c56bb7b65818b4733ca7",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-filter": "*",
|
||||||
|
"ext-libxml": "*",
|
||||||
|
"ext-tokenizer": "*",
|
||||||
|
"ext-xmlreader": "*",
|
||||||
|
"php": ">=5.4",
|
||||||
|
"phpcsstandards/phpcsextra": "^1.2.1",
|
||||||
|
"phpcsstandards/phpcsutils": "^1.0.10",
|
||||||
|
"squizlabs/php_codesniffer": "^3.9.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"php-parallel-lint/php-console-highlighter": "^1.0.0",
|
||||||
|
"php-parallel-lint/php-parallel-lint": "^1.3.2",
|
||||||
|
"phpcompatibility/php-compatibility": "^9.0",
|
||||||
|
"phpcsstandards/phpcsdevtools": "^1.2.0",
|
||||||
|
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-iconv": "For improved results",
|
||||||
|
"ext-mbstring": "For improved results"
|
||||||
|
},
|
||||||
|
"type": "phpcodesniffer-standard",
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Contributors",
|
||||||
|
"homepage": "https://github.com/WordPress/WordPress-Coding-Standards/graphs/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions",
|
||||||
|
"keywords": [
|
||||||
|
"phpcs",
|
||||||
|
"standards",
|
||||||
|
"static analysis",
|
||||||
|
"wordpress"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/WordPress/WordPress-Coding-Standards/issues",
|
||||||
|
"source": "https://github.com/WordPress/WordPress-Coding-Standards",
|
||||||
|
"wiki": "https://github.com/WordPress/WordPress-Coding-Standards/wiki"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://opencollective.com/php_codesniffer",
|
||||||
|
"type": "custom"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-03-25T16:39:00+00:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"aliases": [],
|
||||||
|
"minimum-stability": "stable",
|
||||||
|
"stability-flags": {},
|
||||||
|
"prefer-stable": false,
|
||||||
|
"prefer-lowest": false,
|
||||||
|
"platform": {},
|
||||||
|
"platform-dev": {},
|
||||||
|
"plugin-api-version": "2.6.0"
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
+111
@@ -0,0 +1,111 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Theme footer template
|
||||||
|
*
|
||||||
|
* @package BasicWP
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace BasicWP;
|
||||||
|
|
||||||
|
$footerLogo = getFieldValue( 'footer.footer_logo.url' ) ? getFieldValue( 'footer.footer_logo.url' ) : '';
|
||||||
|
$footerDesc = getFieldValue( 'footer.footer_description' ) ? getFieldValue( 'footer.footer_description' ) : '';
|
||||||
|
|
||||||
|
$copyright_text = getFieldValue( 'footer.copyright_text' ) ? getFieldValue( 'footer.copyright_text' ) : 'Copyright © %Y ' . get_bloginfo( 'name' );
|
||||||
|
|
||||||
|
$copyright = str_replace( '%Y', gmdate( 'Y' ), $copyright_text );
|
||||||
|
|
||||||
|
$locations = get_nav_menu_locations();
|
||||||
|
$footerNav = ! empty( $locations['footer_navigation'] )
|
||||||
|
? ( wp_get_nav_menu_items( (int) $locations['footer_navigation'] ) ? wp_get_nav_menu_items( (int) $locations['footer_navigation'] ) : array() )
|
||||||
|
: array();
|
||||||
|
?>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer role="contentinfo" class="site-footer bg-gray-800 text-white text-base">
|
||||||
|
<div class="pt-16 pb-12 text-base">
|
||||||
|
<div class="container mx-auto">
|
||||||
|
<div class="grid grid-cols-4 gap-6 md:grid-cols-8 lg:grid-cols-12">
|
||||||
|
<div class="col-span-4 md:col-span-8 lg:col-span-4 max-w-[40ch] prose-p:text-14px prose-p:mb-4 text-balance" aria-labelledby="footer-header">
|
||||||
|
<h2 id="footer-header" class="max-w-64 h-auto">
|
||||||
|
<a href="<?php echo esc_url( home_url( '/' ) ); ?>" class="site-footer__logo-link h-full w-full">
|
||||||
|
<?php if ( $footerLogo ) { ?>
|
||||||
|
<img src="<?php echo esc_url( $footerLogo ); ?>" alt="<?php echo esc_attr( get_bloginfo( 'name' ) ); ?>" class="site-footer__logo-image" />
|
||||||
|
<?php
|
||||||
|
} else {
|
||||||
|
echo esc_html( get_bloginfo( 'name' ) );
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</a>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<div id="footer-description" aria-label="Footer description">
|
||||||
|
<?php echo wp_kses_post( $footerDesc ); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="social-links mt-8">
|
||||||
|
<?php
|
||||||
|
get_template_part(
|
||||||
|
'views/partials/social-media',
|
||||||
|
null,
|
||||||
|
array(
|
||||||
|
'circle' => false,
|
||||||
|
'classes' => 'social-icons p-0 mr-2 text-30px text-gray-300! hover:text-info!',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="footRight" class="col-span-4 md:col-span-8 grid md:grid-cols-4 gap-10 lg:justify-end">
|
||||||
|
<div aria-labelledby="footer-area-1" class="prose-p:text-balance">
|
||||||
|
<h3 class="mb-4 pb-2 border-b border-b-secondary font-bold text-white" id="footer-area-1">Footer Area 1</h3>
|
||||||
|
<?php dynamic_sidebar( 'footer-1' ); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div aria-labelledby="footer-area-2" class="prose-p:text-balance">
|
||||||
|
<h3 class="mb-4 pb-2 border-b border-b-secondary font-bold text-white" id="footer-area-2">Footer Area 2</h3>
|
||||||
|
<?php dynamic_sidebar( 'footer-2' ); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div aria-labelledby="footer-area-3" class="prose-p:text-balance">
|
||||||
|
<h3 class="mb-4 pb-2 border-b border-b-secondary font-bold text-white" id="footer-area-3">Footer Area 3</h3>
|
||||||
|
<?php dynamic_sidebar( 'footer-3' ); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="footer-nav" aria-labelledby="footer-navigation">
|
||||||
|
<h3 class="mb-4 pb-2 border-b border-b-secondary font-bold text-white" id="footer-navigation"><?php echo esc_html__( 'Navigation' ); ?></h3>
|
||||||
|
<?php if ( $footerNav ) : ?>
|
||||||
|
<nav class="site-footer__nav" aria-label="Footer navigation">
|
||||||
|
<ul class="site-footer__nav-list">
|
||||||
|
<?php foreach ( $footerNav as $item ) : ?>
|
||||||
|
<li class="site-footer__nav-item list-none text-left <?php echo esc_attr( implode( ' ', $item->classes ) ); ?>">
|
||||||
|
<a href="<?php echo esc_url( $item->url ); ?>" class="site-footer__nav-link">
|
||||||
|
<?php echo esc_html( $item->title ); ?>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="copyright bg-primary text-white text-center py-3 text-14px">
|
||||||
|
<?php
|
||||||
|
if ( $copyright ) {
|
||||||
|
echo wp_kses_post( $copyright );
|
||||||
|
} else {
|
||||||
|
echo esc_html( '© ' . gmdate( 'Y' ) . ' ' . get_bloginfo( 'name' ) . '.' );
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<?php wp_footer(); ?>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Front Page Template
|
||||||
|
*
|
||||||
|
* @package BasicWP
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace BasicWP;
|
||||||
|
|
||||||
|
get_header();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="container my-section lg:my-0 mx-auto">
|
||||||
|
<div>
|
||||||
|
<?php
|
||||||
|
// Content block
|
||||||
|
if ( have_posts() ) {
|
||||||
|
while ( have_posts() ) {
|
||||||
|
the_post();
|
||||||
|
the_content();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php get_footer(); ?>
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Functions file for the BasicWP theme.
|
||||||
|
*
|
||||||
|
* This file initializes the theme by including necessary dependencies
|
||||||
|
* and loading additional function files.
|
||||||
|
*
|
||||||
|
* @package BasicWP
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace BasicWP;
|
||||||
|
|
||||||
|
// Load functions.
|
||||||
|
foreach ( glob( __DIR__ . '/lib/*.php' ) as $filename ) {
|
||||||
|
include_once $filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Registers custom ACF (Advanced Custom Fields) blocks for use in the WordPress theme.
|
||||||
|
*
|
||||||
|
* This function is intended to define and register custom Gutenberg blocks
|
||||||
|
* using ACF, allowing for dynamic and reusable content blocks within the theme.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function regACFBlocks() {
|
||||||
|
define( 'BLOCKS_DIR', get_stylesheet_directory() . '/views/blocks' );
|
||||||
|
|
||||||
|
if ( is_dir( BLOCKS_DIR ) ) {
|
||||||
|
foreach ( scandir( BLOCKS_DIR ) as $folder ) {
|
||||||
|
if ( ( '.' !== $folder && '..' !== $folder && 'boilerplate' !== $folder ) && is_dir( BLOCKS_DIR . '/' . $folder ) ) {
|
||||||
|
register_block_type( BLOCKS_DIR . '/' . $folder );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
add_action( 'init', __NAMESPACE__ . '\\regACFBlocks', 5 );
|
||||||
+62
@@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Theme header template
|
||||||
|
*
|
||||||
|
* @package BasicWP
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace BasicWP;
|
||||||
|
|
||||||
|
global $views;
|
||||||
|
|
||||||
|
$headerLogo = getFieldValue( 'header.header_logo.url' ) ? getFieldValue( 'header.header_logo.url' ) : get_theme_file_uri( '/static/img/logo.svg' );
|
||||||
|
|
||||||
|
// Check conditions for displaying the hero section
|
||||||
|
$showHero = in_array(
|
||||||
|
true,
|
||||||
|
array(
|
||||||
|
get_field( 'hero_style' ) === 'default',
|
||||||
|
is_home(),
|
||||||
|
is_archive(),
|
||||||
|
is_single(),
|
||||||
|
is_search(),
|
||||||
|
is_404(),
|
||||||
|
),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html <?php language_attributes(); ?>>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title><?php wp_title( '' ); ?></title>
|
||||||
|
<meta charset="<?php bloginfo( 'charset' ); ?>">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<?php wp_head(); ?>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body <?php echo body_class(); ?>>
|
||||||
|
<a class="skip-link" href="#maincontent">
|
||||||
|
<?php echo esc_html__( 'Skip to main content' ); ?>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<header role="banner" class="site-header bg-secondary flex flex-col items-center justify-start">
|
||||||
|
<?php get_template_part( 'views/components/nav-aux' ); ?>
|
||||||
|
|
||||||
|
<div class="header__nav-main container py-4 items-center grid gap-x-8 gap-y-0 grid-cols-[83px_auto] grid-rows-[1fr] justify-between">
|
||||||
|
<a href="<?php bloginfo( 'url' ); ?>" class="site-header__logo block size-20">
|
||||||
|
<img class="size-full" src="<?php echo esc_url( $headerLogo ); ?>" alt="<?php bloginfo( 'name' ); ?> logo"/>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<?php get_template_part( 'views/components/nav-main' ); ?>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main id="maincontent" class="overflow-hidden min-h-[78dvh]">
|
||||||
|
<?php if ( $showHero ) : ?>
|
||||||
|
<?php get_template_part( 'views/partials/page-hero' ); ?>
|
||||||
|
<?php endif; ?>
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Blog posts list
|
||||||
|
*
|
||||||
|
* @package BasicWP
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace BasicWP;
|
||||||
|
|
||||||
|
// Determine classes based on sidebar presence
|
||||||
|
if ( hasSidebar() ) {
|
||||||
|
$classes = 'container grid grid-cols-1 lg:grid-cols-4 gap-8 xl:gap-16 my-section mx-auto';
|
||||||
|
$clsEntry = 'lg:col-span-3';
|
||||||
|
} else {
|
||||||
|
$classes = 'container my-section lg:my-0 mx-auto';
|
||||||
|
}
|
||||||
|
|
||||||
|
get_header();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<section class="<?php echo esc_attr( $classes ); ?>">
|
||||||
|
<?php if ( have_posts() ) : ?>
|
||||||
|
<div class="blog-posts <?php echo esc_attr( $clsEntry ); ?>">
|
||||||
|
<div class="post-list">
|
||||||
|
<div class="post-list__posts grid grid-cols-[repeat(auto-fit,minmax(20rem,1fr))] gap-6">
|
||||||
|
<?php
|
||||||
|
while ( have_posts() ) :
|
||||||
|
the_post();
|
||||||
|
?>
|
||||||
|
<div class="post-list__post flex flex-col border border-secondary rounded-md shadow-lg hover:prose-img:scale-110 hover:prose-img:origin-center hover:prose-img:duration-500">
|
||||||
|
<figure class="post-list__img aspect-video border-b border-secondary rounded-t-md block h-auto w-full overflow-hidden m-0 p-0">
|
||||||
|
<?php if ( has_post_thumbnail() ) : ?>
|
||||||
|
<?php
|
||||||
|
$featImg = get_the_post_thumbnail_url();
|
||||||
|
$postImg = $featImg ? $featImg : 'https://picsum.photos/600/400?random=' . get_the_ID();
|
||||||
|
$imgAlt = get_post_meta( get_post_thumbnail_id(), '_wp_attachment_image_alt', true ) ?? get_the_title();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<img class="block h-full object-cover transition-transform duration-300 ease-linear w-full will-change-transform" src="<?php echo esc_url( $postImg ); ?>" alt="<?php echo esc_attr( $imgAlt ); ?>">
|
||||||
|
<?php endif; ?>
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
<div class="post-list__details px-4 py-8 flex flex-col grow">
|
||||||
|
<div class="post-list__cats">
|
||||||
|
Posted in:
|
||||||
|
<?php
|
||||||
|
$categories = get_the_category();
|
||||||
|
foreach ( $categories as $index => $category ) :
|
||||||
|
$separator = $index < count( $categories ) - 1 ? ', ' : '';
|
||||||
|
?>
|
||||||
|
<a href="<?php echo esc_url( get_category_link( $category->term_id ) ); ?>" class="post-list__category text-14px font-semibold leading-none uppercase mt-0 mb-2.5 mx-0 inline-block"><?php echo esc_html( $category->name ); ?></a><?php echo esc_attr( $separator ); ?>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a href="<?php the_permalink(); ?>" class="">
|
||||||
|
<h2 class="post-list__title font-normal text-25px text-balance line-clamp-4 truncate mt-0 mb-5 mx-0"><?php the_title(); ?></h2>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="post-list__excerpt mb-6">
|
||||||
|
<?php customExcerpt( get_the_content(), 15 ); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="post-list__byline mt-auto">
|
||||||
|
<span class="post-list__author"><?php echo esc_html( ucfirst( get_the_author() ) ); ?> —</span>
|
||||||
|
<span class="post-list__date"><?php echo get_the_date(); ?></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php endwhile; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="post-list__pagination">
|
||||||
|
<?php
|
||||||
|
the_posts_pagination(
|
||||||
|
array(
|
||||||
|
'mid_size' => 2,
|
||||||
|
'prev_text' => '« Previous',
|
||||||
|
'next_text' => 'Next »',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php else : ?>
|
||||||
|
<div class="blog-posts <?php echo esc_attr( $clsEntry ); ?>">
|
||||||
|
<div class="no-posts">
|
||||||
|
<h2 class="no-posts__title">Nothing here yet…</h2>
|
||||||
|
<p class="no-posts__desc">No published posts found.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if ( hasSidebar() ) : ?>
|
||||||
|
<?php get_sidebar(); ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<?php get_footer(); ?>
|
||||||
@@ -0,0 +1,251 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* On Theme Activation adds Home and News pages, sets up reading options for front page and posts page, and erases sample page and post
|
||||||
|
*/
|
||||||
|
|
||||||
|
// phpcs:ignore
|
||||||
|
if ( isset( $_GET['activated'] ) && is_admin() ) {
|
||||||
|
// Set Blog Description to nothing
|
||||||
|
update_option( 'blogdescription', '' );
|
||||||
|
|
||||||
|
// List of pages to create with nested structure
|
||||||
|
$arrPages = array(
|
||||||
|
'Home' => array(),
|
||||||
|
'News' => array(),
|
||||||
|
'Page Not Found (Error 404)' => array(),
|
||||||
|
'Contact Us' => array(),
|
||||||
|
/**
|
||||||
|
* Sample nested structure
|
||||||
|
*
|
||||||
|
* 'Parent Page' => array(
|
||||||
|
* 'Subpage 1' => array(
|
||||||
|
* 'Sub-subpage 1',
|
||||||
|
* 'Sub-subpage 2'
|
||||||
|
* ),
|
||||||
|
* 'Subpage 2.2' => array()
|
||||||
|
* ),
|
||||||
|
*/
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ( $arrPages as $pageTitle => $childPages ) {
|
||||||
|
// phpcs:ignore
|
||||||
|
$pageExists = get_page_by_title($pageTitle);
|
||||||
|
|
||||||
|
if ( ! $pageExists ) {
|
||||||
|
// Create the parent page
|
||||||
|
$pageId = wp_insert_post(
|
||||||
|
array(
|
||||||
|
'post_title' => $pageTitle,
|
||||||
|
'post_content' => '',
|
||||||
|
'post_type' => 'page',
|
||||||
|
'post_status' => 'publish',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// If there are child pages, create them under the parent page
|
||||||
|
foreach ( $childPages as $childPageTitle => $subChildPages ) {
|
||||||
|
if ( is_array( $subChildPages ) ) {
|
||||||
|
$subpageId = wp_insert_post(
|
||||||
|
array(
|
||||||
|
'post_title' => $childPageTitle,
|
||||||
|
'post_content' => '',
|
||||||
|
'post_type' => 'page',
|
||||||
|
'post_status' => 'publish',
|
||||||
|
'post_parent' => $pageId,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ( $subChildPages as $subChildPageTitle ) {
|
||||||
|
wp_insert_post(
|
||||||
|
array(
|
||||||
|
'post_title' => $subChildPageTitle,
|
||||||
|
'post_content' => '',
|
||||||
|
'post_type' => 'page',
|
||||||
|
'post_status' => 'publish',
|
||||||
|
'post_parent' => $subpageId,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
wp_insert_post(
|
||||||
|
array(
|
||||||
|
'post_title' => $childPageTitle,
|
||||||
|
'post_content' => '',
|
||||||
|
'post_type' => 'page',
|
||||||
|
'post_status' => 'publish',
|
||||||
|
'post_parent' => $pageId,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use a static front page
|
||||||
|
// phpcs:ignore
|
||||||
|
$home = get_page_by_title('Home');
|
||||||
|
update_option( 'page_on_front', $home->ID );
|
||||||
|
update_option( 'show_on_front', 'page' );
|
||||||
|
|
||||||
|
// Set the blog/news page
|
||||||
|
// phpcs:ignore
|
||||||
|
$news = get_page_by_title('News');
|
||||||
|
update_option( 'page_for_posts', $news->ID );
|
||||||
|
|
||||||
|
// Trash the samples
|
||||||
|
wp_delete_post( 1, true );
|
||||||
|
wp_delete_post( 2, true );
|
||||||
|
|
||||||
|
// Flush rewrite rules to ensure new pages are recognized
|
||||||
|
flush_rewrite_rules();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install and activate must-use plugins
|
||||||
|
*/
|
||||||
|
|
||||||
|
$muPlugins = array(
|
||||||
|
array(
|
||||||
|
'url' => 'https://docs.vincentdevelopment.ca/files/advanced-custom-fields-pro.zip',
|
||||||
|
'active' => true,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'url' => 'https://docs.vincentdevelopment.ca/files/gravity-forms.zip',
|
||||||
|
'active' => true,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'url' => 'https://updraftplus.com/wp-content/uploads/updraftplus.zip',
|
||||||
|
'active' => false,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'url' => 'https://downloads.wordpress.org/plugin/simple-history.5.11.0.zip',
|
||||||
|
'active' => true,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'url' => 'https://downloads.wordpress.org/plugin/autodescription.5.1.2.zip',
|
||||||
|
'active' => true,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'url' => 'https://downloads.wordpress.org/plugin/better-search-replace.1.4.10.zip',
|
||||||
|
'active' => true,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'url' => 'https://downloads.wordpress.org/plugin/google-site-kit.1.153.0.zip',
|
||||||
|
'active' => false,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Custom log file
|
||||||
|
$logFile = WP_CONTENT_DIR . '/mu-plugin-install.log';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple logging function.
|
||||||
|
*
|
||||||
|
* @param string $message The message to log.
|
||||||
|
*/
|
||||||
|
function log_message( $message ) {
|
||||||
|
global $logFile;
|
||||||
|
$timestamp = gmdate( 'Y-m-d H:i:s' );
|
||||||
|
// phpcs:ignore
|
||||||
|
file_put_contents( $logFile, "[$timestamp] $message\n", FILE_APPEND );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Include necessary WordPress files
|
||||||
|
require_once ABSPATH . 'wp-admin/includes/file.php';
|
||||||
|
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
|
||||||
|
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||||
|
|
||||||
|
// Force direct filesystem access
|
||||||
|
add_filter( 'filesystem_method', fn() => 'direct' );
|
||||||
|
|
||||||
|
global $wp_filesystem;
|
||||||
|
if ( ! WP_Filesystem() ) {
|
||||||
|
log_message( 'Filesystem initialization failed.' );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define a silent skin to avoid show_message() errors
|
||||||
|
// phpcs:disable
|
||||||
|
class Silent_Upgrader_Skin extends WP_Upgrader_Skin {
|
||||||
|
public function feedback( $string, ...$args ) {}
|
||||||
|
public function header() {}
|
||||||
|
public function footer() {}
|
||||||
|
public function error( $errors ) {
|
||||||
|
log_message( 'Upgrader error: ' . print_r( $errors, true ) );
|
||||||
|
}
|
||||||
|
public function before() {}
|
||||||
|
public function after() {}
|
||||||
|
}
|
||||||
|
// phpcs:enable
|
||||||
|
|
||||||
|
$skin = new Silent_Upgrader_Skin();
|
||||||
|
$upgrader = new Plugin_Upgrader( $skin );
|
||||||
|
|
||||||
|
// Process each plugin
|
||||||
|
foreach ( $muPlugins as $plug ) {
|
||||||
|
$plugUrl = $plug['url'];
|
||||||
|
$shouldActivate = ! empty( $plug['active'] );
|
||||||
|
|
||||||
|
// Download plugin
|
||||||
|
$response = wp_remote_get( $plugUrl );
|
||||||
|
if ( is_wp_error( $response ) ) {
|
||||||
|
log_message( "Failed to download plugin from {$plugUrl}: " . $response->get_error_message() );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract filename from URL
|
||||||
|
$plugFileName = basename( wp_parse_url( $plugUrl, PHP_URL_PATH ) );
|
||||||
|
|
||||||
|
// Save the plugin zip
|
||||||
|
$plugZip = wp_upload_bits( $plugFileName, null, wp_remote_retrieve_body( $response ) );
|
||||||
|
if ( $plugZip['error'] ) {
|
||||||
|
log_message( "Failed to save plugin zip {$plugFileName}: " . $plugZip['error'] );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Install the plugin
|
||||||
|
$installResult = $upgrader->install( $plugZip['file'] );
|
||||||
|
if ( is_wp_error( $installResult ) ) {
|
||||||
|
log_message( "Failed to install plugin {$plugFileName}: " . $installResult->get_error_message() );
|
||||||
|
// Cleanup temp zip
|
||||||
|
if ( file_exists( $plugZip['file'] ) ) {
|
||||||
|
wp_delete_file( $plugZip['file'] );
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get plugin info ( folder/main file )
|
||||||
|
$plugInfo = $upgrader->plugin_info();
|
||||||
|
log_message( "plugin_info for {$plugFileName}: {$plugInfo}" );
|
||||||
|
|
||||||
|
if ( ! $plugInfo || ! file_exists( WP_PLUGIN_DIR . '/' . $plugInfo ) ) {
|
||||||
|
log_message( "Could not determine installed plugin file for {$plugFileName}." );
|
||||||
|
// Cleanup temp zip
|
||||||
|
if ( file_exists( $plugZip['file'] ) ) {
|
||||||
|
wp_delete_file( $plugZip['file'] );
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_message( "Successfully installed plugin {$plugInfo}." );
|
||||||
|
|
||||||
|
// Attempt activation if marked active
|
||||||
|
if ( $shouldActivate ) {
|
||||||
|
$activateResult = activate_plugin( $plugInfo );
|
||||||
|
if ( is_wp_error( $activateResult ) ) {
|
||||||
|
log_message( "Failed to activate plugin {$plugInfo}: " . $activateResult->get_error_message() );
|
||||||
|
} else {
|
||||||
|
log_message( "Successfully activated plugin {$plugInfo}." );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log_message( "Plugin {$plugInfo} installed but not activated ( per configuration )." );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup temp zip
|
||||||
|
if ( file_exists( $plugZip['file'] ) ) {
|
||||||
|
wp_delete_file( $plugZip['file'] );
|
||||||
|
log_message( "Deleted temporary zip file {$plugZip['file']}." );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log_message( '=== Plugin installation and activation process completed ===' );
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* ACF (Advanced Custom Fields) support class & functions
|
||||||
|
*
|
||||||
|
* @package BasicWP
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace BasicWP;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ACF
|
||||||
|
*
|
||||||
|
* This class serves as a wrapper or utility for handling Advanced Custom Fields (ACF) functionality.
|
||||||
|
* It is part of the Basic-WP project and is located in the `lib` directory.
|
||||||
|
*
|
||||||
|
* @package Basic-WP
|
||||||
|
*/
|
||||||
|
class ACF {
|
||||||
|
/**
|
||||||
|
* Variable to hold the file path.
|
||||||
|
*
|
||||||
|
* @var string $path The file path associated with the class.
|
||||||
|
*/
|
||||||
|
public $path;
|
||||||
|
|
||||||
|
/** Constructor.
|
||||||
|
*
|
||||||
|
* This constructor initializes the class by setting the file path and
|
||||||
|
* adding filters for loading and saving JSON files related to ACF.
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
$this->path = get_stylesheet_directory() . '/acf';
|
||||||
|
add_filter( 'acf/settings/load_json', array( $this, 'loadJson' ) );
|
||||||
|
add_filter( 'acf/settings/save_json', array( $this, 'saveJson' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Save JSON.
|
||||||
|
*
|
||||||
|
* @param mixed $path The path to save the JSON file.
|
||||||
|
*/
|
||||||
|
// phpcs:ignore
|
||||||
|
public function saveJson( $path ) {
|
||||||
|
return $this->path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Load JSON.
|
||||||
|
*
|
||||||
|
* @param mixed $paths The paths to load the JSON file.
|
||||||
|
*/
|
||||||
|
// phpcs:ignore
|
||||||
|
public function loadJson( $paths ) {
|
||||||
|
return array( $this->path );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( function_exists( 'get_fields' ) ) {
|
||||||
|
$acfInstance = new ACF();
|
||||||
|
}
|
||||||
@@ -0,0 +1,396 @@
|
|||||||
|
<?php
|
||||||
|
namespace BasicWP;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Breadcrumbs
|
||||||
|
*
|
||||||
|
* This class is responsible for generating and managing breadcrumb navigation
|
||||||
|
* for the WordPress theme. Breadcrumbs provide a navigational aid that helps
|
||||||
|
* users understand their location within the website's hierarchy.
|
||||||
|
*
|
||||||
|
* @package Basic-WP
|
||||||
|
* @subpackage Breadcrumbs
|
||||||
|
*/
|
||||||
|
class Breadcrumbs {
|
||||||
|
/**
|
||||||
|
* Generates the breadcrumb navigation for the website.
|
||||||
|
*
|
||||||
|
* This method is responsible for creating and returning the breadcrumb
|
||||||
|
* trail, which helps users navigate the website by showing their current
|
||||||
|
* location within the site's hierarchy.
|
||||||
|
*
|
||||||
|
* @return array An array of breadcrumb items, where each item is typically an
|
||||||
|
* associative array containing 'title' and 'url' keys.
|
||||||
|
*/
|
||||||
|
public static function generate() {
|
||||||
|
global $post;
|
||||||
|
|
||||||
|
$breadcrumbs = array();
|
||||||
|
|
||||||
|
// Always start with Home
|
||||||
|
$breadcrumbs[] = self::getHomeBreadcrumb();
|
||||||
|
|
||||||
|
if ( is_front_page() ) {
|
||||||
|
// Front Page - do nothing
|
||||||
|
return $breadcrumbs;
|
||||||
|
} elseif ( is_home() ) {
|
||||||
|
// Blog Index - add the Blog Posts Index page title
|
||||||
|
$breadcrumbs[] = self::getBlogPostsIndexBreadcrumb();
|
||||||
|
} elseif ( is_singular( 'post' ) ) {
|
||||||
|
// Single Post - add the category and post title
|
||||||
|
$breadcrumbs = array_merge( $breadcrumbs, self::getSinglePostBreadcrumbs() );
|
||||||
|
} elseif ( is_singular() && ! is_page() ) {
|
||||||
|
// Single Custom Post Type - add the post type archive and post title
|
||||||
|
$breadcrumbs = array_merge( $breadcrumbs, self::getCustomPostTypeBreadcrumbs() );
|
||||||
|
} elseif ( is_page() ) {
|
||||||
|
// Static Page - add the parent pages if any, and the page title
|
||||||
|
$breadcrumbs = array_merge( $breadcrumbs, self::getStaticPageBreadcrumbs( $post ) );
|
||||||
|
} elseif ( is_category() || is_tag() || is_tax() ) {
|
||||||
|
// Taxonomy Archive - add the taxonomy term name
|
||||||
|
$breadcrumbs[] = self::getTaxonomyArchiveBreadcrumb();
|
||||||
|
} elseif ( is_post_type_archive() ) {
|
||||||
|
// Post Type Archive - add the post type name
|
||||||
|
$breadcrumbs[] = self::getPostTypeArchiveBreadcrumb();
|
||||||
|
} elseif ( is_day() ) {
|
||||||
|
// Daily Archive - add the month and day links
|
||||||
|
$breadcrumbs = array_merge( $breadcrumbs, self::getDateArchiveBreadcrumbs() );
|
||||||
|
} elseif ( is_month() ) {
|
||||||
|
// Monthly Archive - add the month link
|
||||||
|
$breadcrumbs[] = self::getMonthArchiveBreadcrumb();
|
||||||
|
} elseif ( is_year() ) {
|
||||||
|
// Yearly Archive - add the year link
|
||||||
|
$breadcrumbs[] = self::getYearArchiveBreadcrumb();
|
||||||
|
} elseif ( is_author() ) {
|
||||||
|
// Author Archive - add the author name
|
||||||
|
$breadcrumbs[] = self::getAuthorArchiveBreadcrumb();
|
||||||
|
} elseif ( is_search() ) {
|
||||||
|
// Search Results - add the search query
|
||||||
|
$breadcrumbs[] = self::getSearchBreadcrumb();
|
||||||
|
} elseif ( is_404() ) {
|
||||||
|
// 404 Not Found - add a 404 message
|
||||||
|
$breadcrumbs[] = self::get404Breadcrumb();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $breadcrumbs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generates the breadcrumb for the home page.
|
||||||
|
*
|
||||||
|
* This method is responsible for creating the breadcrumb
|
||||||
|
* link or label that represents the home page in the breadcrumb
|
||||||
|
* navigation trail.
|
||||||
|
*
|
||||||
|
* @return string The HTML or text representation of the home breadcrumb.
|
||||||
|
*/
|
||||||
|
private static function getHomeBreadcrumb() {
|
||||||
|
return array(
|
||||||
|
'url' => home_url(),
|
||||||
|
'label' => 'Home',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generates the breadcrumb for the blog posts index page.
|
||||||
|
*
|
||||||
|
* This method is responsible for creating a breadcrumb entry
|
||||||
|
* that represents the blog posts index page in the breadcrumb trail.
|
||||||
|
*
|
||||||
|
* @return array An associative array representing the breadcrumb for the blog posts index page.
|
||||||
|
*/
|
||||||
|
private static function getBlogPostsIndexBreadcrumb() {
|
||||||
|
return array( 'label' => get_the_title( get_option( 'page_for_posts' ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generates the breadcrumb trail for a single post.
|
||||||
|
*
|
||||||
|
* This method is responsible for creating the breadcrumb navigation
|
||||||
|
* specific to single post views. It typically includes links to the
|
||||||
|
* homepage, category (or categories) the post belongs to, and the
|
||||||
|
* post title itself.
|
||||||
|
*
|
||||||
|
* @return array An array representing the breadcrumb trail, where each
|
||||||
|
* element is a breadcrumb item (e.g., URL and label).
|
||||||
|
*/
|
||||||
|
private static function getSinglePostBreadcrumbs() {
|
||||||
|
$breadcrumbs = array();
|
||||||
|
$categories = get_the_category();
|
||||||
|
|
||||||
|
$breadcrumbs[] = array(
|
||||||
|
'url' => get_permalink( get_option( 'page_for_posts' ) ),
|
||||||
|
'label' => get_the_title( get_option( 'page_for_posts' ) ),
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( ! empty( $categories ) ) {
|
||||||
|
$cat = $categories[0];
|
||||||
|
$breadcrumbs[] = array(
|
||||||
|
'url' => get_category_link( $cat ),
|
||||||
|
'label' => $cat->name,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$breadcrumbs[] = array( 'label' => get_the_title() );
|
||||||
|
return $breadcrumbs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generates breadcrumbs for custom post types.
|
||||||
|
*
|
||||||
|
* This method is responsible for creating breadcrumb navigation
|
||||||
|
* specific to custom post types. It retrieves and formats the
|
||||||
|
* breadcrumb trail based on the custom post type's hierarchy
|
||||||
|
* and structure.
|
||||||
|
*
|
||||||
|
* @return array An array representing the breadcrumb trail for the custom post type.
|
||||||
|
*/
|
||||||
|
private static function getCustomPostTypeBreadcrumbs() {
|
||||||
|
$breadcrumbs = array();
|
||||||
|
$postType = get_post_type_object( get_post_type() );
|
||||||
|
if ( $postType && ! in_array( get_post_type(), array( 'post', 'page' ), true ) ) {
|
||||||
|
$breadcrumbs[] = array(
|
||||||
|
'url' => get_post_type_archive_link( $postType->name ),
|
||||||
|
'label' => $postType->labels->name,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$breadcrumbs[] = array( 'label' => get_the_title() );
|
||||||
|
return $breadcrumbs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generates breadcrumbs for a static page.
|
||||||
|
*
|
||||||
|
* This method is responsible for creating breadcrumb navigation
|
||||||
|
* for static pages in a WordPress theme. It utilizes the provided
|
||||||
|
* post object to determine the breadcrumb structure.
|
||||||
|
*
|
||||||
|
* @param WP_Post $post The WordPress post object representing the static page.
|
||||||
|
* @return array An array of breadcrumb items, where each item is typically
|
||||||
|
* an associative array containing 'title' and 'url' keys.
|
||||||
|
*/
|
||||||
|
private static function getStaticPageBreadcrumbs( $post ) {
|
||||||
|
$breadcrumbs = array();
|
||||||
|
if ( $post->post_parent ) {
|
||||||
|
$ancestors = array_reverse( get_post_ancestors( $post->ID ) );
|
||||||
|
foreach ( $ancestors as $ancestor ) {
|
||||||
|
$breadcrumbs[] = array(
|
||||||
|
'url' => get_permalink( $ancestor ),
|
||||||
|
'label' => get_the_title( $ancestor ),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$breadcrumbs[] = array( 'label' => get_the_title() );
|
||||||
|
return $breadcrumbs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generates a breadcrumb for taxonomy archive pages.
|
||||||
|
*
|
||||||
|
* This method is responsible for creating breadcrumb navigation
|
||||||
|
* specific to taxonomy archive pages, providing users with a clear
|
||||||
|
* path to navigate back to the taxonomy or related sections.
|
||||||
|
*
|
||||||
|
* @return array An array representing the breadcrumb trail for the taxonomy archive.
|
||||||
|
*/
|
||||||
|
private static function getTaxonomyArchiveBreadcrumb() {
|
||||||
|
$term = get_queried_object();
|
||||||
|
return $term && isset( $term->name ) ? array( 'label' => $term->name ) : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generates a breadcrumb for the archive page of a custom post type.
|
||||||
|
*
|
||||||
|
* This method is responsible for creating a breadcrumb link that points
|
||||||
|
* to the archive page of a specific custom post type. It is typically used
|
||||||
|
* in breadcrumb navigation to provide users with a way to navigate back
|
||||||
|
* to the archive page of the post type they are currently viewing.
|
||||||
|
*
|
||||||
|
* @return array An array containing the breadcrumb data for the custom post type archive.
|
||||||
|
*/
|
||||||
|
private static function getPostTypeArchiveBreadcrumb() {
|
||||||
|
$postType = get_post_type_object( get_post_type() );
|
||||||
|
return $postType ? array( 'label' => $postType->labels->name ) : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generates breadcrumbs for date-based archives.
|
||||||
|
*
|
||||||
|
* This method is responsible for creating breadcrumb navigation
|
||||||
|
* for WordPress date archive pages, such as year, month, or day archives.
|
||||||
|
*
|
||||||
|
* @return array An array representing the breadcrumb trail for the date archive.
|
||||||
|
*/
|
||||||
|
private static function getDateArchiveBreadcrumbs() {
|
||||||
|
return array(
|
||||||
|
array(
|
||||||
|
'url' => get_month_link( get_query_var( 'year' ), get_query_var( 'monthnum' ) ),
|
||||||
|
'label' => get_the_date( 'F Y' ),
|
||||||
|
),
|
||||||
|
array( 'label' => get_the_date() ),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generates a breadcrumb for a monthly archive page.
|
||||||
|
*
|
||||||
|
* This method is responsible for creating a breadcrumb
|
||||||
|
* specific to WordPress monthly archive pages. It typically
|
||||||
|
* includes the year and month as part of the breadcrumb trail.
|
||||||
|
*
|
||||||
|
* @return string The HTML markup for the monthly archive breadcrumb.
|
||||||
|
*/
|
||||||
|
private static function getMonthArchiveBreadcrumb() {
|
||||||
|
return array( 'label' => get_the_date( 'F Y' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generates a breadcrumb for the year-based archive page.
|
||||||
|
*
|
||||||
|
* This method is responsible for creating a breadcrumb link
|
||||||
|
* specific to the year archive in a WordPress site. It is typically
|
||||||
|
* used to provide navigation for users when they are viewing posts
|
||||||
|
* filtered by a specific year.
|
||||||
|
*
|
||||||
|
* @return string The HTML markup for the year archive breadcrumb.
|
||||||
|
*/
|
||||||
|
private static function getYearArchiveBreadcrumb() {
|
||||||
|
return array( 'label' => get_the_date( 'Y' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generates the breadcrumb for the author archive page.
|
||||||
|
*
|
||||||
|
* This method is responsible for creating a breadcrumb trail
|
||||||
|
* specific to the author archive, providing navigation context
|
||||||
|
* for pages that display posts by a particular author.
|
||||||
|
*
|
||||||
|
* @return string The HTML markup for the author archive breadcrumb.
|
||||||
|
*/
|
||||||
|
private static function getAuthorArchiveBreadcrumb() {
|
||||||
|
$author = get_queried_object();
|
||||||
|
return array( 'label' => 'Author: ' . $author->display_name );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generates the breadcrumb for search results.
|
||||||
|
*
|
||||||
|
* This method is responsible for creating a breadcrumb trail
|
||||||
|
* specific to search result pages. It helps users navigate back
|
||||||
|
* to the search context or other parts of the site.
|
||||||
|
*
|
||||||
|
* @return string The HTML markup for the search breadcrumb.
|
||||||
|
*/
|
||||||
|
private static function getSearchBreadcrumb() {
|
||||||
|
return array( 'label' => 'Search: ' . get_search_query() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generates the breadcrumb trail for a 404 error page.
|
||||||
|
*
|
||||||
|
* This method is responsible for creating a breadcrumb structure
|
||||||
|
* specifically for 404 error pages, providing users with a navigational
|
||||||
|
* context when a requested page is not found.
|
||||||
|
*
|
||||||
|
* @return array An array representing the breadcrumb trail for the 404 page.
|
||||||
|
*/
|
||||||
|
private static function get404Breadcrumb() {
|
||||||
|
return array( 'label' => '404 Not Found' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Renders the breadcrumb navigation.
|
||||||
|
*
|
||||||
|
* This method generates and outputs the breadcrumb trail for the current page.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function render() {
|
||||||
|
$items = self::generate();
|
||||||
|
|
||||||
|
$metadata = array(
|
||||||
|
'@context' => 'https://schema.org',
|
||||||
|
'@type' => 'BreadcrumbList',
|
||||||
|
'itemListElement' => array(),
|
||||||
|
);
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<nav aria-label="Breadcrumbs" class="flex items-center py-2 -mx-2 leading-none" vocab="https://schema.org/" typeof="BreadcrumbList">
|
||||||
|
<?php foreach ( $items as $index => $item ) : ?>
|
||||||
|
<?php
|
||||||
|
$ldItem = array(
|
||||||
|
'@type' => 'ListItem',
|
||||||
|
'position' => $index + 1,
|
||||||
|
'name' => htmlspecialchars( $item['label'], ENT_QUOTES, 'UTF-8' ),
|
||||||
|
);
|
||||||
|
|
||||||
|
$isActive = ( $index === count( $items ) - 1 );
|
||||||
|
$activeClass = $isActive ? ' active' : '';
|
||||||
|
?>
|
||||||
|
<span class="p-2 breadcrumb-item<?php echo esc_attr( $activeClass ); ?>"
|
||||||
|
<?php
|
||||||
|
if ( $isActive ) :
|
||||||
|
?>
|
||||||
|
aria-current="page"<?php endif; ?>>
|
||||||
|
<?php if ( ! empty( $item['url'] ) ) : ?>
|
||||||
|
<a href="<?php echo esc_url( $item['url'] ); ?>">
|
||||||
|
<?php if ( $index === 0 ) : ?>
|
||||||
|
<svg class="flex-shrink-0 w-5 h-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" aria-label="Home">
|
||||||
|
<path d="M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z" />
|
||||||
|
</svg>
|
||||||
|
<span class="sr-only"><?php echo esc_attr( $item['label'] ); ?></span>
|
||||||
|
<?php else : ?>
|
||||||
|
<?php echo esc_attr( $item['label'] ); ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
</a>
|
||||||
|
<?php $ldItem['item'] = $item['url']; ?>
|
||||||
|
<?php else : ?>
|
||||||
|
<?php echo esc_attr( $item['label'] ); ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<?php $metadata['itemListElement'][] = $ldItem; ?>
|
||||||
|
|
||||||
|
<?php if ( ! $isActive ) : ?>
|
||||||
|
<svg class="flex-shrink-0 w-5 h-5 text-light" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||||
|
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<script type="application/ld+json"><?php echo esc_js( wp_json_encode( $metadata ) ); ?></script>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
echo wp_kses(
|
||||||
|
ob_get_clean(),
|
||||||
|
array(
|
||||||
|
'a' => array(
|
||||||
|
'class' => array(),
|
||||||
|
'href' => array(),
|
||||||
|
'title' => array(),
|
||||||
|
'rel' => array(),
|
||||||
|
'target' => array(),
|
||||||
|
'aria-label' => array(),
|
||||||
|
'aria-current' => array(),
|
||||||
|
),
|
||||||
|
'nav' => array(
|
||||||
|
'aria-label' => array(),
|
||||||
|
'class' => array(),
|
||||||
|
'vocab' => array(),
|
||||||
|
'typeof' => array(),
|
||||||
|
),
|
||||||
|
'span' => array(
|
||||||
|
'class' => array(),
|
||||||
|
'aria-current' => array(),
|
||||||
|
),
|
||||||
|
'svg' => array(
|
||||||
|
'class' => array(),
|
||||||
|
'xmlns' => array(),
|
||||||
|
'viewBox' => array(),
|
||||||
|
'fill' => array(),
|
||||||
|
'aria-hidden' => array(),
|
||||||
|
'aria-label' => array(),
|
||||||
|
),
|
||||||
|
'path' => array(
|
||||||
|
'd' => array(),
|
||||||
|
'fill-rule' => array(),
|
||||||
|
'clip-rule' => array(),
|
||||||
|
'fill' => array(),
|
||||||
|
'xmlns:xlink' => array(),
|
||||||
|
),
|
||||||
|
'script' => array(
|
||||||
|
'type' => array(),
|
||||||
|
'src' => array(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* BasicWP Theme Enqueue Class
|
||||||
|
*
|
||||||
|
* @package BasicWP
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace BasicWP;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Enqueue
|
||||||
|
*
|
||||||
|
* Handles the enqueueing of scripts and styles in a WordPress theme or plugin.
|
||||||
|
*
|
||||||
|
* @package Basic-WP
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
class Enqueue {
|
||||||
|
/**
|
||||||
|
* Initialize hooks to enqueue scripts and styles.
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
add_action( 'wp_enqueue_scripts', array( $this, 'enqFEAssets' ) );
|
||||||
|
add_action( 'admin_enqueue_scripts', array( $this, 'enqBEAssets' ) );
|
||||||
|
add_action( 'enqueue_block_editor_assets', array( $this, 'enqEditorAssets' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enqueue frontend CSS and JS files.
|
||||||
|
*/
|
||||||
|
public function enqFEAssets() {
|
||||||
|
$theme_dir = get_stylesheet_directory();
|
||||||
|
$theme_uri = get_stylesheet_directory_uri();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CSS
|
||||||
|
*/
|
||||||
|
$css_path = '/static/dist/theme.css';
|
||||||
|
if ( file_exists( $theme_dir . $css_path ) ) {
|
||||||
|
$version = filemtime( $theme_dir . $css_path );
|
||||||
|
wp_enqueue_style( 'basicwp-theme', $theme_uri . $css_path, array(), $version );
|
||||||
|
}
|
||||||
|
|
||||||
|
$font_ver = gmdate( 'U' );
|
||||||
|
wp_enqueue_style( 'raleway', 'https://fonts.googleapis.com/css2?family=Raleway:wght@100..900&display=swap', false, $font_ver );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JS
|
||||||
|
*/
|
||||||
|
$js_path = '/static/js/theme.js';
|
||||||
|
|
||||||
|
if ( file_exists( $theme_dir . $js_path ) ) {
|
||||||
|
$version = filemtime( $theme_dir . $js_path );
|
||||||
|
wp_enqueue_script( 'jquery' ); // Needed by downstream scripts; modules can't depend on classic scripts.
|
||||||
|
wp_enqueue_script_module( 'basicwp-theme', $theme_uri . $js_path, array(), $version );
|
||||||
|
wp_enqueue_script_module( 'basicwp-button', $theme_uri . '/static/js/components/button.js', array( 'basicwp-theme' ), $version );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enqueue backend (admin/editor) CSS and JS files.
|
||||||
|
*/
|
||||||
|
public function enqBEAssets() {
|
||||||
|
$theme_dir = get_stylesheet_directory();
|
||||||
|
$theme_uri = get_stylesheet_directory_uri();
|
||||||
|
|
||||||
|
$font_ver = gmdate( 'U' );
|
||||||
|
wp_enqueue_style( 'raleway', 'https://fonts.googleapis.com/css2?family=Raleway:wght@100..900&display=swap', false, $font_ver );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Admin CSS
|
||||||
|
*/
|
||||||
|
$admin_css_path = '/styles/backend/admin.css';
|
||||||
|
if ( file_exists( $theme_dir . $admin_css_path ) ) {
|
||||||
|
$version = filemtime( $theme_dir . $admin_css_path );
|
||||||
|
wp_enqueue_style( 'basicwp-admin', $theme_uri . $admin_css_path, array(), $version );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Admin JS
|
||||||
|
*/
|
||||||
|
$admin_js_path = '/static/js/admin.js';
|
||||||
|
if ( file_exists( $theme_dir . $admin_js_path ) ) {
|
||||||
|
$version = filemtime( $theme_dir . $admin_js_path );
|
||||||
|
wp_enqueue_script( 'jquery' ); // Needed by downstream scripts; modules can't depend on classic scripts.
|
||||||
|
wp_enqueue_script_module( 'basicwp-admin', $theme_uri . $admin_js_path, array(), $version );
|
||||||
|
wp_enqueue_script_module( 'basicwp-button', $theme_uri . '/static/js/components/button.js', array( 'basicwp-admin' ), $version );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enqueue block editor CSS (scoped to editor to avoid leaking into wp-admin UI).
|
||||||
|
*/
|
||||||
|
public function enqEditorAssets() {
|
||||||
|
$theme_dir = get_stylesheet_directory();
|
||||||
|
$theme_uri = get_stylesheet_directory_uri();
|
||||||
|
|
||||||
|
$editor_css_path = '/styles/backend/editor.css';
|
||||||
|
|
||||||
|
$font_ver = gmdate( 'U' );
|
||||||
|
wp_enqueue_style( 'raleway', 'https://fonts.googleapis.com/css2?family=Raleway:wght@100..900&display=swap', false, $font_ver );
|
||||||
|
|
||||||
|
if ( file_exists( $theme_dir . $editor_css_path ) ) {
|
||||||
|
$version = filemtime( $theme_dir . $editor_css_path );
|
||||||
|
wp_enqueue_style( 'basicwp-editor', $theme_uri . $editor_css_path, array(), $version );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the Enqueue class.
|
||||||
|
$enqueue = new Enqueue();
|
||||||
@@ -0,0 +1,185 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* BasicWP MenuItems Class
|
||||||
|
*
|
||||||
|
* @package BasicWP
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace BasicWP;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class MenuItems
|
||||||
|
*
|
||||||
|
* This class is responsible for managing menu items within the Basic-WP theme.
|
||||||
|
*
|
||||||
|
* @package Basic-WP
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
class MenuItems {
|
||||||
|
/**
|
||||||
|
* Accepts menu name to populate navigation items.
|
||||||
|
*
|
||||||
|
* @var string $displayLocation
|
||||||
|
*/
|
||||||
|
protected $displayLocation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* First level menu items (menu_item_parent = 0).
|
||||||
|
*
|
||||||
|
* @var array $topLevelNavItems
|
||||||
|
*/
|
||||||
|
public $topLevelNavItems;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if nav item has children items.
|
||||||
|
*
|
||||||
|
* @var bool $hasChildren
|
||||||
|
*/
|
||||||
|
public $hasChildren;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Children navigation items.
|
||||||
|
*
|
||||||
|
* @var array $nestedNavItems
|
||||||
|
*/
|
||||||
|
public $nestedNavItems;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if the current page is the same as the menu item.
|
||||||
|
*
|
||||||
|
* @var bool $currentPage
|
||||||
|
*/
|
||||||
|
public $currentPage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor method for initializing the class with a specific menu name.
|
||||||
|
*
|
||||||
|
* @param string $menuName The name of the menu to be used. Defaults to 'main_navigation'.
|
||||||
|
*/
|
||||||
|
public function __construct( $menuName = 'main_navigation' ) {
|
||||||
|
$this->displayLocation = $menuName;
|
||||||
|
|
||||||
|
$this->topLevelNavItems = $this->getTopLevelNavItems();
|
||||||
|
$this->hasChildren = function ( $item ) {
|
||||||
|
return $this->hasChildren( $item );
|
||||||
|
};
|
||||||
|
$this->nestedNavItems = function ( $parentItem ) {
|
||||||
|
return $this->getNestedNavItems( $parentItem );
|
||||||
|
};
|
||||||
|
$this->currentPage = function ( $item ) {
|
||||||
|
return $this->currentPage( $item );
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the list of menus.
|
||||||
|
*
|
||||||
|
* @return array An array containing menu items.
|
||||||
|
*/
|
||||||
|
public function getMenus() {
|
||||||
|
$menus = get_nav_menu_locations();
|
||||||
|
return empty( $menus ) ? array() : $menus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the navigation items.
|
||||||
|
*
|
||||||
|
* @return array An array of navigation items.
|
||||||
|
*/
|
||||||
|
public function getNavItems() {
|
||||||
|
$locations = $this->getMenus();
|
||||||
|
|
||||||
|
// If the menu location doesn't exist, return empty array
|
||||||
|
if ( ! isset( $locations[ $this->displayLocation ] ) ) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the menu ID for this location
|
||||||
|
$menuId = $locations[ $this->displayLocation ];
|
||||||
|
|
||||||
|
// Direct call to wp_get_nav_menu_items with the menu ID
|
||||||
|
$items = wp_get_nav_menu_items( $menuId );
|
||||||
|
|
||||||
|
// Return empty array if no items
|
||||||
|
return is_array( $items ) ? $items : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the given parent item has child items.
|
||||||
|
*
|
||||||
|
* @param mixed $parentItem The parent item to check for children.
|
||||||
|
* @return bool Returns true if the parent item has children, false otherwise.
|
||||||
|
*/
|
||||||
|
public function hasChildren( $parentItem ) {
|
||||||
|
foreach ( $this->getNavItems() as $item ) {
|
||||||
|
if ( $item->menu_item_parent === strval( $parentItem->ID ) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the top-level navigation items.
|
||||||
|
*
|
||||||
|
* @return array An array of top-level navigation items.
|
||||||
|
*/
|
||||||
|
public function getTopLevelNavItems() {
|
||||||
|
$items = array();
|
||||||
|
foreach ( $this->getNavItems() as $item ) {
|
||||||
|
if ( $item->menu_item_parent === '0' ) {
|
||||||
|
array_push( $items, $item );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $items;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the nested navigation items for a given parent item.
|
||||||
|
*
|
||||||
|
* @param mixed $parentItem The parent navigation item for which nested items are to be retrieved.
|
||||||
|
* @return array The list of nested navigation items.
|
||||||
|
*/
|
||||||
|
public function getNestedNavItems( $parentItem ) {
|
||||||
|
$childrenItems = array();
|
||||||
|
foreach ( $this->getNavItems() as $item ) {
|
||||||
|
if ( $item->menu_item_parent === strval( $parentItem->ID ) ) {
|
||||||
|
array_push( $childrenItems, $item );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $childrenItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the current page based on the provided item.
|
||||||
|
*
|
||||||
|
* @param mixed $item The item used to determine the current page.
|
||||||
|
* @return mixed The current page information.
|
||||||
|
*/
|
||||||
|
public function currentPage( $item ) {
|
||||||
|
global $wp;
|
||||||
|
return ( $item->url === home_url( $wp->request ) . '/' ) ? 'true' : 'false';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the output for the current context.
|
||||||
|
*
|
||||||
|
* This method is responsible for generating and returning the
|
||||||
|
* appropriate output for the current context or request.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function render() {
|
||||||
|
global $views;
|
||||||
|
|
||||||
|
// Extract class properties to local variables
|
||||||
|
$location = $this->displayLocation;
|
||||||
|
$topLevelNavItems = $this->topLevelNavItems;
|
||||||
|
$hasChildren = $this->hasChildren;
|
||||||
|
$nestedNavItems = $this->nestedNavItems;
|
||||||
|
$currentPage = $this->currentPage;
|
||||||
|
|
||||||
|
include $views . '/components/menu-items/index.php';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Resources custom post type & taxonomies
|
||||||
|
*
|
||||||
|
* @package BasicWP
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace BasicWP;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Resources
|
||||||
|
*
|
||||||
|
* This class is responsible for setting up the Resources post type and taxonomies.
|
||||||
|
*
|
||||||
|
* @package Basic-WP
|
||||||
|
*/
|
||||||
|
class Resources {
|
||||||
|
/**
|
||||||
|
* Constructor for the class.
|
||||||
|
*
|
||||||
|
* Initializes the class and sets up any necessary properties or methods.
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
add_action( 'init', array( $this, 'registerPostType' ) );
|
||||||
|
add_action( 'init', array( $this, 'registerTaxonomy' ) );
|
||||||
|
add_filter( 'post_type_link', array( $this, 'postTypeLink' ), 10, 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a custom post type.
|
||||||
|
*
|
||||||
|
* This method is responsible for defining and registering a custom post type
|
||||||
|
* with WordPress. It should include all necessary arguments and labels
|
||||||
|
* required for the post type to function correctly.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function registerPostType() {
|
||||||
|
register_post_type(
|
||||||
|
'resources',
|
||||||
|
array(
|
||||||
|
'labels' => array(
|
||||||
|
'name' => 'Resources',
|
||||||
|
'singular_name' => 'Resource',
|
||||||
|
'menu_name' => 'Resources',
|
||||||
|
'name_admin_bar' => 'Resource',
|
||||||
|
'add_new' => 'Add New Resource',
|
||||||
|
'add_new_item' => 'Add New Resource',
|
||||||
|
'edit_item' => 'Edit Resource',
|
||||||
|
'new_item' => 'New Resource',
|
||||||
|
'view_item' => 'View Resource',
|
||||||
|
'search_items' => 'Search Resources',
|
||||||
|
'not_found' => 'No resources found',
|
||||||
|
'not_found_in_trash' => 'No resources found in Trash',
|
||||||
|
),
|
||||||
|
'public' => true,
|
||||||
|
'has_archive' => true,
|
||||||
|
'rewrite' => array( 'slug' => 'resources' ),
|
||||||
|
'supports' => array( 'title', 'editor', 'excerpt', 'thumbnail', 'revisions', 'custom-fields' ),
|
||||||
|
'menu_position' => 20,
|
||||||
|
'menu_icon' => 'dashicons-hammer',
|
||||||
|
'show_in_rest' => true,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a custom taxonomy.
|
||||||
|
*
|
||||||
|
* This method is responsible for defining and registering a custom taxonomy
|
||||||
|
* within the WordPress environment. It should include the necessary arguments
|
||||||
|
* and settings for the taxonomy to function as intended.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function registerTaxonomy() {
|
||||||
|
register_taxonomy(
|
||||||
|
'resource_type',
|
||||||
|
array( 'resources' ),
|
||||||
|
array(
|
||||||
|
'labels' => array(
|
||||||
|
'name' => 'Resource Types',
|
||||||
|
'singular_name' => 'Resource Type',
|
||||||
|
'search_items' => 'Search Resource Types',
|
||||||
|
'all_items' => 'All Resource Types',
|
||||||
|
'parent_item' => 'Parent Resource Type',
|
||||||
|
'parent_item_colon' => 'Parent Resource Type:',
|
||||||
|
'edit_item' => 'Edit Resource Type',
|
||||||
|
'update_item' => 'Update Resource Type',
|
||||||
|
'add_new_item' => 'Add New Resource Type',
|
||||||
|
'new_item_name' => 'New Resource Type Name',
|
||||||
|
'menu_name' => 'Resource Types',
|
||||||
|
),
|
||||||
|
'public' => true,
|
||||||
|
'hierarchical' => true,
|
||||||
|
'show_admin_column' => true,
|
||||||
|
'rewrite' => array(
|
||||||
|
'slug' => 'resources',
|
||||||
|
'with_front' => false,
|
||||||
|
'hierarchical' => true,
|
||||||
|
),
|
||||||
|
'show_in_rest' => true,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters the permalink for a post of a specific post type.
|
||||||
|
*
|
||||||
|
* @param string $post_link The post's permalink.
|
||||||
|
* @param WP_Post $post The post object.
|
||||||
|
* @return string The filtered post permalink.
|
||||||
|
*/
|
||||||
|
public function postTypeLink( $post_link, $post ) {
|
||||||
|
if ( 'resources' === $post->post_type ) {
|
||||||
|
$terms = get_the_terms( $post->ID, 'resource_type' );
|
||||||
|
if ( $terms && ! is_wp_error( $terms ) ) {
|
||||||
|
$term_slug = $terms[0]->slug;
|
||||||
|
|
||||||
|
return home_url( "resources/{$term_slug}/{$post->post_name}" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $post_link;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new Resources();
|
||||||
+260
@@ -0,0 +1,260 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Filters. etc
|
||||||
|
*
|
||||||
|
* @package BasicWP
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace BasicWP;
|
||||||
|
|
||||||
|
/** Get child pages of the current page, sorted by menu order.
|
||||||
|
*
|
||||||
|
* @return array Array of child page objects, with URL added to each.
|
||||||
|
*/
|
||||||
|
function getChildrenPages() {
|
||||||
|
$children = get_pages(
|
||||||
|
array(
|
||||||
|
'child_of' => get_the_ID(),
|
||||||
|
'sort_order' => 'ASC',
|
||||||
|
'sort_column' => 'menu_order',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ( $children as &$child ) {
|
||||||
|
$child->url = get_page_link( $child->ID );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $children;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modify which pages should render the sidebar.
|
||||||
|
add_filter(
|
||||||
|
'hasSidebar',
|
||||||
|
function ( $has_sidebar ) {
|
||||||
|
// Add post types that should never have a sidebar.
|
||||||
|
|
||||||
|
if ( is_page() && ! get_field( 'has_sidebar' ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $has_sidebar;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Helper to check whether or not the sidebar should be rendered
|
||||||
|
* (to add/remove a sidebar from a page, edit the filter instead
|
||||||
|
* of modifying this function).
|
||||||
|
*/
|
||||||
|
function hasSidebar() {
|
||||||
|
return apply_filters( 'hasSidebar', true );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add extra body classes here.
|
||||||
|
add_filter(
|
||||||
|
'body_class',
|
||||||
|
function ( $classes ) {
|
||||||
|
if ( hasSidebar() ) {
|
||||||
|
$classes = array_merge( $classes, array( 'has-sidebar' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $classes;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the page should render a page header.
|
||||||
|
*
|
||||||
|
* @return bool true if page header should be rendered, false otherwise
|
||||||
|
*/
|
||||||
|
function hasPageHeader() {
|
||||||
|
global $post;
|
||||||
|
|
||||||
|
if ( get_field( 'hero_style' ) !== 'none' ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Create the Owner role.
|
||||||
|
*
|
||||||
|
* This function creates a new role named "Owner" with all the capabilities of the
|
||||||
|
* Administrator role, except for the following:
|
||||||
|
*
|
||||||
|
* - activate_plugins
|
||||||
|
* - delete_plugins
|
||||||
|
* - edit_plugins
|
||||||
|
* - install_plugins
|
||||||
|
* - update_plugins
|
||||||
|
* - switch_themes
|
||||||
|
* - edit_themes
|
||||||
|
* - delete_themes
|
||||||
|
* - install_themes
|
||||||
|
* - update_themes
|
||||||
|
* - update_core
|
||||||
|
* - manage_options
|
||||||
|
*
|
||||||
|
* This role is meant to be used by a person who should have almost all the same
|
||||||
|
* capabilities as an Administrator, but should not have the ability to update
|
||||||
|
* the WordPress core software, manage plugins or themes, or edit other site
|
||||||
|
* options.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function createOwnerRole() {
|
||||||
|
// First, remove the role if it exists.
|
||||||
|
remove_role( 'owner' );
|
||||||
|
|
||||||
|
// Get the administrator role.
|
||||||
|
$admin_role = get_role( 'administrator' );
|
||||||
|
$admin_capabilities = $admin_role->capabilities;
|
||||||
|
|
||||||
|
// Remove specific capabilities.
|
||||||
|
$capabilities_to_remove = array(
|
||||||
|
'activate_plugins',
|
||||||
|
'delete_plugins',
|
||||||
|
'edit_plugins',
|
||||||
|
'install_plugins',
|
||||||
|
'update_plugins',
|
||||||
|
'switch_themes',
|
||||||
|
'edit_themes',
|
||||||
|
'delete_themes',
|
||||||
|
'install_themes',
|
||||||
|
'update_themes',
|
||||||
|
'update_core',
|
||||||
|
'manage_options',
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ( $capabilities_to_remove as $capability ) {
|
||||||
|
unset( $admin_capabilities[ $capability ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the Owner role with the modified capabilities.
|
||||||
|
add_role( 'owner', 'Owner', $admin_capabilities );
|
||||||
|
}
|
||||||
|
add_action( 'init', __NAMESPACE__ . '\\createOwnerRole' );
|
||||||
|
|
||||||
|
/** Retrieves the appropriate title for the current page context.
|
||||||
|
*
|
||||||
|
* The function determines the type of page being viewed and returns
|
||||||
|
* the corresponding title. It handles different page types, including
|
||||||
|
* the home page, single posts, archives, search results, and 404 pages.
|
||||||
|
* If none of these conditions apply, it defaults to fetching the page's title.
|
||||||
|
*
|
||||||
|
* @return string The title relevant to the current page context.
|
||||||
|
*/
|
||||||
|
function getTheTitle() {
|
||||||
|
$title = '';
|
||||||
|
|
||||||
|
if ( is_home() || is_single() ) {
|
||||||
|
$title = get_the_title( get_option( 'page_for_posts', true ) );
|
||||||
|
} elseif ( is_archive() ) {
|
||||||
|
$title = get_the_archive_title();
|
||||||
|
} elseif ( is_search() ) {
|
||||||
|
$title = sprintf(
|
||||||
|
/* translators: %s is replaced with the search query */
|
||||||
|
__( 'Search Results for "%s"', 'basicwp' ),
|
||||||
|
get_search_query()
|
||||||
|
);
|
||||||
|
} elseif ( is_404() ) {
|
||||||
|
$title = 'Page Not Found (error 404)';
|
||||||
|
} else {
|
||||||
|
$title = get_the_title();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $title;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Wraps iframes and embed elements in a div with a specific class.
|
||||||
|
*
|
||||||
|
* This function searches for iframe and embed elements within the provided
|
||||||
|
* content and wraps each found element in a div with the class "embed".
|
||||||
|
* It is useful for applying consistent styling or responsive behavior
|
||||||
|
* to embedded media elements.
|
||||||
|
*
|
||||||
|
* @param string $content The HTML content containing iframes or embeds.
|
||||||
|
* @return string The modified content with wrapped iframes and embeds.
|
||||||
|
*/
|
||||||
|
function divWrapper( $content ) {
|
||||||
|
// match any iframes.
|
||||||
|
$pattern = '~<iframe.*</iframe>|<embed.*</embed>~';
|
||||||
|
preg_match_all( $pattern, $content, $matches );
|
||||||
|
|
||||||
|
foreach ( $matches[0] as $match ) {
|
||||||
|
// wrap matched iframe with div.
|
||||||
|
$wrappedframe = '<div class="embed">' . $match . '</div>';
|
||||||
|
|
||||||
|
// replace original iframe with new in content.
|
||||||
|
$content = str_replace( $match, $wrappedframe, $content );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_filter( 'the_content', __NAMESPACE__ . '\\divWrapper' );
|
||||||
|
|
||||||
|
/** Selectively add sidebar to page.
|
||||||
|
*
|
||||||
|
* This function adds a custom field group to the WordPress editor for
|
||||||
|
* pages, allowing users to specify whether a page should have a sidebar.
|
||||||
|
* Default is no sidebar.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
add_action(
|
||||||
|
'acf/include_fields',
|
||||||
|
function () {
|
||||||
|
if ( ! function_exists( 'acf_add_local_field_group' ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
acf_add_local_field_group(
|
||||||
|
array(
|
||||||
|
'key' => 'group_6817d79573087',
|
||||||
|
'title' => 'Page Sidebar',
|
||||||
|
'fields' => array(
|
||||||
|
array(
|
||||||
|
'key' => 'field_6817d7954a168',
|
||||||
|
'label' => '',
|
||||||
|
'name' => 'has_sidebar',
|
||||||
|
'aria-label' => '',
|
||||||
|
'type' => 'true_false',
|
||||||
|
'instructions' => '',
|
||||||
|
'required' => 0,
|
||||||
|
'conditional_logic' => 0,
|
||||||
|
'wrapper' => array(
|
||||||
|
'width' => '',
|
||||||
|
'class' => '',
|
||||||
|
'id' => '',
|
||||||
|
),
|
||||||
|
'message' => 'Should this page have a sidebar?',
|
||||||
|
'default_value' => 0,
|
||||||
|
'allow_in_bindings' => 0,
|
||||||
|
'ui' => 0,
|
||||||
|
'ui_on_text' => '',
|
||||||
|
'ui_off_text' => '',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'location' => array(
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'param' => 'post_type',
|
||||||
|
'operator' => '==',
|
||||||
|
'value' => 'page',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'menu_order' => 0,
|
||||||
|
'position' => 'side',
|
||||||
|
'style' => 'default',
|
||||||
|
'label_placement' => 'top',
|
||||||
|
'instruction_placement' => 'label',
|
||||||
|
'hide_on_screen' => '',
|
||||||
|
'active' => true,
|
||||||
|
'description' => '',
|
||||||
|
'show_in_rest' => 0,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
+219
@@ -0,0 +1,219 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* BasicWP Theme Helpers
|
||||||
|
*
|
||||||
|
* @package BasicWP
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace BasicWP;
|
||||||
|
|
||||||
|
// Define global variables for theme and views folder paths.
|
||||||
|
global $theme, $views;
|
||||||
|
|
||||||
|
$theme = get_template_directory();
|
||||||
|
$views = $theme . '/views';
|
||||||
|
|
||||||
|
/** Retrieves a nested value from an ACF field.
|
||||||
|
*
|
||||||
|
* @param string $field_path The dot-notated path to the value. For example, 'contact_info.phone'.
|
||||||
|
*
|
||||||
|
* @return mixed The value at the specified path.
|
||||||
|
*/
|
||||||
|
function getFieldValue( $field_path ) {
|
||||||
|
$parts = explode( '.', $field_path );
|
||||||
|
$field = get_field( array_shift( $parts ), 'option' );
|
||||||
|
|
||||||
|
foreach ( $parts as $part ) {
|
||||||
|
$field = $field[ $part ] ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $field;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns wrapper attributes for a block for both preview and front-end contexts.
|
||||||
|
*
|
||||||
|
* @param string $classes Space separated class list.
|
||||||
|
* @param bool $is_preview Whether the block is being previewed in the editor.
|
||||||
|
*
|
||||||
|
* @return string Wrapper attributes ready for output.
|
||||||
|
*/
|
||||||
|
function blockWrapperAttributes( $classes, $is_preview ) {
|
||||||
|
if ( $is_preview ) {
|
||||||
|
return 'class="' . $classes . '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return get_block_wrapper_attributes(
|
||||||
|
array(
|
||||||
|
'class' => $classes,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add Global Fields options page.
|
||||||
|
if ( function_exists( 'acf_add_options_page' ) ) {
|
||||||
|
add_action(
|
||||||
|
'init',
|
||||||
|
function () {
|
||||||
|
acf_add_options_page(
|
||||||
|
array(
|
||||||
|
'page_title' => 'Global Fields',
|
||||||
|
'menu_title' => 'Global Fields',
|
||||||
|
'menu_slug' => 'global-fields',
|
||||||
|
'icon_url' => 'dashicons-admin-site',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Customizes the order of the admin menu items in WordPress.
|
||||||
|
*
|
||||||
|
* This function modifies the default menu order in the WordPress admin dashboard
|
||||||
|
* by specifying a custom sequence for menu items, separators, and additional
|
||||||
|
* options. If the menu order is not specified, it returns true to allow the
|
||||||
|
* default order to be used.
|
||||||
|
*
|
||||||
|
* @param bool $menu_ord Indicates whether the menu order has been specified.
|
||||||
|
*
|
||||||
|
* @return array|bool An array specifying the custom menu order, or true if the
|
||||||
|
* menu order is not specified.
|
||||||
|
*/
|
||||||
|
function customMenuOrder( $menu_ord ) {
|
||||||
|
if ( ! $menu_ord ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'index.php', // Dashboard.
|
||||||
|
'global-fields', // Global Theme Fields.
|
||||||
|
'edit.php?post_type=acf-field-group', // ACF Field Groups.
|
||||||
|
'separator1', // First separator.
|
||||||
|
'edit.php', // Posts.
|
||||||
|
'edit.php?post_type=page', // Pages.
|
||||||
|
'edit.php?post_type=resources', // Resources.
|
||||||
|
'upload.php', // Media.
|
||||||
|
'separator2', // Second separator.
|
||||||
|
'edit.php?post_type=page-template', // Page Templates.
|
||||||
|
'edit.php?post_type=wp_block', // Reusable Blocks.
|
||||||
|
'edit.php?post_type=block-pattern', // Block Patterns.
|
||||||
|
'edit.php?post_type=element', // Elements.
|
||||||
|
'separator3', // Third separator.
|
||||||
|
'link-manager.php', // Links.
|
||||||
|
'edit-comments.php', // Comments.
|
||||||
|
'gf_edit_forms', // Gravity Forms.
|
||||||
|
'themes.php', // Appearance.
|
||||||
|
'plugins.php', // Plugins.
|
||||||
|
'separator-last', // Last separator.
|
||||||
|
'users.php', // Users.
|
||||||
|
'tools.php', // Tools.
|
||||||
|
'options-general.php', // Settings.
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
add_filter( 'custom_menu_order', __NAMESPACE__ . '\\customMenuOrder', 10, 1 );
|
||||||
|
add_filter( 'menu_order', __NAMESPACE__ . '\\customMenuOrder', 10, 1 );
|
||||||
|
|
||||||
|
/** Add custom block category for our blocks
|
||||||
|
*
|
||||||
|
* @param array $categories The existing block categories.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function blockCategories( $categories ) {
|
||||||
|
$vdi_cat = array(
|
||||||
|
'slug' => 'vdi-blocks',
|
||||||
|
'title' => 'VDI Custom Blocks',
|
||||||
|
'icon' => 'dashicons-admin-customizer',
|
||||||
|
);
|
||||||
|
|
||||||
|
array_unshift( $categories, $vdi_cat );
|
||||||
|
return $categories;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_filter( 'block_categories_all', __NAMESPACE__ . '\\blockCategories', 10, 2 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a escaping function to allowed certain HTML for embed content.
|
||||||
|
* Needed for when echoing the innerblock HTML.
|
||||||
|
*
|
||||||
|
* @return array An array of HTML elements allowed.
|
||||||
|
*/
|
||||||
|
function escEmbeds() {
|
||||||
|
/**
|
||||||
|
* Return the allowed html
|
||||||
|
* These are the elements in the rendered embed block for youtube and vimeo videos.
|
||||||
|
* Therefore we need to allow these to keep the same structure.
|
||||||
|
*/
|
||||||
|
return array(
|
||||||
|
'iframe' => array(
|
||||||
|
'role' => true, // Add role="presentation" to iframes.
|
||||||
|
'presentation' => true, // Add role="presentation" to iframes.
|
||||||
|
'src' => true,
|
||||||
|
'height' => true,
|
||||||
|
'width' => true,
|
||||||
|
'frameborder' => true,
|
||||||
|
'allowfullscreen' => true,
|
||||||
|
),
|
||||||
|
'figure' => array(
|
||||||
|
'class' => true,
|
||||||
|
),
|
||||||
|
'div' => array(
|
||||||
|
'class' => true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the numeric position of the first occurrence of a needle in a haystack array.
|
||||||
|
*
|
||||||
|
* @param string $haystack The string to search in.
|
||||||
|
* @param mixed $needles The array of strings to search for.
|
||||||
|
* @param int $offset (Optional) The position to start the search from.
|
||||||
|
* @return int|false The numeric position of the first occurrence of a needle in the haystack array.
|
||||||
|
*/
|
||||||
|
function strposArray( $haystack, $needles, $offset = 0 ) {
|
||||||
|
if ( is_array( $needles ) ) {
|
||||||
|
$positions = array();
|
||||||
|
|
||||||
|
foreach ( $needles as $str ) {
|
||||||
|
$pos = strpos( $haystack, $str, $offset );
|
||||||
|
|
||||||
|
if ( $pos !== false ) {
|
||||||
|
$positions[] = $pos; }
|
||||||
|
}
|
||||||
|
|
||||||
|
return count( $positions ) ? min( $positions ) : false;
|
||||||
|
} else {
|
||||||
|
return strpos( $haystack, $needles, $offset );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a custom excerpt for the given text.
|
||||||
|
*
|
||||||
|
* @param string $text The text to generate the excerpt from.
|
||||||
|
* @param int $number_of_words The maximum number of words in the excerpt. Default is 55.
|
||||||
|
* @param string|null $more The string to append to the end of the excerpt if it is truncated. Default is null.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function customExcerpt( $text, $number_of_words = 55, $more = null ) {
|
||||||
|
$allowed_end = array( '.', '!', '?', '...' );
|
||||||
|
$text_no_html = wp_strip_all_tags( $text );
|
||||||
|
$trimmed_text = wp_trim_words( $text, $number_of_words, $more );
|
||||||
|
$trimmed_text_length = strlen( $trimmed_text );
|
||||||
|
$sentence_end_position = strposArray( $text_no_html, $allowed_end, $trimmed_text_length );
|
||||||
|
$text_with_html = ( ( $sentence_end_position !== false ) ? substr( $text_no_html, 0, ( $sentence_end_position + 1 ) ) : $trimmed_text );
|
||||||
|
|
||||||
|
echo wp_kses_post( wpautop( $text_with_html ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Print a variable to the console for debugging purposes.
|
||||||
|
*
|
||||||
|
* @param mixed $data The data to print to the console.
|
||||||
|
*/
|
||||||
|
function consoleLog( $data ) {
|
||||||
|
echo '<script>';
|
||||||
|
echo 'console.log(' . wp_json_encode( $data ) . ')';
|
||||||
|
echo '</script>';
|
||||||
|
}
|
||||||
+301
@@ -0,0 +1,301 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* BasicWP Theme Hooks
|
||||||
|
*
|
||||||
|
* @package BasicWP
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace BasicWP;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add preconnect for Google fonts to head
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
add_action(
|
||||||
|
'wp_head',
|
||||||
|
function () {
|
||||||
|
?>
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<?php
|
||||||
|
},
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the navigation menus.
|
||||||
|
*
|
||||||
|
* @link https://developer.wordpress.org/reference/functions/register_nav_menus/
|
||||||
|
*/
|
||||||
|
register_nav_menus(
|
||||||
|
array(
|
||||||
|
'main_navigation' => 'Main Navigation',
|
||||||
|
'aux_navigation' => 'Auxiliary Navigation',
|
||||||
|
'footer_navigation' => 'Footer Navigation',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Widget Areas
|
||||||
|
*
|
||||||
|
* Set up sidebar/widget areas for the theme.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
add_action(
|
||||||
|
'widgets_init',
|
||||||
|
function () {
|
||||||
|
$config = array(
|
||||||
|
'before_widget' => '<div class="widget %1$s %2$s">',
|
||||||
|
'after_widget' => '</div>',
|
||||||
|
'before_title' => '<h2>',
|
||||||
|
'after_title' => '</h2>',
|
||||||
|
);
|
||||||
|
|
||||||
|
$cfg_foot = array(
|
||||||
|
'before_widget' => '<div class="widget %1$s %2$s">',
|
||||||
|
'after_widget' => '</div>',
|
||||||
|
'before_title' => '<h4>',
|
||||||
|
'after_title' => '</h4>',
|
||||||
|
);
|
||||||
|
|
||||||
|
register_sidebar(
|
||||||
|
array(
|
||||||
|
'name' => 'Primary Sidebar',
|
||||||
|
'id' => 'sidebar-primary',
|
||||||
|
) + $config
|
||||||
|
);
|
||||||
|
|
||||||
|
register_sidebar(
|
||||||
|
array(
|
||||||
|
'name' => 'Page Sidebar',
|
||||||
|
'id' => 'sidebar-page',
|
||||||
|
) + $config
|
||||||
|
);
|
||||||
|
|
||||||
|
register_sidebar(
|
||||||
|
array(
|
||||||
|
'name' => 'Footer Area 1',
|
||||||
|
'id' => 'footer-1',
|
||||||
|
) + $cfg_foot
|
||||||
|
);
|
||||||
|
|
||||||
|
register_sidebar(
|
||||||
|
array(
|
||||||
|
'name' => 'Footer Area 2',
|
||||||
|
'id' => 'footer-2',
|
||||||
|
) + $cfg_foot
|
||||||
|
);
|
||||||
|
|
||||||
|
register_sidebar(
|
||||||
|
array(
|
||||||
|
'name' => 'Footer Area 3',
|
||||||
|
'id' => 'footer-3',
|
||||||
|
) + $cfg_foot
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic SEO
|
||||||
|
*
|
||||||
|
* {Site URL}: {Title}
|
||||||
|
*/
|
||||||
|
add_filter(
|
||||||
|
'wp_title',
|
||||||
|
function ( $title ) {
|
||||||
|
$site_name = get_bloginfo( 'name' );
|
||||||
|
|
||||||
|
return "{$site_name}: {$title}";
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Excerpt
|
||||||
|
*/
|
||||||
|
add_filter(
|
||||||
|
'excerpt_more',
|
||||||
|
function () {
|
||||||
|
return '…';
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the page hero should hold the main h1 of the page.
|
||||||
|
*/
|
||||||
|
add_filter(
|
||||||
|
'include_page_title_in_hero',
|
||||||
|
function ( $include_title ) {
|
||||||
|
// Add post types that should not use the title in the hero.
|
||||||
|
if ( is_singular( ( 'post' ) ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $include_title;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WP Cleanup
|
||||||
|
*/
|
||||||
|
function init() {
|
||||||
|
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
|
||||||
|
remove_action( 'wp_print_styles', 'print_emoji_styles' );
|
||||||
|
remove_action( 'admin_print_styles', 'print_emoji_styles' );
|
||||||
|
remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
|
||||||
|
remove_filter( 'the_content_feed', 'wp_staticize_emoji' );
|
||||||
|
remove_filter( 'comment_text_rss', 'wp_staticize_emoji' );
|
||||||
|
remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
|
||||||
|
wp_dequeue_style( 'wp-block-library' ); // Core block styles.
|
||||||
|
wp_dequeue_style( 'wp-block-library-theme' ); // Block theme styles.
|
||||||
|
wp_dequeue_style( 'global-styles' ); // Global styles.
|
||||||
|
wp_dequeue_style( 'core-block-supports' ); // Core block supports.
|
||||||
|
wp_dequeue_style( 'core-block-styles' ); // Core block styles.
|
||||||
|
remove_action( 'wp_enqueue_scripts', 'wp_enqueue_global_styles', 1 );
|
||||||
|
remove_action( 'wp_enqueue_scripts', 'wp_enqueue_classic_theme_styles', 1 );
|
||||||
|
remove_action( 'wp_head', 'wp_print_head_scripts', 9 );
|
||||||
|
remove_action( 'wp_head', 'wp_generator' ); // WordPress version.
|
||||||
|
remove_action( 'wp_head', 'rsd_link' ); // RSD link.
|
||||||
|
remove_action( 'wp_head', 'wlwmanifest_link' ); // Windows Live Writer.
|
||||||
|
remove_action( 'wp_head', 'wp_shortlink_wp_head' ); // Shortlink.
|
||||||
|
remove_action( 'wp_head', 'rest_output_link_wp_head' ); // REST API link.
|
||||||
|
remove_action( 'wp_head', 'wp_oembed_add_discovery_links' ); // oEmbed discovery links.
|
||||||
|
remove_action( 'wp_head', 'rel_canonical' ); // Canonical URL.
|
||||||
|
remove_action( 'wp_head', 'wp_resource_hints', 2 ); // DNS Prefetch.
|
||||||
|
add_filter( 'wp_img_tag_add_width_and_height_attr', '__return_false' ); // Disable intrinsic image size.
|
||||||
|
add_filter( 'wp_img_tag_add_auto_sizes', '__return_false' ); // Disable auto sizes.
|
||||||
|
add_filter( 'xmlrpc_enabled', '__return_false' );
|
||||||
|
|
||||||
|
// Add theme support features
|
||||||
|
add_theme_support( 'post-thumbnails' );
|
||||||
|
add_theme_support( 'title-tag' );
|
||||||
|
add_theme_support(
|
||||||
|
'html5',
|
||||||
|
array(
|
||||||
|
'caption',
|
||||||
|
'comment-form',
|
||||||
|
'comment-list',
|
||||||
|
'gallery',
|
||||||
|
'global-search-form',
|
||||||
|
'script',
|
||||||
|
'style',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
add_theme_support( 'align-wide' );
|
||||||
|
add_theme_support( 'editor-styles' );
|
||||||
|
add_theme_support( 'responsive-embeds' );
|
||||||
|
add_theme_support( 'customize-selective-refresh-widgets' );
|
||||||
|
}
|
||||||
|
|
||||||
|
add_action( 'init', __NAMESPACE__ . '\\init', 1 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow SVG uploads
|
||||||
|
*/
|
||||||
|
add_filter(
|
||||||
|
'wp_check_filetype_and_ext',
|
||||||
|
function ( $data, $file, $filename, $mimes ) {
|
||||||
|
global $wp_version;
|
||||||
|
|
||||||
|
if ( '4.7.1' !== $wp_version ) {
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
$filetype = wp_check_filetype( $filename, $mimes );
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'ext' => $filetype['ext'],
|
||||||
|
'type' => $filetype['type'],
|
||||||
|
'proper_filename' => $data['proper_filename'],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
10,
|
||||||
|
4
|
||||||
|
);
|
||||||
|
|
||||||
|
add_filter(
|
||||||
|
'upload_mimes',
|
||||||
|
function ( $mimes ) {
|
||||||
|
$mimes['svg'] = 'image/svg+xml';
|
||||||
|
return $mimes;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fix display issues with SVGs in admin
|
||||||
|
*/
|
||||||
|
add_action(
|
||||||
|
'admin_head',
|
||||||
|
function () {
|
||||||
|
echo '
|
||||||
|
<style type="text/css">
|
||||||
|
.attachment-266x266, .thumbnail img {
|
||||||
|
width: 100% !important;
|
||||||
|
height: auto !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
';
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters the email address used as the sender in outgoing emails.
|
||||||
|
*
|
||||||
|
* This function allows you to modify the default "from" email address
|
||||||
|
* used by WordPress when sending emails.
|
||||||
|
*
|
||||||
|
* @param string $old The original email address.
|
||||||
|
* @return string The new email address to use as the sender.
|
||||||
|
*/
|
||||||
|
// phpcs:ignore
|
||||||
|
function new_mail_from( $old ) {
|
||||||
|
return get_option( 'admin_email' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters the name used as the sender in outgoing emails.
|
||||||
|
*
|
||||||
|
* This function allows you to modify the default "from" name
|
||||||
|
* used by WordPress when sending emails.
|
||||||
|
*
|
||||||
|
* @param string $old The original name.
|
||||||
|
* @return string The new name to use as the sender.
|
||||||
|
*/
|
||||||
|
// phpcs:ignore
|
||||||
|
function new_mail_from_name( $old ) {
|
||||||
|
return get_option( 'blogname' );
|
||||||
|
}
|
||||||
|
|
||||||
|
add_filter( 'wp_mail_from', __NAMESPACE__ . '\\new_mail_from' );
|
||||||
|
add_filter( 'wp_mail_from_name', __NAMESPACE__ . '\\new_mail_from_name' );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add child page template
|
||||||
|
*/
|
||||||
|
add_filter(
|
||||||
|
'page_template',
|
||||||
|
function ( $template ) {
|
||||||
|
global $post;
|
||||||
|
|
||||||
|
if ( $post->post_parent ) {
|
||||||
|
// get top level parent page
|
||||||
|
$parent = get_post(
|
||||||
|
reset( array_reverse( get_post_ancestors( $post->ID ) ) )
|
||||||
|
);
|
||||||
|
|
||||||
|
$child_template = locate_template(
|
||||||
|
array(
|
||||||
|
$parent->post_name . '-child.php',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( $child_template ) {
|
||||||
|
return $child_template;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $template;
|
||||||
|
}
|
||||||
|
);
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Search features for BasicWP theme.
|
||||||
|
*
|
||||||
|
* @package BasicWP
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace BasicWP;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modifies the WordPress query object for page search functionality.
|
||||||
|
*
|
||||||
|
* @param WP_Query $query The WordPress query object.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function pageSearch( $query ) {
|
||||||
|
if ( ! is_admin() && $query->is_main_query() && $query->is_search ) {
|
||||||
|
$query->set( 'paged', ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1 );
|
||||||
|
$query->set( 'posts_per_page', -1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
add_action( 'pre_get_posts', __NAMESPACE__ . '\\pageSearch' );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort WP_Post objects in reverse order (most recent first).
|
||||||
|
*
|
||||||
|
* @param string $key WP_Post object property used for sorting. 'post_date' is assumed.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
function postSort( $key ) {
|
||||||
|
return function ( $a, $b ) use ( $key ) {
|
||||||
|
if ( $a->$key < $b->$key ) {
|
||||||
|
return 1;
|
||||||
|
} elseif ( $a->$key > $b->$key ) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
// If first comparison is equal, use title as secondary sort key.
|
||||||
|
return strnatcasecmp( $a->post_title, $b->post_title );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove duplicate posts in combined list from default and secondary queries.
|
||||||
|
*
|
||||||
|
* @param array $posts Array of WP_Post objects.
|
||||||
|
* @param string $key Search key used to identify duplicate objects. Post ID is used.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function dedupe( $posts, $key ) {
|
||||||
|
$unique_posts = array();
|
||||||
|
$ids = array();
|
||||||
|
|
||||||
|
foreach ( $posts as $post ) {
|
||||||
|
if ( ! in_array( $post->$key, $ids, true ) ) {
|
||||||
|
$ids[] = $post->$key;
|
||||||
|
$unique_posts[] = $post;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $unique_posts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Posts_results filter hook callback.
|
||||||
|
*
|
||||||
|
* @param array $posts Array of WP_Post objects.
|
||||||
|
* @param object $query WP_Query object from default search.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function searchResultFilter( $posts, $query ) {
|
||||||
|
if ( \is_search() && $query->is_search() && ! \is_admin() ) {
|
||||||
|
$args = array(
|
||||||
|
'post_type' => array( 'post', 'page' ),
|
||||||
|
'posts_per_page' => -1,
|
||||||
|
'tax_query' => array(
|
||||||
|
'relation' => 'OR', // Include both tags and categories.
|
||||||
|
array(
|
||||||
|
'taxonomy' => 'post_tag',
|
||||||
|
'field' => 'name',
|
||||||
|
'terms' => $query->get( 's' ),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'taxonomy' => 'category',
|
||||||
|
'field' => 'name',
|
||||||
|
'terms' => $query->get( 's' ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Remove callback to avoid infinite loop.
|
||||||
|
remove_filter( 'posts_results', __NAMESPACE__ . '\\searchResultFilter', 10 );
|
||||||
|
|
||||||
|
$secondary_query = new \WP_Query( $args );
|
||||||
|
|
||||||
|
$tagged_posts = $secondary_query->get_posts();
|
||||||
|
|
||||||
|
// Combine default search results with secondary query.
|
||||||
|
$all_posts = array_merge( $posts, $tagged_posts );
|
||||||
|
|
||||||
|
// Remove duplicate posts.
|
||||||
|
$unique_posts = dedupe( $all_posts, 'ID' );
|
||||||
|
|
||||||
|
// Sort by reverse post_date order (most recent first).
|
||||||
|
usort( $unique_posts, postSort( 'post_date' ) );
|
||||||
|
|
||||||
|
// Restore posts_results callback.
|
||||||
|
add_filter( 'posts_results', __NAMESPACE__ . '\\searchResultFilter', 10, 2 );
|
||||||
|
|
||||||
|
return $unique_posts;
|
||||||
|
} else {
|
||||||
|
return $posts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
add_filter( 'posts_results', __NAMESPACE__ . '\\searchResultFilter', 10, 2 );
|
||||||
@@ -0,0 +1,174 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Add a comment to show which template is being used on the current page.
|
||||||
|
*
|
||||||
|
* @package BasicWP
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace BasicWP;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ShowTemplate
|
||||||
|
*
|
||||||
|
* Displays the active WordPress template in the footer for debugging purposes.
|
||||||
|
* Determines which template WordPress has chosen to use and outputs it as an HTML comment.
|
||||||
|
*
|
||||||
|
* @package BasicWP
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
class ShowTemplate {
|
||||||
|
/**
|
||||||
|
* The template file path that WordPress has chosen to use.
|
||||||
|
*
|
||||||
|
* @var string|false
|
||||||
|
*/
|
||||||
|
private $template = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for ShowTemplate class.
|
||||||
|
*
|
||||||
|
* Initializes the template checking functionality by hooking into template_redirect action.
|
||||||
|
* Does nothing if called from admin area.
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
if ( is_admin() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_action( 'template_redirect', array( &$this, 'checkTemplate' ), 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Using the same logic used by WordPress determine the template to be used
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public function checkTemplate() {
|
||||||
|
if ( is_404() ) {
|
||||||
|
$template = get_404_template();
|
||||||
|
|
||||||
|
if ( $template ) {
|
||||||
|
$this->template = $template;
|
||||||
|
}
|
||||||
|
} elseif ( is_search() ) {
|
||||||
|
$template = get_search_template();
|
||||||
|
|
||||||
|
if ( $template ) {
|
||||||
|
$this->template = $template;
|
||||||
|
}
|
||||||
|
} elseif ( is_tax() ) {
|
||||||
|
$template = get_taxonomy_template();
|
||||||
|
|
||||||
|
if ( $template ) {
|
||||||
|
$this->template = $template;
|
||||||
|
}
|
||||||
|
} elseif ( is_home() ) {
|
||||||
|
$template = get_home_template();
|
||||||
|
|
||||||
|
if ( $template ) {
|
||||||
|
$this->template = $template;
|
||||||
|
}
|
||||||
|
} elseif ( is_front_page() ) {
|
||||||
|
$template = get_front_page_template();
|
||||||
|
|
||||||
|
if ( $template ) {
|
||||||
|
$this->template = $template;
|
||||||
|
}
|
||||||
|
} elseif ( is_attachment() ) {
|
||||||
|
$template = get_attachment_template();
|
||||||
|
|
||||||
|
if ( $template ) {
|
||||||
|
$this->template = $template;
|
||||||
|
}
|
||||||
|
} elseif ( is_single() ) {
|
||||||
|
$template = get_single_template();
|
||||||
|
|
||||||
|
if ( $template ) {
|
||||||
|
$this->template = $template;
|
||||||
|
}
|
||||||
|
} elseif ( is_page() ) {
|
||||||
|
$template = get_page_template();
|
||||||
|
|
||||||
|
if ( $template ) {
|
||||||
|
$this->template = $template;
|
||||||
|
}
|
||||||
|
} elseif ( is_category() ) {
|
||||||
|
$template = get_category_template();
|
||||||
|
|
||||||
|
if ( $template ) {
|
||||||
|
$this->template = $template;
|
||||||
|
}
|
||||||
|
} elseif ( is_tag() ) {
|
||||||
|
$template = get_tag_template();
|
||||||
|
|
||||||
|
if ( $template ) {
|
||||||
|
$this->template = $template;
|
||||||
|
}
|
||||||
|
} elseif ( is_author() ) {
|
||||||
|
$template = get_author_template();
|
||||||
|
|
||||||
|
if ( $template ) {
|
||||||
|
$this->template = $template;
|
||||||
|
}
|
||||||
|
} elseif ( is_date() ) {
|
||||||
|
$template = get_date_template();
|
||||||
|
|
||||||
|
if ( $template ) {
|
||||||
|
$this->template = $template;
|
||||||
|
}
|
||||||
|
} elseif ( is_archive() ) {
|
||||||
|
$template = get_archive_template();
|
||||||
|
|
||||||
|
if ( $template ) {
|
||||||
|
$this->template = $template;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->template = function_exists( 'get_index_template' ) ? get_index_template() : get_template_directory() . '/index.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->template = apply_filters( 'template_include', $this->template );
|
||||||
|
|
||||||
|
// Hook into the footer so we can echo the active template
|
||||||
|
add_action( 'wp_footer', array( &$this, 'show_template' ), 100 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Echo the active template to the footer
|
||||||
|
* Try to catch when a plugin or otherwise hooks template_redirect to include a different template
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public function show_template() {
|
||||||
|
$fudge = false;
|
||||||
|
|
||||||
|
foreach ( debug_backtrace() as $trace ) { // phpcs:ignore
|
||||||
|
switch ( $trace['function'] ) {
|
||||||
|
case 'wp_footer':
|
||||||
|
$wp_footer = $trace['file'];
|
||||||
|
break;
|
||||||
|
case 'get_footer':
|
||||||
|
$get_footer = $trace['file'];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$fudge = isset( $get_footer ) ? $get_footer : $wp_footer;
|
||||||
|
|
||||||
|
if ( $fudge === $this->template || $fudge === false ) {
|
||||||
|
echo wp_kses_post( "<!-- Active Template: {$this->template} -->\n" );
|
||||||
|
} else {
|
||||||
|
echo esc_html( "<!--\n" );
|
||||||
|
echo esc_html( "The template loader logic has chosen a different template than what was used.\n\n" );
|
||||||
|
echo esc_html( "Chosen Template: {$this->template}\n" );
|
||||||
|
echo esc_html( "Actual Template: $fudge\n\n" );
|
||||||
|
echo esc_html( "This will usually occur if the template file was overriden using an action on template_redirect.\n" );
|
||||||
|
echo esc_html( "This is a best effort guess to catch such scenarios as mentioned above but can be incorrect.\n" );
|
||||||
|
echo esc_html( "-->\n" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$ShowTemplate = new ShowTemplate();
|
||||||
Generated
+3021
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "vdi-starter-v5",
|
||||||
|
"version": "5.0",
|
||||||
|
"description": "VDI-Starter-v5 is a minimal WordPress theme designed as a starting point for custom theme development. It focuses on modern development approaches with a lean architecture that avoids the overhead of theme frameworks.",
|
||||||
|
"scripts": {
|
||||||
|
"start": "npm run watch",
|
||||||
|
"watch": "node bin/.watch.js",
|
||||||
|
"build": "npx @tailwindcss/cli -i ./styles/theme.css -o ./static/dist/theme.css --optimize"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/Vincent-Design-Inc/VDI-Starter-v5.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"wordpress",
|
||||||
|
"minimal",
|
||||||
|
"basic",
|
||||||
|
"custom",
|
||||||
|
"theme"
|
||||||
|
],
|
||||||
|
"author": "Keith Solomon <keith@vincentdesign.ca>",
|
||||||
|
"license": "MIT",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/Vincent-Design-Inc/VDI-Starter-v5/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/Vincent-Design-Inc/VDI-Starter-v5#readme",
|
||||||
|
"devDependencies": {
|
||||||
|
"@axe-core/playwright": "^4.10.1",
|
||||||
|
"@playwright/test": "^1.52.0",
|
||||||
|
"@types/node": "^22.15.2",
|
||||||
|
"browser-sync": "^3.0.3",
|
||||||
|
"dotenv": "^16.4.7"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@tailwindcss/cli": "^4.0.13",
|
||||||
|
"@tailwindcss/typography": "^0.5.16",
|
||||||
|
"glob": "^10.3.10",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"lodash.debounce": "^4.0.8",
|
||||||
|
"tailwindcss": "^4.0.13"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Single Pages
|
||||||
|
*
|
||||||
|
* @package BasicWP
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace BasicWP;
|
||||||
|
|
||||||
|
get_header();
|
||||||
|
|
||||||
|
$clsEntry = '';
|
||||||
|
|
||||||
|
// Determine classes based on sidebar presence
|
||||||
|
if ( hasSidebar() ) {
|
||||||
|
$classes = 'container grid grid-cols-1 lg:grid-cols-4 gap-8 xl:gap-16 my-section mx-auto';
|
||||||
|
$clsEntry = 'lg:col-span-3';
|
||||||
|
} else {
|
||||||
|
$classes = 'container my-section lg:my-0 mx-auto';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<article class="<?php echo esc_attr( $classes ); ?>">
|
||||||
|
<div class="entry-content <?php echo esc_attr( $clsEntry ); ?>">
|
||||||
|
<?php
|
||||||
|
if ( have_posts() ) {
|
||||||
|
while ( have_posts() ) {
|
||||||
|
the_post();
|
||||||
|
the_content();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php if ( hasSidebar() ) : ?>
|
||||||
|
<?php get_sidebar( 'page' ); ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<?php get_footer(); ?>
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
// @ts-check
|
||||||
|
import { defineConfig, devices } from '@playwright/test';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read environment variables from file.
|
||||||
|
* https://github.com/motdotla/dotenv
|
||||||
|
*/
|
||||||
|
// import dotenv from 'dotenv';
|
||||||
|
// import path from 'path';
|
||||||
|
// dotenv.config({ path: path.resolve(__dirname, '.env') });
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see https://playwright.dev/docs/test-configuration
|
||||||
|
*/
|
||||||
|
export default defineConfig({
|
||||||
|
testDir: './tests',
|
||||||
|
/* Run tests in files in parallel */
|
||||||
|
fullyParallel: true,
|
||||||
|
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
||||||
|
forbidOnly: !!process.env.CI,
|
||||||
|
/* Retry on CI only */
|
||||||
|
retries: process.env.CI ? 2 : 0,
|
||||||
|
/* Opt out of parallel tests on CI. */
|
||||||
|
workers: process.env.CI ? 1 : undefined,
|
||||||
|
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||||
|
reporter: 'html',
|
||||||
|
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||||
|
use: {
|
||||||
|
/* Base URL to use in actions like `await page.goto('/')`. */
|
||||||
|
// baseURL: 'http://127.0.0.1:3000',
|
||||||
|
|
||||||
|
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||||
|
trace: 'on-first-retry',
|
||||||
|
ignoreHTTPSErrors: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Configure projects for major browsers */
|
||||||
|
projects: [
|
||||||
|
{
|
||||||
|
name: 'chromium',
|
||||||
|
use: { ...devices['Desktop Chrome'] },
|
||||||
|
},
|
||||||
|
|
||||||
|
// {
|
||||||
|
// name: 'firefox',
|
||||||
|
// use: { ...devices['Desktop Firefox'] },
|
||||||
|
// },
|
||||||
|
|
||||||
|
// {
|
||||||
|
// name: 'webkit',
|
||||||
|
// use: { ...devices['Desktop Safari'] },
|
||||||
|
// },
|
||||||
|
|
||||||
|
/* Test against mobile viewports. */
|
||||||
|
// {
|
||||||
|
// name: 'Mobile Chrome',
|
||||||
|
// use: { ...devices['Pixel 5'] },
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// name: 'Mobile Safari',
|
||||||
|
// use: { ...devices['iPhone 12'] },
|
||||||
|
// },
|
||||||
|
|
||||||
|
/* Test against branded browsers. */
|
||||||
|
// {
|
||||||
|
// name: 'Microsoft Edge',
|
||||||
|
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// name: 'Google Chrome',
|
||||||
|
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
|
||||||
|
// },
|
||||||
|
],
|
||||||
|
|
||||||
|
/* Run your local dev server before starting the tests */
|
||||||
|
// webServer: {
|
||||||
|
// command: 'npm run start',
|
||||||
|
// url: 'http://127.0.0.1:3000',
|
||||||
|
// reuseExistingServer: !process.env.CI,
|
||||||
|
// },
|
||||||
|
});
|
||||||
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 67 KiB |
+103
@@ -0,0 +1,103 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Blog search template
|
||||||
|
*
|
||||||
|
* @package BasicWP
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace BasicWP;
|
||||||
|
|
||||||
|
// Determine classes based on sidebar presence
|
||||||
|
if ( hasSidebar() ) {
|
||||||
|
$classes = 'container grid grid-cols-1 lg:grid-cols-4 gap-8 xl:gap-16 my-section mx-auto';
|
||||||
|
$clsEntry = 'lg:col-span-3';
|
||||||
|
} else {
|
||||||
|
$classes = 'container my-section lg:my-0 mx-auto';
|
||||||
|
}
|
||||||
|
|
||||||
|
get_header();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<section class="<?php echo esc_attr( $classes ); ?>">
|
||||||
|
<?php if ( have_posts() ) : ?>
|
||||||
|
<div class="blog-posts <?php echo esc_attr( $clsEntry ); ?>">
|
||||||
|
<div class="post-list">
|
||||||
|
<div class="post-list__posts grid grid-cols-[repeat(auto-fit,minmax(20rem,1fr))] gap-6">
|
||||||
|
<?php
|
||||||
|
while ( have_posts() ) :
|
||||||
|
the_post();
|
||||||
|
?>
|
||||||
|
<div class="post-list__post flex flex-col border border-secondary rounded-md shadow-lg hover:prose-img:scale-110 hover:prose-img:origin-center hover:prose-img:duration-500">
|
||||||
|
<figure class="post-list__img aspect-video border-b border-secondary rounded-t-md block h-auto w-full overflow-hidden m-0 p-0">
|
||||||
|
<?php
|
||||||
|
$featImg = get_the_post_thumbnail_url();
|
||||||
|
$postImg = $featimg ? $featImg : 'https://picsum.photos/600/400?random=' . get_the_ID();
|
||||||
|
$imgAlt = get_post_meta( get_post_thumbnail_id(), '_wp_attachment_image_alt', true ) ?? get_the_title();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<img class="block h-full object-cover transition-transform duration-300 ease-linear w-full will-change-transform" src="<?php echo esc_url( $postImg ); ?>" alt="<?php echo esc_attr( $imgAlt ); ?>">
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
<div class="post-list__details px-4 py-8 flex flex-col flex-grow">
|
||||||
|
<?php
|
||||||
|
$categories = get_the_category();
|
||||||
|
if ( ! empty( $categories ) ) {
|
||||||
|
?>
|
||||||
|
<div class="post-list__cats">
|
||||||
|
Posted in:
|
||||||
|
<?php
|
||||||
|
foreach ( $categories as $index => $category ) :
|
||||||
|
$separator = $index < count( $categories ) - 1 ? ', ' : '';
|
||||||
|
?>
|
||||||
|
<a href="<?php echo esc_url( get_category_link( $category->term_id ) ); ?>" class="post-list__category text-14px font-semibold leading-none uppercase mt-0 mb-2.5 mx-0 inline-block"><?php echo esc_html( $category->name ); ?></a><?php echo esc_attr( $separator ); ?>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
<?php } else { ?>
|
||||||
|
<div class="post-list__cats">
|
||||||
|
<?php $postType = get_post_type(); ?>
|
||||||
|
Post Type: <span class="post-list__category text-14px font-semibold leading-none uppercase mt-0 mb-2.5 mx-0 inline-block"><?php echo esc_html( $postType ); ?></span>
|
||||||
|
</div>
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
|
<a href="<?php the_permalink(); ?>" class="">
|
||||||
|
<h2 class="post-list__title font-normal text-25px text-balance line-clamp-4 truncate mt-0 mb-5 mx-0"><?php the_title(); ?></h2>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="post-list__byline mt-auto">
|
||||||
|
<span class="post-list__author"><?php echo esc_html( ucfirst( get_the_author() ) ); ?> —</span>
|
||||||
|
<span class="post-list__date"><?php echo get_the_date(); ?></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php endwhile; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="post-list__pagination">
|
||||||
|
<?php
|
||||||
|
the_posts_pagination(
|
||||||
|
array(
|
||||||
|
'mid_size' => 2,
|
||||||
|
'prev_text' => '« Previous',
|
||||||
|
'next_text' => 'Next »',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php else : ?>
|
||||||
|
<div class="blog-posts <?php echo esc_attr( $clsEntry ); ?>">
|
||||||
|
<div class="no-posts">
|
||||||
|
<h2 class="no-posts__title">Nothing here yet…</h2>
|
||||||
|
<p class="no-posts__desc">No published posts found.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if ( hasSidebar() ) : ?>
|
||||||
|
<?php get_sidebar(); ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<?php get_footer(); ?>
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Page Sidebar
|
||||||
|
*
|
||||||
|
* @package BasicWP
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace BasicWP;
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<aside class="sidebar sidebar-page">
|
||||||
|
<h2><?php esc_html_e( 'Page Sidebar', 'basicwp' ); ?></h2>
|
||||||
|
<?php dynamic_sidebar( 'sidebar-page' ); ?>
|
||||||
|
</aside>
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Sidebar
|
||||||
|
*
|
||||||
|
* @package BasicWP
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace BasicWP;
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<aside class="sidebar">
|
||||||
|
<?php dynamic_sidebar( 'sidebar-primary' ); ?>
|
||||||
|
</aside>
|
||||||
+86
@@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Single Posts
|
||||||
|
*
|
||||||
|
* @package BasicWP
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace BasicWP;
|
||||||
|
|
||||||
|
get_header();
|
||||||
|
|
||||||
|
// Determine classes based on sidebar presence
|
||||||
|
if ( hasSidebar() ) {
|
||||||
|
$classes = 'container grid grid-cols-1 lg:grid-cols-4 gap-8 xl:gap-16 my-section mx-auto';
|
||||||
|
$clsEntry = 'lg:col-span-3';
|
||||||
|
} else {
|
||||||
|
$classes = 'container my-section lg:my-0 mx-auto';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<article class="<?php echo esc_attr( $classes ); ?>">
|
||||||
|
<div class="entry-content <?php echo esc_attr( $clsEntry ); ?>">
|
||||||
|
<?php
|
||||||
|
if ( have_posts() ) {
|
||||||
|
while ( have_posts() ) {
|
||||||
|
the_post();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="post-title mb-0">
|
||||||
|
<h1 class="mb-0"><?php the_title(); ?></h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="post-meta text-14px italic mb-6">
|
||||||
|
<div class="">
|
||||||
|
<span class="post-date">Posted: <?php the_date(); ?></span> | <span class="post-author">Posted by: <?php echo esc_html( ucfirst( get_the_author() ) ); ?></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="">
|
||||||
|
<span class="post-categories">
|
||||||
|
<?php
|
||||||
|
$categories = get_the_category();
|
||||||
|
if ( ! empty( $categories ) ) {
|
||||||
|
echo '<span>Posted in: ';
|
||||||
|
foreach ( $categories as $ct ) {
|
||||||
|
echo '<a href="' . esc_url( get_category_link( $ct->cat_ID ) ) . '">' . esc_html( $ct->name ) . '</a>';
|
||||||
|
if ( count( $categories ) > 1 && $ct !== end( $categories ) ) {
|
||||||
|
echo ', ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo '</span>';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</span>
|
||||||
|
|
|
||||||
|
<span class="post-tags">
|
||||||
|
<?php
|
||||||
|
$tags = get_the_tags();
|
||||||
|
if ( ! empty( $tags ) ) {
|
||||||
|
echo '<span>Tagged: ';
|
||||||
|
foreach ( $tags as $tg ) {
|
||||||
|
echo '<a href="' . esc_url( get_tag_link( $tg->term_id ) ) . '">' . esc_html( $tg->name ) . '</a>';
|
||||||
|
if ( count( $tags ) > 1 && $tg !== end( $tags ) ) {
|
||||||
|
echo ', ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo '</span>';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
the_content();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php if ( hasSidebar() ) : ?>
|
||||||
|
<?php get_sidebar(); ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<?php get_footer(); ?>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<svg width="83px" height="83px" viewBox="0 0 83 83" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Copyright (c) 2025 Kevinleary.net, LLC. All rights reserved. -->
|
||||||
|
<title>kevinleary.net</title>
|
||||||
|
<circle fill="#FFFFFF" cx="41.5" cy="41.5" r="41.5"></circle>
|
||||||
|
<path d="M41.4990862,5 C21.3735072,5 5,21.3753349 5,41.5009138 C5,61.6264928 21.3735072,78 41.5009138,78 C61.6264928,78 78,61.6264928 78,41.5009138 C78,21.3753349 61.6264928,5 41.4990862,5 Z M50.341036,59.1902962 L34.0314949,42.9703077 L33.9218386,43.0799639 L33.9218386,59.1902962 L30.0893523,59.1902962 L30.0893523,22.8904188 L33.9218386,22.8904188 L33.9218386,37.9517062 L49.2389906,22.8904188 L54.5006634,22.8904188 L36.7016248,40.400696 L55.5387427,59.1902962 L50.341036,59.1902962 Z" fill="#000000" fill-rule="nonzero"></path>
|
||||||
|
<path d="M41.5,0 C18.5798958,0 0,18.5798958 0,41.5 C0,64.418375 18.5798958,83 41.5,83 C64.418375,83 83,64.4201042 83,41.5 C83,18.5798958 64.4201042,0 41.5,0 Z M41.5,80.2934783 C20.1078009,80.2934783 2.70652174,62.8907964 2.70652174,41.5009041 C2.70652174,20.1092036 20.1096092,2.70652174 41.5,2.70652174 C62.8903908,2.70652174 80.2934783,20.1092036 80.2934783,41.5009041 C80.2934783,62.8907964 62.8903908,80.2934783 41.5,80.2934783 Z" fill="#000000" fill-rule="nonzero"></path>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 976 B |
@@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* Admin JS
|
||||||
|
*/
|
||||||
|
import { registerButtonComponent } from './components/button.js';
|
||||||
|
|
||||||
|
const app = () => {
|
||||||
|
registerButtonComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', app);
|
||||||
|
|
||||||
|
console.log(`admin.js loaded.`);
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
// Back to Top Button Component
|
||||||
|
class BackToTopButton extends HTMLElement {
|
||||||
|
connectedCallback() {
|
||||||
|
this.innerHTML = `
|
||||||
|
<button id="backToTopBtn" aria-label="Back to top" class="back-to-top" style="">
|
||||||
|
↑ Top
|
||||||
|
</button>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const btn = this.querySelector('#backToTopBtn');
|
||||||
|
|
||||||
|
let previousScrollY = window.scrollY;
|
||||||
|
|
||||||
|
window.addEventListener('scroll', () => {
|
||||||
|
const currentScrollY = window.scrollY;
|
||||||
|
const isScrollingUp = currentScrollY < previousScrollY;
|
||||||
|
const shouldShowButton = currentScrollY > 300 && isScrollingUp;
|
||||||
|
|
||||||
|
btn.style.display = shouldShowButton ? 'block' : 'none';
|
||||||
|
previousScrollY = currentScrollY;
|
||||||
|
});
|
||||||
|
|
||||||
|
btn.addEventListener('click', () => {
|
||||||
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function registerBackToTopButton() {
|
||||||
|
if (!customElements.get('back-to-top')) {
|
||||||
|
customElements.define('back-to-top', BackToTopButton);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
class ButtonComponent extends HTMLElement {
|
||||||
|
/**
|
||||||
|
* Parameters
|
||||||
|
* - btnClasses: Additional classes to add to the block.
|
||||||
|
* - element: The element to use for the button. Defaults to 'a'.
|
||||||
|
* - url: The URL to link to.
|
||||||
|
* - target: The target for the link.
|
||||||
|
* - title: The text to display on the button.
|
||||||
|
* - ariaLabel: The ARIA label for the button.
|
||||||
|
* - color: The color of the button.
|
||||||
|
* - variant: The variant of the button.
|
||||||
|
* - size: The size of the button.
|
||||||
|
* - width: The width of the button.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
if (!this.querySelector(this.getAttribute('element'))) {
|
||||||
|
this.append(document.createElement(this.getAttribute('element')));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
static get observedAttributes() {
|
||||||
|
return [
|
||||||
|
'btnClasses',
|
||||||
|
'el',
|
||||||
|
'element',
|
||||||
|
'type',
|
||||||
|
'url',
|
||||||
|
'target',
|
||||||
|
'title',
|
||||||
|
'ariaLabel',
|
||||||
|
'color',
|
||||||
|
'variant',
|
||||||
|
'size',
|
||||||
|
'width',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
attributeChangedCallback() {
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
update() {
|
||||||
|
const btn = this.querySelector(this.getAttribute('element'));
|
||||||
|
|
||||||
|
// console.log('[ButtonComponent] attributes', {
|
||||||
|
// btnClasses: this.getAttribute('btnClasses'),
|
||||||
|
// element: this.getAttribute('element'),
|
||||||
|
// type: this.getAttribute('type'),
|
||||||
|
// url: this.getAttribute('url'),
|
||||||
|
// target: this.getAttribute('target'),
|
||||||
|
// title: this.getAttribute('title'),
|
||||||
|
// ariaLabel: this.getAttribute('ariaLabel'),
|
||||||
|
// color: this.getAttribute('color'),
|
||||||
|
// variant: this.getAttribute('variant'),
|
||||||
|
// size: this.getAttribute('size'),
|
||||||
|
// width: this.getAttribute('width'),
|
||||||
|
// });
|
||||||
|
|
||||||
|
if (btn) {
|
||||||
|
btn.classList = this.getAttribute('btnClasses') || '';
|
||||||
|
|
||||||
|
if (this.getAttribute('element') == 'a') {
|
||||||
|
btn.href = this.getAttribute('url') || '#';
|
||||||
|
|
||||||
|
if (btn.target) {
|
||||||
|
btn.target = 'target="${this.getAttribute(target)}"';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const type = this.getAttribute('type');
|
||||||
|
if (type && this.getAttribute('element') !== 'a') {
|
||||||
|
btn.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
btn.title = this.getAttribute('title') || '';
|
||||||
|
btn.textContent = this.getAttribute('title') || '';
|
||||||
|
|
||||||
|
if (!this.getAttribute('ariaLabel') && this.getAttribute('url')) {
|
||||||
|
btn.setAttribute('aria-label', `Link to ${this.getAttribute('url')}`);
|
||||||
|
} else {
|
||||||
|
btn.setAttribute('aria-label', this.getAttribute('ariaLabel'));
|
||||||
|
}
|
||||||
|
|
||||||
|
btn.setAttribute('aria-label', this.getAttribute('ariaLabel'));
|
||||||
|
btn.setAttribute('data-button-color', this.getAttribute('color'));
|
||||||
|
btn.setAttribute('data-button-variant', this.getAttribute('variant'));
|
||||||
|
btn.setAttribute('data-button-size', this.getAttribute('size'));
|
||||||
|
btn.setAttribute('data-button-width', this.getAttribute('width'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const registerButtonComponent = () => {
|
||||||
|
customElements.define('x-button', ButtonComponent);
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* Get Header Height
|
||||||
|
* -
|
||||||
|
* Get header height and set CSS variable "--hgtHeader" to the header height.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getHeaderHeight() {
|
||||||
|
const headerHeight = document.querySelector('.header__nav-main').getBoundingClientRect().height;
|
||||||
|
document.documentElement.style.setProperty('--hgtHeader', `${headerHeight}px`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default getHeaderHeight;
|
||||||
@@ -0,0 +1,576 @@
|
|||||||
|
/**
|
||||||
|
* VDI Main Nav - All Main Navigation Functionality
|
||||||
|
*
|
||||||
|
* Please review documentation upon first use, and, as-needed:
|
||||||
|
* https://docs.vincentdevelopment.ca/docs/starter-v3-enhancements/navigation/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigation
|
||||||
|
* Handles navigation logic
|
||||||
|
*
|
||||||
|
* @param {string} mobileMenuButtonId
|
||||||
|
* @param {string} dropDownClass
|
||||||
|
* @param {string} subMenuLinkClass
|
||||||
|
*/
|
||||||
|
class Navigation {
|
||||||
|
/**
|
||||||
|
* The main toggle element
|
||||||
|
*
|
||||||
|
* @type {HTMLElement}
|
||||||
|
* @link {https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_properties}
|
||||||
|
*/
|
||||||
|
#mobileMenuButton;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of sub dropdown buttons
|
||||||
|
*
|
||||||
|
* @type {NodeList}
|
||||||
|
* @link {https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_properties}
|
||||||
|
*/
|
||||||
|
#dropdownButtons;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class name to identify sub menu items (ul>li>a)
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
#subMenuElementIdentifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current navigation level in sliding viewport
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
#currentLevel = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigation stack for breadcrumb functionality
|
||||||
|
* @type {Array}
|
||||||
|
*/
|
||||||
|
#navigationStack = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether sliding viewport mode is enabled
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
#slidingViewportEnabled = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
constructor(mobileMenuButtonId, dropDownClass, subMenuLinkClass = "sub-menu-item") {
|
||||||
|
this.#mobileMenuButton = document.getElementById(mobileMenuButtonId);
|
||||||
|
this.#dropdownButtons = document.querySelectorAll(dropDownClass); // Do not change this to getElementsByClassName, logic is iterating over non-live node list
|
||||||
|
this.#subMenuElementIdentifier = subMenuLinkClass;
|
||||||
|
|
||||||
|
this.handleEscapeKey();
|
||||||
|
|
||||||
|
// Initialize sliding viewport immediately if styles are detected
|
||||||
|
this.initializeSlidingViewport();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles main mobile toggling
|
||||||
|
* Adds an event listener to mobile menu dropdown
|
||||||
|
* toggle button
|
||||||
|
*/
|
||||||
|
mobileMenuToggle() {
|
||||||
|
this.#mobileMenuButton.addEventListener("click", (event) => {
|
||||||
|
this.toggleMobileMenu(event, this.#mobileMenuButton); // toggle submenu on mobile
|
||||||
|
});
|
||||||
|
|
||||||
|
this.closeOnBlur(this.#mobileMenuButton, { "navType": "desktop" }); // close submenu when user clicks outside
|
||||||
|
this.closeOnBlur(this.#mobileMenuButton, { "navType": "mobile" });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles dropdowns on desktop navigation
|
||||||
|
* Loops over list of navigation dropdown buttons
|
||||||
|
* and adds eventlisteners to toggle view
|
||||||
|
*/
|
||||||
|
desktopMenuDropdowns() {
|
||||||
|
this.#dropdownButtons.forEach((button) => {
|
||||||
|
button.addEventListener("click", (event) => {
|
||||||
|
this.toggleDropdown(event, button);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.closeOnBlur(button); // close menu when user clicks outside
|
||||||
|
this.handleFocus(button); // close dropdown when user finishes tabbing submenu elements
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles desktop dropdowns
|
||||||
|
*
|
||||||
|
* @param {EventTarget} event
|
||||||
|
* @param {HTMLButtonElement} button
|
||||||
|
*/
|
||||||
|
toggleDropdown(event, button) {
|
||||||
|
this.toggleAriaExpanded(event, button);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles mobile menu
|
||||||
|
*
|
||||||
|
* @param {EventTarget} event
|
||||||
|
* @param {HTMLButtonElement} button
|
||||||
|
*/
|
||||||
|
toggleMobileMenu(event, button) {
|
||||||
|
this.toggleAriaExpanded(event, button);
|
||||||
|
|
||||||
|
const isExpanded = button.getAttribute("aria-expanded") === "true";
|
||||||
|
|
||||||
|
if (!isExpanded) {
|
||||||
|
// Reset sliding navigation when menu is closed
|
||||||
|
if (this.#slidingViewportEnabled) {
|
||||||
|
this.resetSlidingNavigation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles aria-expanded attribute
|
||||||
|
*
|
||||||
|
* @param {EventTarget} event
|
||||||
|
* @param {HTMLButtonElement} button
|
||||||
|
*/
|
||||||
|
toggleAriaExpanded(event, button) {
|
||||||
|
let isExpanded = event.currentTarget.getAttribute("aria-expanded") === "true"; // true is returned as string
|
||||||
|
|
||||||
|
// ... but open the targeted secondary nav
|
||||||
|
if (!isExpanded) {
|
||||||
|
// close all dropdowns...
|
||||||
|
this.closeAllDropDowns();
|
||||||
|
// then toggle targeted dropdown...
|
||||||
|
button.setAttribute("aria-expanded", true);
|
||||||
|
} else {
|
||||||
|
button.setAttribute("aria-expanded", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close dropdown when user clicks anywhere else on the screen
|
||||||
|
*
|
||||||
|
* @param {HTMLButtonElement} button
|
||||||
|
* @link {https://developer.mozilla.org/en-US/docs/Web/API/Element/blur_event}
|
||||||
|
* @link {https://developer.mozilla.org/en-US/docs/Web/API/FocusEvent/relatedTarget}
|
||||||
|
*/
|
||||||
|
closeOnBlur(button, args) {
|
||||||
|
if (args === undefined || args?.navType === "desktop") {
|
||||||
|
button.addEventListener("blur", (event) => {
|
||||||
|
if (event.relatedTarget == null) {
|
||||||
|
event.currentTarget.setAttribute("aria-expanded", false);
|
||||||
|
}
|
||||||
|
}, { passive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
//FIXME: Remove hardcoded literal
|
||||||
|
if (args?.navType === "mobile") {
|
||||||
|
document.getElementById("menu-container").addEventListener("blur", (event) => {
|
||||||
|
// Note: cannot group negation -1*-1*-1 != -(1*1*1)
|
||||||
|
const isNull = event.relatedTarget == null;
|
||||||
|
const isNotMenuItem = !isNull && !event.relatedTarget.classList.contains("menu-vdi__toggle")
|
||||||
|
&& !event.relatedTarget.classList.contains("sub-menu-item")
|
||||||
|
&& !event.relatedTarget.classList.contains("menu-vdi__link")
|
||||||
|
&& !event.relatedTarget.classList.contains("menu-vdi__back"); // Don't close on back button click
|
||||||
|
|
||||||
|
if (isNull || isNotMenuItem)
|
||||||
|
button.setAttribute("aria-expanded", false);
|
||||||
|
}, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles escape behaviour
|
||||||
|
* Closes all dropdown when user hits
|
||||||
|
* escape key
|
||||||
|
*
|
||||||
|
* @link {https://developer.mozilla.org/en-US/docs/Web/API/Element/keyup_event}
|
||||||
|
*/
|
||||||
|
handleEscapeKey() {
|
||||||
|
window.addEventListener("keyup", (event) => {
|
||||||
|
if (event.key === "Escape") {
|
||||||
|
this.#mobileMenuButton.setAttribute("aria-expanded", false);
|
||||||
|
this.closeAllDropDowns();
|
||||||
|
|
||||||
|
// Reset sliding navigation on escape
|
||||||
|
if (this.#slidingViewportEnabled) {
|
||||||
|
this.resetSlidingNavigation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, { passive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close all dropdown menus
|
||||||
|
* Sets aria expanded property by looping
|
||||||
|
* over the list of dropdown button elements
|
||||||
|
*
|
||||||
|
* @link {https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-expanded}
|
||||||
|
*/
|
||||||
|
closeAllDropDowns() {
|
||||||
|
this.#dropdownButtons.forEach((button) => {
|
||||||
|
button.setAttribute("aria-expanded", false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle focus
|
||||||
|
* Watches blur event on submenu list container, if the next
|
||||||
|
* focus element is not a submenu list item, closes the
|
||||||
|
* dropdown.
|
||||||
|
*
|
||||||
|
* Implemented for WCAG 2.2 compliance
|
||||||
|
*
|
||||||
|
* @param {htmlButtonElement} button
|
||||||
|
*/
|
||||||
|
handleFocus(button) {
|
||||||
|
const subMenuListElement = button.closest("ul");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ducking JavaScript, I am not sure why the blur event on submenu(ul)
|
||||||
|
* would bubble up to the button since the button and sub menu list element
|
||||||
|
* are siblings and not nested. This is a mystery to me.
|
||||||
|
*
|
||||||
|
* Here we are stopping any bubbling event that may be propagated to the
|
||||||
|
* top level buttons. This includes the bubbling event from sub menu list element.
|
||||||
|
*
|
||||||
|
* If anyone finds a better solution to this or can explain bubbling of focus event
|
||||||
|
* to next sibling, you time and effort would be much appreciated.
|
||||||
|
*/
|
||||||
|
button.addEventListener("focusout", (event) => {
|
||||||
|
event.stopImmediatePropagation();
|
||||||
|
})
|
||||||
|
|
||||||
|
subMenuListElement.addEventListener("focusout", (event) => {
|
||||||
|
// blur event triggers when user clicks outside
|
||||||
|
const nextFocusElement = event.relatedTarget;
|
||||||
|
|
||||||
|
let isSubMenuElement;
|
||||||
|
|
||||||
|
if (nextFocusElement !== null) {
|
||||||
|
isSubMenuElement = nextFocusElement.classList.contains(this.#subMenuElementIdentifier);
|
||||||
|
} else {
|
||||||
|
isSubMenuElement = false; // close when user clicks outside
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isSubMenuElement) {
|
||||||
|
this.closeAllDropDowns();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize sliding viewport navigation
|
||||||
|
* Detects if sliding viewport should be enabled and sets up the structure
|
||||||
|
*/
|
||||||
|
initializeSlidingViewport() {
|
||||||
|
// Check if we should enable sliding viewport (could be based on screen size, user preference, etc.)
|
||||||
|
this.#slidingViewportEnabled = this.shouldEnableSlidingViewport();
|
||||||
|
|
||||||
|
if (this.#slidingViewportEnabled) {
|
||||||
|
console.log('Sliding viewport enabled, setting up structure');
|
||||||
|
this.setupSlidingViewportStructure();
|
||||||
|
} else {
|
||||||
|
console.log('Sliding viewport not enabled');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if sliding viewport should be enabled
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
shouldEnableSlidingViewport() {
|
||||||
|
// Check if sliding viewport styles are loaded by testing if the CSS rule exists
|
||||||
|
// This allows CSS-based switching between navigation styles
|
||||||
|
const isMobile = window.innerWidth <= 1000; // 62.5rem converted to px
|
||||||
|
|
||||||
|
if (!isMobile) return false;
|
||||||
|
|
||||||
|
// Check if sliding viewport CSS is loaded by testing a specific rule
|
||||||
|
// We need to test the element within the proper context (.nav-main)
|
||||||
|
try {
|
||||||
|
const navMain = document.querySelector('.nav-main');
|
||||||
|
if (!navMain) return false;
|
||||||
|
|
||||||
|
const testElement = document.createElement('div');
|
||||||
|
testElement.className = 'menu-vdi--sliding';
|
||||||
|
testElement.style.position = 'absolute';
|
||||||
|
testElement.style.visibility = 'hidden';
|
||||||
|
testElement.style.height = '1px';
|
||||||
|
testElement.style.width = '1px';
|
||||||
|
|
||||||
|
navMain.appendChild(testElement);
|
||||||
|
|
||||||
|
// Get computed styles to check if sliding viewport CSS is active
|
||||||
|
const computedStyle = window.getComputedStyle(testElement);
|
||||||
|
const hasOverflowHidden = computedStyle.overflow === 'hidden';
|
||||||
|
|
||||||
|
navMain.removeChild(testElement);
|
||||||
|
|
||||||
|
return hasOverflowHidden;
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('Error detecting sliding viewport styles:', error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup the HTML structure for sliding viewport navigation
|
||||||
|
*/
|
||||||
|
setupSlidingViewportStructure() {
|
||||||
|
const menuContainer = document.getElementById('menu-container');
|
||||||
|
if (!menuContainer) {
|
||||||
|
console.warn('Menu container not found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't set up if already configured
|
||||||
|
if (menuContainer.classList.contains('menu-vdi--sliding')) {
|
||||||
|
console.log('Sliding viewport already configured');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Setting up sliding viewport structure');
|
||||||
|
|
||||||
|
// Add sliding class to enable sliding styles
|
||||||
|
menuContainer.classList.add('menu-vdi--sliding');
|
||||||
|
|
||||||
|
// Create viewport container
|
||||||
|
const viewport = document.createElement('div');
|
||||||
|
viewport.className = 'menu-vdi__viewport';
|
||||||
|
viewport.setAttribute('data-current-level', '0');
|
||||||
|
|
||||||
|
// Create main level
|
||||||
|
const mainLevel = document.createElement('div');
|
||||||
|
mainLevel.className = 'menu-vdi__level menu-vdi__level--main';
|
||||||
|
mainLevel.setAttribute('data-level', '0');
|
||||||
|
|
||||||
|
// Move existing menu items to main level
|
||||||
|
const existingItems = Array.from(menuContainer.children);
|
||||||
|
console.log('Moving', existingItems.length, 'existing items to main level');
|
||||||
|
|
||||||
|
existingItems.forEach(item => {
|
||||||
|
mainLevel.appendChild(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Setup click handlers for parent items in sliding mode
|
||||||
|
this.setupSlidingClickHandlers(mainLevel);
|
||||||
|
|
||||||
|
viewport.appendChild(mainLevel);
|
||||||
|
menuContainer.appendChild(viewport);
|
||||||
|
|
||||||
|
console.log('Sliding viewport structure complete');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup click handlers for parent menu items in sliding mode
|
||||||
|
* @param {HTMLElement} level
|
||||||
|
*/
|
||||||
|
setupSlidingClickHandlers(level) {
|
||||||
|
const parentButtons = level.querySelectorAll('.menu-vdi__toggle');
|
||||||
|
|
||||||
|
parentButtons.forEach(button => {
|
||||||
|
button.addEventListener('click', (event) => {
|
||||||
|
if (this.#slidingViewportEnabled) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
const parentItem = button.closest('.menu-vdi__item--parent');
|
||||||
|
const submenu = parentItem.querySelector('.menu-vdi__submenu');
|
||||||
|
|
||||||
|
if (submenu) {
|
||||||
|
this.navigateToLevel(button.textContent.trim(), submenu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, true); // Use capture phase to intercept before other handlers
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigate to a specific navigation level
|
||||||
|
* @param {string} levelTitle
|
||||||
|
* @param {HTMLElement} submenuElement
|
||||||
|
*/
|
||||||
|
navigateToLevel(levelTitle, submenuElement) {
|
||||||
|
const viewport = document.querySelector('.menu-vdi__viewport');
|
||||||
|
if (!viewport) return;
|
||||||
|
|
||||||
|
this.#currentLevel++;
|
||||||
|
this.#navigationStack.push({ title: levelTitle, level: this.#currentLevel });
|
||||||
|
|
||||||
|
// Create new level
|
||||||
|
const newLevel = document.createElement('div');
|
||||||
|
newLevel.className = 'menu-vdi__level';
|
||||||
|
newLevel.setAttribute('data-level', this.#currentLevel);
|
||||||
|
|
||||||
|
// Add back button
|
||||||
|
const backButton = this.createBackButton();
|
||||||
|
newLevel.appendChild(backButton);
|
||||||
|
|
||||||
|
// Add level title
|
||||||
|
const levelTitleEl = document.createElement('div');
|
||||||
|
levelTitleEl.className = 'menu-vdi__level-title';
|
||||||
|
levelTitleEl.textContent = levelTitle;
|
||||||
|
newLevel.appendChild(levelTitleEl);
|
||||||
|
|
||||||
|
// Clone and add submenu items
|
||||||
|
const submenuItems = submenuElement.cloneNode(true);
|
||||||
|
submenuItems.className = 'menu-vdi__level-items';
|
||||||
|
|
||||||
|
// Convert submenu items to level items and ensure proper visibility
|
||||||
|
const items = submenuItems.querySelectorAll('.menu-vdi__item');
|
||||||
|
items.forEach(item => {
|
||||||
|
// Remove any nested classes that don't apply to sliding mode
|
||||||
|
item.classList.remove('menu-vdi__item--child', 'menu-vdi__item--grandchild');
|
||||||
|
|
||||||
|
// Handle nested items if they exist
|
||||||
|
const nestedToggle = item.querySelector('.menu-vdi__toggle');
|
||||||
|
if (nestedToggle) {
|
||||||
|
nestedToggle.addEventListener('click', (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
// Could implement deeper nesting here if needed
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Remove any hidden submenu classes from nested elements to ensure visibility
|
||||||
|
const nestedSubmenus = submenuItems.querySelectorAll('.menu-vdi__submenu');
|
||||||
|
nestedSubmenus.forEach(nestedSubmenu => {
|
||||||
|
nestedSubmenu.classList.remove('menu-vdi__submenu');
|
||||||
|
nestedSubmenu.classList.add('menu-vdi__nested-items');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Ensure all list items are visible in sliding mode
|
||||||
|
const allListItems = submenuItems.querySelectorAll('li');
|
||||||
|
allListItems.forEach(li => {
|
||||||
|
if (!li.classList.contains('menu-vdi__item')) {
|
||||||
|
li.classList.add('menu-vdi__item');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
newLevel.appendChild(submenuItems);
|
||||||
|
viewport.appendChild(newLevel);
|
||||||
|
|
||||||
|
// Animate to new level
|
||||||
|
this.animateToLevel(this.#currentLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a back button for navigation levels
|
||||||
|
* @returns {HTMLElement}
|
||||||
|
*/
|
||||||
|
createBackButton() {
|
||||||
|
const backButton = document.createElement('button');
|
||||||
|
backButton.className = 'menu-vdi__back';
|
||||||
|
backButton.innerHTML = `
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5L8.25 12l7.5-7.5" />
|
||||||
|
</svg>
|
||||||
|
Back
|
||||||
|
`;
|
||||||
|
|
||||||
|
backButton.addEventListener('click', (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
this.navigateBack();
|
||||||
|
});
|
||||||
|
|
||||||
|
return backButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigate back to previous level
|
||||||
|
*/
|
||||||
|
navigateBack() {
|
||||||
|
if (this.#currentLevel > 0) {
|
||||||
|
this.#currentLevel--;
|
||||||
|
this.#navigationStack.pop();
|
||||||
|
|
||||||
|
// Remove the current level element
|
||||||
|
const viewport = document.querySelector('.menu-vdi__viewport');
|
||||||
|
const currentLevelEl = viewport.querySelector(`[data-level="${this.#currentLevel + 1}"]`);
|
||||||
|
if (currentLevelEl) {
|
||||||
|
currentLevelEl.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Animate back to previous level
|
||||||
|
this.animateToLevel(this.#currentLevel);
|
||||||
|
|
||||||
|
// Ensure menu stays open after back navigation
|
||||||
|
setTimeout(() => {
|
||||||
|
if (this.#mobileMenuButton.getAttribute("aria-expanded") === "false") {
|
||||||
|
this.#mobileMenuButton.setAttribute("aria-expanded", "true");
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Animate viewport to specific level
|
||||||
|
* @param {number} level
|
||||||
|
*/
|
||||||
|
animateToLevel(level) {
|
||||||
|
const viewport = document.querySelector('.menu-vdi__viewport');
|
||||||
|
if (!viewport) return;
|
||||||
|
|
||||||
|
const translateX = -level * 100;
|
||||||
|
viewport.style.transform = `translateX(${translateX}%)`;
|
||||||
|
viewport.setAttribute('data-current-level', level);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset sliding navigation to main level
|
||||||
|
*/
|
||||||
|
resetSlidingNavigation() {
|
||||||
|
const menuContainer = document.getElementById('menu-container');
|
||||||
|
if (!menuContainer) return;
|
||||||
|
|
||||||
|
if (this.#slidingViewportEnabled) {
|
||||||
|
this.#currentLevel = 0;
|
||||||
|
this.#navigationStack = [];
|
||||||
|
|
||||||
|
const viewport = document.querySelector('.menu-vdi__viewport');
|
||||||
|
if (viewport) {
|
||||||
|
// Remove all levels except main
|
||||||
|
const levels = viewport.querySelectorAll('.menu-vdi__level:not(.menu-vdi__level--main)');
|
||||||
|
levels.forEach(level => level.remove());
|
||||||
|
|
||||||
|
// Reset position
|
||||||
|
this.animateToLevel(0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Clean up sliding structure and restore normal menu
|
||||||
|
this.cleanupSlidingStructure();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean up sliding viewport structure and restore normal menu
|
||||||
|
*/
|
||||||
|
cleanupSlidingStructure() {
|
||||||
|
const menuContainer = document.getElementById('menu-container');
|
||||||
|
if (!menuContainer) return;
|
||||||
|
|
||||||
|
// Remove sliding class
|
||||||
|
menuContainer.classList.remove('menu-vdi--sliding');
|
||||||
|
|
||||||
|
// Find viewport and move items back to container
|
||||||
|
const viewport = menuContainer.querySelector('.menu-vdi__viewport');
|
||||||
|
if (viewport) {
|
||||||
|
const mainLevel = viewport.querySelector('.menu-vdi__level--main');
|
||||||
|
if (mainLevel) {
|
||||||
|
// Move all items back to menu container
|
||||||
|
const items = Array.from(mainLevel.children);
|
||||||
|
items.forEach(item => {
|
||||||
|
menuContainer.appendChild(item);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove viewport structure
|
||||||
|
viewport.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Sliding structure cleaned up');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Navigation;
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* Tags external links in the document with appropriate attributes and styling.
|
||||||
|
*
|
||||||
|
* This function identifies all anchor elements with href attributes and determines
|
||||||
|
* if they point to external domains. External links are enhanced with:
|
||||||
|
* - Accessibility label indicating they open in a new tab
|
||||||
|
* - target="_blank" to open in new tab
|
||||||
|
* - rel="noopener noreferrer" for security
|
||||||
|
* - Custom CSS class "extLink" for styling
|
||||||
|
*
|
||||||
|
* Links are considered external if their host differs from the current page's host.
|
||||||
|
* Malformed URLs are silently ignored.
|
||||||
|
*
|
||||||
|
* @function tagExternalLinks
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
|
||||||
|
function tagExternalLinks() {
|
||||||
|
const currentHost = window.location.host;
|
||||||
|
|
||||||
|
document.querySelectorAll('a[href]').forEach(link => {
|
||||||
|
try {
|
||||||
|
const url = new URL(link.href, window.location.href);
|
||||||
|
|
||||||
|
// If the link's host is different from the current host, treat as external
|
||||||
|
if (url.host !== currentHost) {
|
||||||
|
link.setAttribute('aria-label', 'External link, opens in a new tab');
|
||||||
|
link.setAttribute('target', '_blank');
|
||||||
|
link.setAttribute('rel', 'noopener noreferrer'); // Security best practice
|
||||||
|
link.classList.add('extLink'); // Add a custom class for icons or other styling
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// Ignore malformed URLs
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default tagExternalLinks;
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
/**
|
||||||
|
* Theme JS
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { registerButtonComponent } from './components/button.js';
|
||||||
|
import { registerBackToTopButton } from './components/backToTop.js';
|
||||||
|
import GetHeaderHeight from './modules/GetHeaderHeight.js';
|
||||||
|
import tagExternalLinks from './modules/TagExternalLinks.js';
|
||||||
|
import Navigation from './modules/Navigation.js';
|
||||||
|
|
||||||
|
// Add passive event listeners
|
||||||
|
! function (e) {
|
||||||
|
"function" == typeof define && define.amd ? define(e) : e()
|
||||||
|
}(function () {
|
||||||
|
let e;
|
||||||
|
const t = ["scroll", "wheel", "touchstart", "touchmove", "touchenter", "touchend", "touchleave", "mouseout", "mouseleave", "mouseup", "mousedown", "mousemove", "mouseenter", "mousewheel", "mouseover"];
|
||||||
|
if (function () {
|
||||||
|
let e = !1;
|
||||||
|
try {
|
||||||
|
const t = Object.defineProperty({}, "passive", {
|
||||||
|
get: function () {
|
||||||
|
e = !0
|
||||||
|
}
|
||||||
|
});
|
||||||
|
window.addEventListener("test", null, t);
|
||||||
|
window.removeEventListener("test", null, t);
|
||||||
|
} catch (e) { }
|
||||||
|
return e
|
||||||
|
}()) {
|
||||||
|
const n = EventTarget.prototype.addEventListener;
|
||||||
|
e = n;
|
||||||
|
EventTarget.prototype.addEventListener = function (n, o, r) {
|
||||||
|
let i;
|
||||||
|
const s = "object" == typeof r && null !== r,
|
||||||
|
u = s ? r.capture : r;
|
||||||
|
if (s) {
|
||||||
|
const t = Object.getOwnPropertyDescriptor(r, "passive");
|
||||||
|
r = t && !0 !== t.writable && void 0 === t.set ? { ...r } : r;
|
||||||
|
} else {
|
||||||
|
r = {};
|
||||||
|
}
|
||||||
|
r.passive = void 0 !== (i = r.passive) ? i : -1 !== t.indexOf(n) && !0;
|
||||||
|
r.capture = void 0 !== u && u;
|
||||||
|
e.call(this, n, o, r);
|
||||||
|
};
|
||||||
|
EventTarget.prototype.addEventListener._original = e
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Application entrypoint
|
||||||
|
*/
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
// Tag external links
|
||||||
|
tagExternalLinks();
|
||||||
|
|
||||||
|
// Register button component
|
||||||
|
registerButtonComponent();
|
||||||
|
registerBackToTopButton();
|
||||||
|
|
||||||
|
// Initialize Navigation
|
||||||
|
const navigation = new Navigation('navMainToggle', '.menu-vdi__toggle');
|
||||||
|
|
||||||
|
// Initialize Navigation
|
||||||
|
navigation.desktopMenuDropdowns();
|
||||||
|
navigation.mobileMenuToggle();
|
||||||
|
|
||||||
|
// Initialize Header Height
|
||||||
|
GetHeaderHeight();
|
||||||
|
|
||||||
|
// Add Back to Top button to body
|
||||||
|
const backToTop = document.createElement('back-to-top');
|
||||||
|
document.body.appendChild(backToTop);
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`theme.js loaded.`);
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
/*
|
||||||
|
* Theme Name:VDI Starter v5
|
||||||
|
* Description: Custom WordPress theme starter for VDI Projects
|
||||||
|
* Version: 5.0
|
||||||
|
* Author: Vincent Design Inc.
|
||||||
|
* Text Domain: basicwp
|
||||||
|
*/
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
/* Light admin styles; avoid overriding core wp-admin UI */
|
||||||
|
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
/* Theme editor styles */
|
||||||
|
|
||||||
|
@import "../../static/dist/theme.css";
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--vdi-editor-gutter: clamp(1rem, 4vw, 3rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: var(--font-sans);
|
||||||
|
|
||||||
|
h1, h2, h3,
|
||||||
|
h4, h5, h6 {
|
||||||
|
font-family: var(--font-headings);
|
||||||
|
font-weight: 700;
|
||||||
|
margin: 0 0 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-styles-wrapper.is-root-container,
|
||||||
|
.editor-styles-wrapper .block-editor-block-list__layout.is-root-container,
|
||||||
|
.editor-styles-wrapper .wp-block-post-content,
|
||||||
|
.editor-visual-editor__post-title-wrapper {
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-inline: auto;
|
||||||
|
max-width: min(100%, var(--wp--style--global--wide-size, 1536px));
|
||||||
|
padding-inline: var(--vdi-editor-gutter);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-styles-wrapper .alignfull,
|
||||||
|
.editor-styles-wrapper .mx-break-out {
|
||||||
|
margin-left: calc(var(--vdi-editor-gutter) * -1);
|
||||||
|
margin-right: calc(var(--vdi-editor-gutter) * -1);
|
||||||
|
max-width: none;
|
||||||
|
width: calc(100% + (var(--vdi-editor-gutter) * 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-styles-wrapper .ml-break-out {
|
||||||
|
margin-left: calc(var(--vdi-editor-gutter) * -1);
|
||||||
|
max-width: none;
|
||||||
|
width: calc(100% + var(--vdi-editor-gutter));
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-styles-wrapper .mr-break-out {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: calc(var(--vdi-editor-gutter) * -1);
|
||||||
|
max-width: none;
|
||||||
|
width: calc(100% + var(--vdi-editor-gutter));
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-block-buttons .block-editor-block-list__layout {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
@theme {
|
||||||
|
/** Break-out variables
|
||||||
|
* These are used for the break-out plugin and the responsive utilities.
|
||||||
|
* The break-out variables are set to match the default plugin settings.
|
||||||
|
* You can override them if you need to adjust for a particular use case.
|
||||||
|
*/
|
||||||
|
--twcb-scrollbar-width: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@utility mx-break-out {
|
||||||
|
margin-left: calc(50% - 50vw);
|
||||||
|
margin-right: calc(50% - 50vw);
|
||||||
|
width: calc(100vw - var(--twcb-scrollbar-width));
|
||||||
|
}
|
||||||
|
|
||||||
|
@utility ml-break-out {
|
||||||
|
margin-left: calc(50% - 50vw);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@utility mr-break-out {
|
||||||
|
margin-left: calc(-50% + 50vw);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/* Theme color definitions */
|
||||||
|
|
||||||
|
@theme {
|
||||||
|
--color-black: oklch(0% 0 0);
|
||||||
|
--color-white: oklch(100% 0 0);
|
||||||
|
|
||||||
|
--color-background: oklch(89.75% 0 0);
|
||||||
|
--color-text: var(--color-black);
|
||||||
|
|
||||||
|
--color-primary: oklch(0.57 0.203362 257.1706);
|
||||||
|
--color-primary-100: color-mix(in oklch, var(--color-primary) 10%, white);
|
||||||
|
--color-primary-200: color-mix(in oklch, var(--color-primary) 20%, white);
|
||||||
|
--color-primary-300: color-mix(in oklch, var(--color-primary) 30%, white);
|
||||||
|
--color-primary-400: color-mix(in oklch, var(--color-primary) 40%, white);
|
||||||
|
--color-primary-500: color-mix(in oklch, var(--color-primary) 50%, white);
|
||||||
|
--color-primary-600: color-mix(in oklch, var(--color-primary) 60%, white);
|
||||||
|
--color-primary-700: color-mix(in oklch, var(--color-primary) 70%, white);
|
||||||
|
--color-primary-800: color-mix(in oklch, var(--color-primary) 80%, white);
|
||||||
|
--color-primary-900: color-mix(in oklch, var(--color-primary) 90%, white);
|
||||||
|
|
||||||
|
--color-secondary: oklch(0.56 0.0176 257.23);
|
||||||
|
--color-secondary-100: color-mix(in oklch, var(--color-secondary) 10%, white);
|
||||||
|
--color-secondary-200: color-mix(in oklch, var(--color-secondary) 20%, white);
|
||||||
|
--color-secondary-300: color-mix(in oklch, var(--color-secondary) 30%, white);
|
||||||
|
--color-secondary-400: color-mix(in oklch, var(--color-secondary) 40%, white);
|
||||||
|
--color-secondary-500: color-mix(in oklch, var(--color-secondary) 50%, white);
|
||||||
|
--color-secondary-600: color-mix(in oklch, var(--color-secondary) 60%, white);
|
||||||
|
--color-secondary-700: color-mix(in oklch, var(--color-secondary) 70%, white);
|
||||||
|
--color-secondary-800: color-mix(in oklch, var(--color-secondary) 80%, white);
|
||||||
|
--color-secondary-900: color-mix(in oklch, var(--color-secondary) 90%, white);
|
||||||
|
|
||||||
|
--color-bodylinks: oklch(0.48 0.0789 211.58);
|
||||||
|
--color-footlinks: oklch(0.65 0.1104 212.2);
|
||||||
|
|
||||||
|
--color-success: oklch(64.01% 0.1751 146.7);
|
||||||
|
--color-info: oklch(0.55 0.0922 211.57);
|
||||||
|
--color-warning: oklch(84.42% 0.1722 84.93);
|
||||||
|
--color-danger: oklch(0.5126 0.1865 22.61);
|
||||||
|
--color-light: oklch(98.16% 0.0017 247.8);
|
||||||
|
--color-dark: oklch(34.51% 0.0133 248.2);
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/* Forms */
|
||||||
|
|
||||||
|
/* Base styles */
|
||||||
|
input[type="text"], input[type="email"], input[type="tel"],
|
||||||
|
input[type="url"], input[type="number"], input[type="password"],
|
||||||
|
input[type="date"], select, textarea {
|
||||||
|
@apply px-4 py-2 w-full rounded border-2 border-primary;
|
||||||
|
@apply text-black bg-white;
|
||||||
|
@apply focus-visible:border-transparent focus-visible:outline-2 focus-visible:outline-offset-[3px] focus-visible:outline-primary;
|
||||||
|
|
||||||
|
font-size: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Gravity Forms styles */
|
||||||
|
.gform_wrapper {
|
||||||
|
@apply max-w-full mx-auto;
|
||||||
|
|
||||||
|
.gform_fields { @apply text-black; }
|
||||||
|
|
||||||
|
fieldset.gfield { @apply mb-6; }
|
||||||
|
|
||||||
|
legend, label { @apply text-lg font-bold mb-2; }
|
||||||
|
|
||||||
|
label.gform-field-label--type-sub{ @apply font-normal text-base; }
|
||||||
|
|
||||||
|
.gfield_required { @apply text-danger text-xs font-bold ml-1; }
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
input[type="text"], input[type="email"], input[type="tel"],
|
||||||
|
input[type="url"], input[type="number"], input[type="password"],
|
||||||
|
input[type="date"], select, textarea {
|
||||||
|
@apply text-black bg-white;
|
||||||
|
@apply focus-visible:border-transparent focus-visible:outline-2 focus-visible:outline-offset-[3px] focus-visible:outline-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ginput_complex {
|
||||||
|
@apply sm:flex;
|
||||||
|
|
||||||
|
span {
|
||||||
|
@apply block grow;
|
||||||
|
|
||||||
|
&:not(:first-child) { @apply mt-6 sm:mt-0 sm:ml-4; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.gform_footer { @apply mt-8; }
|
||||||
|
|
||||||
|
h2.gform_submission_error { @apply text-xl text-danger font-bold my-4; }
|
||||||
|
|
||||||
|
.validation_message { @apply italic text-danger; }
|
||||||
|
|
||||||
|
.hidden_label > label { @apply hidden; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search block styles */
|
||||||
|
.wp-block-search__input {
|
||||||
|
@apply px-4 py-2 w-full rounded border-2 border-transparent focus-visible:bg-secondary-300 focus-visible:border-primary;
|
||||||
|
|
||||||
|
appearance: none;
|
||||||
|
flex-grow: 1;
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 0;
|
||||||
|
min-width: 3rem;
|
||||||
|
text-decoration: unset !important;
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
/* Miscellaneous custom styles */
|
||||||
|
@theme {
|
||||||
|
--spacing-menu-top: calc(100% + .9375rem);
|
||||||
|
--spacing-section: 2rem;
|
||||||
|
|
||||||
|
--shadow-menu-shadow: 0 .25rem .375rem rgba(0,0,0,0.1);
|
||||||
|
|
||||||
|
/** Breakpoints
|
||||||
|
* The breakpoints are set to match the default Tailwind breakpoints.
|
||||||
|
* You can override them here if you want to use different breakpoints.
|
||||||
|
*
|
||||||
|
* @see https://tailwindcss.com/docs/breakpoints
|
||||||
|
*/
|
||||||
|
--breakpoint-*: initial;
|
||||||
|
--breakpoint-xxs: 22.5rem; /* 360px */
|
||||||
|
--breakpoint-xs: 29.6875rem; /* 475px */
|
||||||
|
--breakpoint-sm: 40rem; /* 640px */
|
||||||
|
--breakpoint-md: 48rem; /* 768px */
|
||||||
|
--breakpoint-lg: 64rem; /* 1024px */
|
||||||
|
--breakpoint-xl: 70rem; /* 1280px */
|
||||||
|
--breakpoint-2xl: 96rem; /* 1536px */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Basic layout styles */
|
||||||
|
main#maincontent {
|
||||||
|
background-color: var(--color-background);
|
||||||
|
color: var(--color-text);
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 0 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 100%;
|
||||||
|
padding-inline: clamp(1.5rem, 5vw, 3rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
@apply relative my-section px-section;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
@apply mt-0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child, p:last-child {
|
||||||
|
@apply mb-0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.has-background {
|
||||||
|
@apply py-section bg-cover bg-no-repeat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Allows containers inside containers
|
||||||
|
*
|
||||||
|
* .container .wp-block-section {
|
||||||
|
* @apply mx-break-out;
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
|
.content-wrapper {
|
||||||
|
.alignfull {
|
||||||
|
@apply max-w-full;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alignwide {
|
||||||
|
@apply max-w-full;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alignleft {
|
||||||
|
@apply ml-0 mr-auto float-none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alignright {
|
||||||
|
@apply ml-auto mr-0 float-none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aligncenter {
|
||||||
|
@apply mx-auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive embeds */
|
||||||
|
.embed { position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; }
|
||||||
|
.embed iframe, .embed object, .embed embed, .embed video { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
/* Theme base styles */
|
||||||
|
|
||||||
|
@import "./global.css";
|
||||||
|
@import "./colors.css";
|
||||||
|
@import "./prose.css";
|
||||||
|
@import "./typography.css";
|
||||||
|
@import "./skip-link.css";
|
||||||
|
@import './misc.css';
|
||||||
|
@import "./forms.css";
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/* Miscellaneous extra styles */
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/* Theme prose styles */
|
||||||
|
|
||||||
|
@theme {
|
||||||
|
--tw-prose-body: var(--color-primary);
|
||||||
|
--tw-prose-headings: var(--color-primary);
|
||||||
|
--tw-prose-lead: var(--color-primary);
|
||||||
|
--tw-prose-links: var(--color-info);
|
||||||
|
--tw-prose-bold: var(--color-primary);
|
||||||
|
--tw-prose-counters: var(--color-primary);
|
||||||
|
--tw-prose-bullets: var(--color-secondary);
|
||||||
|
--tw-prose-hr: var(--color-secondary);
|
||||||
|
--tw-prose-quotes: var(--color-primary);
|
||||||
|
--tw-prose-quote-borders: var(--color-primary);
|
||||||
|
--tw-prose-captions: var(--color-secondary);
|
||||||
|
--tw-prose-code: var(--color-primary);
|
||||||
|
--tw-prose-pre-code: var(--color-primary);
|
||||||
|
--tw-prose-pre-bg: var(--color-secondary);
|
||||||
|
--tw-prose-th-borders: var(--color-secondary);
|
||||||
|
--tw-prose-td-borders: var(--color-secondary);
|
||||||
|
--tw-prose-invert-body: var(--color-primary);
|
||||||
|
--tw-prose-invert-headings: var(--color-primary);
|
||||||
|
--tw-prose-invert-lead: var(--color-primary);
|
||||||
|
--tw-prose-invert-links: var(--color-secondary);
|
||||||
|
--tw-prose-invert-bold: var(--color-primary);
|
||||||
|
--tw-prose-invert-counters: var(--color-primary);
|
||||||
|
--tw-prose-invert-bullets: var(--color-primary);
|
||||||
|
--tw-prose-invert-hr: var(--color-secondary);
|
||||||
|
--tw-prose-invert-quotes: var(--color-primary);
|
||||||
|
--tw-prose-invert-quote-borders: var(--color-primary);
|
||||||
|
--tw-prose-invert-captions: var(--color-primary);
|
||||||
|
--tw-prose-invert-code: var(--color-secondary);
|
||||||
|
--tw-prose-invert-pre-code: var(--color-primary);
|
||||||
|
--tw-prose-invert-pre-bg: oklch(0% 0 0 / 50%);
|
||||||
|
--tw-prose-invert-th-borders: var(--color-primary);
|
||||||
|
--tw-prose-invert-td-borders: var(--color-primary);
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
.skip-link {
|
||||||
|
background-color: #f6ff00 !important;
|
||||||
|
border-color: #f6ff00 !important;
|
||||||
|
color: #000 !important;
|
||||||
|
font-size: larger;
|
||||||
|
font-weight: 600;
|
||||||
|
left: 0;
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: 90vw;
|
||||||
|
opacity: 1;
|
||||||
|
outline-color: #f6ff00 !important;
|
||||||
|
padding: 1rem;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
text-align: center;
|
||||||
|
top: 0.5rem;
|
||||||
|
transition: transform 0.1875s ease-out;
|
||||||
|
width: 15rem;
|
||||||
|
z-index: 999;
|
||||||
|
|
||||||
|
&:not(:focus):not(:hover) {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-4em);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,174 @@
|
|||||||
|
/* Basic typographical styles */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All font sizes are based on 16px base font size and 1920px wide screen
|
||||||
|
* Default size is expressed as percentage of screen width.
|
||||||
|
* text-14px: 12px-27px, default: 14px
|
||||||
|
* text-16px: 14px-28px, default: 16px
|
||||||
|
* text-18px: 14px-30px, default: 18px
|
||||||
|
* text-20px: 16px-32px, default: 20px
|
||||||
|
* text-22px: 17px-33px, default: 22px
|
||||||
|
* text-25px: 18px-35px, default: 25px
|
||||||
|
* text-30px: 19px-37px, default: 30px
|
||||||
|
* text-35px: 20px-40px, default: 35px
|
||||||
|
* text-38px: 22px-48px, default: 38px
|
||||||
|
* text-40px: 24px-56px, default: 40px
|
||||||
|
* text-45px: 25px-64px, default: 45px
|
||||||
|
* text-50px: 27px-72px, default: 50px
|
||||||
|
* text-55px: 28px-76px, default: 55px
|
||||||
|
* text-60px: 30px-80px, default: 60px
|
||||||
|
* text-70px: 30px-76px, default: 70px
|
||||||
|
* text-75px: 32px-80px, default: 75px
|
||||||
|
*
|
||||||
|
* Font sizes at standard viewport widths:
|
||||||
|
* | 360px | 640px | 768px | 1024px | 1280px | 1440px | 1920px
|
||||||
|
* |-------|-------|-------|--------|--------|--------|-------
|
||||||
|
* text-14px | 12.00 | 12.36 | 12.52 | 12.85 | 13.18 | 13.38 | 14.00
|
||||||
|
* text-16px | 14.00 | 14.36 | 14.52 | 14.85 | 15.18 | 15.38 | 16.00
|
||||||
|
* text-18px | 14.00 | 14.72 | 15.05 | 15.70 | 16.36 | 16.77 | 18.00
|
||||||
|
* text-20px | 16.00 | 16.72 | 17.05 | 17.70 | 18.36 | 18.77 | 20.00
|
||||||
|
* text-22px | 17.60 | 18.36 | 18.75 | 19.47 | 20.19 | 20.65 | 22.00
|
||||||
|
* text-25px | 18.00 | 19.26 | 19.83 | 20.98 | 22.13 | 22.85 | 25.00
|
||||||
|
* text-30px | 18.96 | 20.89 | 21.85 | 23.66 | 25.47 | 26.60 | 30.00
|
||||||
|
* text-35px | 20.00 | 22.69 | 23.92 | 26.38 | 28.85 | 30.38 | 35.00
|
||||||
|
* text-38px | 22.40 | 24.85 | 26.48 | 29.04 | 31.60 | 33.20 | 38.00
|
||||||
|
* text-40px | 24.00 | 26.87 | 28.18 | 30.81 | 33.44 | 35.08 | 40.00
|
||||||
|
* text-45px | 25.60 | 29.22 | 30.67 | 33.86 | 37.04 | 39.03 | 45.00
|
||||||
|
* text-50px | 27.20 | 31.58 | 33.16 | 36.90 | 40.65 | 42.98 | 50.00
|
||||||
|
* text-70px | 30.40 | 37.01 | 40.76 | 47.26 | 53.75 | 57.82 | 70.00
|
||||||
|
* text-75px | 32.00 | 39.46 | 43.25 | 50.30 | 57.36 | 61.77 | 75.00
|
||||||
|
*/
|
||||||
|
|
||||||
|
@theme {
|
||||||
|
--font-sans: "Raleway", sans-serif;
|
||||||
|
--line-height: 1.6;
|
||||||
|
|
||||||
|
--text-base: 1rem;
|
||||||
|
--text-14px: clamp(0.75rem, calc(0.7212rem + 0.1282vw), 0.875rem);
|
||||||
|
--text-16px: clamp(0.875rem, calc(0.8462rem + 0.1282vw), 1rem);
|
||||||
|
--text-18px: clamp(0.875rem, calc(0.8173rem + 0.2564vw), 1.125rem);
|
||||||
|
--text-20px: clamp(1rem, calc(0.9423rem + 0.2564vw), 1.25rem);
|
||||||
|
--text-22px: clamp(1.1rem, calc(1.0365rem + 0.2821vw), 1.375rem);
|
||||||
|
--text-25px: clamp(1.125rem, calc(1.024rem + 0.4487vw), 1.5625rem);
|
||||||
|
--text-30px: clamp(1.185rem, calc(1.0258rem + 0.7077vw), 1.875rem);
|
||||||
|
--text-35px: clamp(1.25rem, calc(1.0337rem + 0.9615vw), 2.1875rem);
|
||||||
|
--text-38px: clamp(1.4rem, calc(1.175rem + 1vw), 2.375rem);
|
||||||
|
--text-40px: clamp(1.5rem, calc(1.2692rem + 1.0256vw), 2.5rem);
|
||||||
|
--text-45px: clamp(1.6rem, calc(1.3202rem + 1.2436vw), 2.8125rem);
|
||||||
|
--text-50px: clamp(1.7rem, calc(1.3712rem + 1.4615vw), 3.125rem);
|
||||||
|
--text-70px: clamp(1.9rem, calc(1.3288rem + 2.5385vw), 4.375rem);
|
||||||
|
--text-75px: clamp(2rem, calc(1.3798rem + 2.7564vw), 4.6875rem);
|
||||||
|
|
||||||
|
--h1: calc(var(--text-base) * 2.25);
|
||||||
|
--h2: calc(var(--text-base) * 1.75);
|
||||||
|
--h3: calc(var(--text-base) * 1.5);
|
||||||
|
--h4: calc(var(--text-base) * 1.25);
|
||||||
|
--h5: calc(var(--text-base) * 1.125);
|
||||||
|
--h6: calc(var(--text-base) * 1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: white;
|
||||||
|
color: black;
|
||||||
|
font-family: var(--font-sans);
|
||||||
|
font-size: var(--text-base);
|
||||||
|
line-height: var(--line-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
::selection { background: var(--color-warning); }
|
||||||
|
|
||||||
|
@layer components {
|
||||||
|
h1, h2, h3,
|
||||||
|
h4, h5, h6 {
|
||||||
|
font-family: var(--font-headings);
|
||||||
|
font-weight: 700;
|
||||||
|
margin: 0 0 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, .h1 {
|
||||||
|
font-size: var(--h1);
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2, .h2 {
|
||||||
|
font-size: var(--h2);
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3, .h3 {
|
||||||
|
font-size: var(--h3);
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4, .h4 {
|
||||||
|
font-size: var(--h4);
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
h5, .h5 { font-size: var(--h5); }
|
||||||
|
|
||||||
|
h6, .h6 { font-size: var(--h6); }
|
||||||
|
}
|
||||||
|
|
||||||
|
a, .link {
|
||||||
|
color: var(--color-bodylinks);
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color 200ms;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover { color: var(--color-primary); }
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 a, .h1 a,
|
||||||
|
h2 a, .h2 a,
|
||||||
|
h3 a, .h3 a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ul { list-style-type: disc; }
|
||||||
|
|
||||||
|
ol { list-style-type: decimal; }
|
||||||
|
|
||||||
|
li ul, li ol { margin: 0 1rem; }
|
||||||
|
|
||||||
|
ol ol { list-style: lower-alpha; }
|
||||||
|
|
||||||
|
ol ol ol { list-style: lower-roman; }
|
||||||
|
|
||||||
|
ol ol ol ol { list-style: lower-alpha; }
|
||||||
|
|
||||||
|
pre, code,
|
||||||
|
samp, style { font-family: monospace; }
|
||||||
|
|
||||||
|
pre {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
overflow: auto;
|
||||||
|
padding: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre code {
|
||||||
|
background-color: inherit;
|
||||||
|
border-radius: 0;
|
||||||
|
color: inherit;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
@apply bg-black/30 px-[3px] py-0.5 font-mono text-black text-xs rounded-sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
background-color: black;
|
||||||
|
border: none;
|
||||||
|
display: block;
|
||||||
|
height: 1px;
|
||||||
|
margin: 1rem 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
@@ -0,0 +1,176 @@
|
|||||||
|
/* Button styles */
|
||||||
|
|
||||||
|
@theme {
|
||||||
|
/* Configuration */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Button component settings
|
||||||
|
*
|
||||||
|
* The variables below are used to define the button styles.
|
||||||
|
* Most of these variables come from the main theme configuration.
|
||||||
|
* The following variables are not defined, but have fallback values
|
||||||
|
* in their respective locations and can be added if needed:
|
||||||
|
*
|
||||||
|
* --button-font-weight (fallback is 600/semibold)
|
||||||
|
* --button-font-size (fallback is 1rem)
|
||||||
|
* --button-outline-width (fallback is --button-border-width)
|
||||||
|
* --button-outline-style (fallback is --button-border-style)
|
||||||
|
* --button-outline-color (fallback is --button-border-color)
|
||||||
|
*/
|
||||||
|
|
||||||
|
--button-bg: var(--color-primary);
|
||||||
|
--button-color: var(--color-white);
|
||||||
|
--button-hover-bg: var(--color-info);
|
||||||
|
--button-hover-border-color: var(--color-info);
|
||||||
|
--button-hover-color: var(--color-white);
|
||||||
|
--button-border-width: 3px;
|
||||||
|
--button-border-style: solid;
|
||||||
|
--button-border-color: var(--button-bg);
|
||||||
|
--button-radius: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn, .button, .acf-block-preview .button {
|
||||||
|
@apply px-8 py-2 min-w-0;
|
||||||
|
|
||||||
|
background: var(--button-bg);
|
||||||
|
color: var(--button-color);
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
transition: background 200ms, border-color 200ms, color 200ms;
|
||||||
|
|
||||||
|
border-width: var(--button-border-width);
|
||||||
|
border-style: var(--button-border-style);
|
||||||
|
border-color: var(--button-border-color);
|
||||||
|
border-radius: var(--button-radius);
|
||||||
|
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: var(--button-font-weight, 600);
|
||||||
|
font-size: var(--button-font-size, 1rem);
|
||||||
|
line-height: 1.1;
|
||||||
|
|
||||||
|
&[data-button-variant="outline"] {
|
||||||
|
background: transparent;
|
||||||
|
&:hover { background: transparent; }
|
||||||
|
|
||||||
|
--button-color: var(--button-outline-color, var(--button-bg));
|
||||||
|
--button-hover-border-color: var(--button-hover-bg);
|
||||||
|
--button-hover-color: var(--button-hover-bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hover/focus/active */
|
||||||
|
.btn:hover, .button:hover, .acf-block-preview .button:hover {
|
||||||
|
background: var(--button-hover-bg);
|
||||||
|
border-color: var(--button-hover-border-color);
|
||||||
|
color: var(--button-hover-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:focus, .button:focus {
|
||||||
|
outline-width: var(--button-outline-width, var(--button-border-width));
|
||||||
|
outline-style: var(--button-outline-style, var(--button-border-style));
|
||||||
|
outline-color: var(--button-outline-color, var(--button-border-color));
|
||||||
|
outline-offset: calc(var(--button-border-width) * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:active, .button:active { transform: scale(99%); }
|
||||||
|
|
||||||
|
/* Back To Top Button */
|
||||||
|
#backToTopBtn {
|
||||||
|
display:none;
|
||||||
|
position:fixed;
|
||||||
|
bottom:2rem;
|
||||||
|
right:2rem;
|
||||||
|
z-index:1000;
|
||||||
|
padding:0.75em 1.5em;
|
||||||
|
font-size:1.1rem;
|
||||||
|
border-radius:2em;
|
||||||
|
background:var(--color-primary,#3857BC);
|
||||||
|
color:#fff;
|
||||||
|
border:none;
|
||||||
|
box-shadow:0 2px 8px rgba(0,0,0,0.15);
|
||||||
|
cursor:pointer;
|
||||||
|
transition:opacity 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variants
|
||||||
|
*
|
||||||
|
* The following styles are used to define button variants.
|
||||||
|
* These styles are applied to the button element using the
|
||||||
|
* `data-button-*` attributes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Sizes */
|
||||||
|
.btn[data-button-size="small"], .button[data-button-size="small"] { @apply px-4 py-0.5; }
|
||||||
|
.btn[data-button-size="medium"], .button[data-button-size="medium"] { @apply px-8 py-2; }
|
||||||
|
.btn[data-button-size="large"], .button[data-button-size="large"] { @apply px-12 py-3; }
|
||||||
|
|
||||||
|
/* Width */
|
||||||
|
.btn[data-button-width="auto"], .button[data-button-width="auto"] { @apply min-w-0; }
|
||||||
|
.btn[data-button-width="small"], .button[data-button-width="small"] { @apply px-2; }
|
||||||
|
.btn[data-button-width="wide"], .button[data-button-width="wide"] { @apply sm:min-w-[20rem]; }
|
||||||
|
.button[data-button-width="full"],
|
||||||
|
x-button:has(.button[data-button-width="full"]) { @apply w-full; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Colors
|
||||||
|
*
|
||||||
|
* We don't need to speicifcally target "primary" buttons
|
||||||
|
* as the button styling defaults to "primary".
|
||||||
|
* However, you can, if necessary, by adding a style block
|
||||||
|
* like the ones below and changing the color values.
|
||||||
|
*/
|
||||||
|
.btn[data-button-color="secondary"], .button[data-button-color="secondary"] {
|
||||||
|
--button-bg: var(--color-secondary);
|
||||||
|
--button-color: var(--color-white);
|
||||||
|
--button-border-color: var(--color-secondary);
|
||||||
|
--button-outline-color: oklch(0.48 0.0136 252.2);
|
||||||
|
--button-hover-bg: var(--color-dark);
|
||||||
|
--button-hover-border-color: var(--color-dark);
|
||||||
|
--button-hover-color: var(--color-white);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn[data-button-color="light"], .button[data-button-color="light"] {
|
||||||
|
--button-bg: var(--color-white);
|
||||||
|
--button-color: var(--color-dark);
|
||||||
|
--button-border-color: var(--color-white);
|
||||||
|
--button-hover-bg: var(--color-dark);
|
||||||
|
--button-hover-border-color: var(--color-dark);
|
||||||
|
--button-hover-color: var(--color-white);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn[data-button-color="white"], .button[data-button-color="white"] {
|
||||||
|
--button-bg: var(--color-white);
|
||||||
|
--button-color: var(--color-black);
|
||||||
|
--button-border-color: var(--color-white);
|
||||||
|
--button-hover-bg: var(--color-secondary-200);
|
||||||
|
--button-hover-border-color: var(--color-secondary-200);
|
||||||
|
--button-hover-color: var(--color-black);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn[data-button-color="black"], .button[data-button-color="black"] {
|
||||||
|
--button-bg: var(--color-black);
|
||||||
|
--button-color: var(--color-white);
|
||||||
|
--button-border-color: var(--color-black);
|
||||||
|
--button-hover-bg: var(--color-secondary);
|
||||||
|
--button-hover-border-color: var(--color-secondary);
|
||||||
|
--button-hover-color: var(--color-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-to-top {
|
||||||
|
background: var(--color-primary, #3857BC);
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
border-radius: 2em;
|
||||||
|
padding: 0.75em 1.5em;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: opacity 0.2s, background 0.2s;
|
||||||
|
opacity: 0.85;
|
||||||
|
}
|
||||||
|
.back-to-top:hover, .back-to-top:focus {
|
||||||
|
background: var(--color-info, #233a7a);
|
||||||
|
opacity: 1;
|
||||||
|
outline: 2px solid var(--color-info, #233a7a);
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
.alignfull {
|
||||||
|
margin-left: calc(50% - 50vw);
|
||||||
|
margin-right: calc(50% - 50vw);
|
||||||
|
width: 100vw;
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
/* Theme block styles */
|
||||||
|
|
||||||
|
@import './buttons.css';
|
||||||
|
@import './core.css';
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
/* Breadcrumb styles */
|
||||||
|
|
||||||
|
#breadcrumbs {
|
||||||
|
@apply text-white;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: oklch(0.72 0.122 212.25);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color:color-mix(in oklch, oklch(0.72 0.122 212.25) 60%, white);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
/* Theme component styles */
|
||||||
|
|
||||||
|
@import "./site-header.css";
|
||||||
|
@import "./breadcrumbs.css";
|
||||||
|
@import "./post-list.css";
|
||||||
|
@import "./sidebar.css";
|
||||||
|
@import "./pagination.css";
|
||||||
|
@import "./site-footer.css";
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/* Post index pagination styles */
|
||||||
|
|
||||||
|
.pagination {
|
||||||
|
.nav-links {
|
||||||
|
@apply hidden md:flex items-center justify-center mt-12;
|
||||||
|
|
||||||
|
.page-numbers {
|
||||||
|
@apply hidden md:flex items-center justify-center h-10 p-4 text-base font-medium transition duration-300 rounded stroke-primary text-primary hover:bg-info hover:text-light hover:stroke-info focus-visible:bg-info focus-visible:text-light focus-visible:stroke-info focus-visible:outline-none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-numbers.current {
|
||||||
|
@apply text-light whitespace-nowrap bg-info ring-offset-2 hover:bg-primary hover:stroke-primary focus-visible:bg-info;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prev, .next {
|
||||||
|
@apply flex gap-4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& a, & span {
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: #3857BC !important;
|
||||||
|
margin: 0 5px;
|
||||||
|
padding: .25rem .5rem;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
& .current, & a:hover {
|
||||||
|
background: #3857BC !important;
|
||||||
|
border-color: #3857BC !important;
|
||||||
|
color: #fff !important;
|
||||||
|
padding: .25rem .5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/* Blog/post index listing styles */
|
||||||
|
|
||||||
|
.post-list {
|
||||||
|
/* Original styles, if needed
|
||||||
|
* .post-list__posts {
|
||||||
|
* }
|
||||||
|
* .post-list__h1 {
|
||||||
|
* }
|
||||||
|
* .post-list__post {
|
||||||
|
* &:hover {
|
||||||
|
* img {
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* .post-list__title {
|
||||||
|
* }
|
||||||
|
* .post-list__details {
|
||||||
|
* }
|
||||||
|
* .post-list__byline {
|
||||||
|
* }
|
||||||
|
* .post-list__author {
|
||||||
|
* }
|
||||||
|
* .post-list__sep {
|
||||||
|
* }
|
||||||
|
* .post-list__date {
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Original styles, if needed
|
||||||
|
* .no-posts {
|
||||||
|
* .no-posts__title {
|
||||||
|
* }
|
||||||
|
* .no-posts__desc {
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/* Sidebar styles */
|
||||||
|
|
||||||
|
.sidebar{
|
||||||
|
.widget {
|
||||||
|
/* Widget styles */
|
||||||
|
@apply mb-8;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
/* Widget title styles */
|
||||||
|
@apply m-0 mb-2 font-semibold;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
/* List styles */
|
||||||
|
@apply list-none m-0 p-0 pl-3 border-l-3 border-secondary-400;
|
||||||
|
|
||||||
|
li {
|
||||||
|
/* List item styles */
|
||||||
|
@apply text-balance;
|
||||||
|
|
||||||
|
&:first-of-type {
|
||||||
|
/* First list item styles */
|
||||||
|
@apply leading-none mb-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/* Footer styles */
|
||||||
|
|
||||||
|
.site-footer {
|
||||||
|
#footRight {
|
||||||
|
div {
|
||||||
|
@apply col-span-1 md:col-span-4 lg:col-span-1;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
@apply font-bold text-secondary-300 text-20px mb-4 pb-2 border-b border-b-secondary-300
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
@apply text-footlinks hover:opacity-60;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.widget {
|
||||||
|
li {
|
||||||
|
@apply text-16px my-1 mb-2 leading-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
@apply font-bold text-18px text-secondary mb-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
@apply transition-colors duration-300 hover:text-success focus-visible:text-success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-footer-menu-container {
|
||||||
|
@apply grow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyright {
|
||||||
|
p { @apply leading-none m-0 p-0; }
|
||||||
|
|
||||||
|
a { @apply text-white hover:text-primary-500 underline underline-offset-2; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/* Header styles */
|
||||||
|
|
||||||
|
.site-header {
|
||||||
|
/* Site header styles */
|
||||||
|
.nav-aux__container {
|
||||||
|
a {
|
||||||
|
/* Link styles */
|
||||||
|
color: var(--color-primary-600);
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: color 0.3s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--color-primary-800);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#globalSearch {
|
||||||
|
@apply text-14px text-light;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 1.8 MiB |
Binary file not shown.
@@ -0,0 +1,702 @@
|
|||||||
|
/*--------------------------------
|
||||||
|
Lineicons regular icon font
|
||||||
|
-------------------------------- */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Lineicons';
|
||||||
|
src: url('../../styles/fonts/Lineicons.woff2') format('woff2'),
|
||||||
|
url('../../styles/fonts/Lineicons.svg') format('svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* base class */
|
||||||
|
[class^="lni-"], [class*=" lni-"],
|
||||||
|
[class^="icon-"], [class*=" icon-"],
|
||||||
|
[class^="lni-"]:before, [class*=" lni-"]:before,
|
||||||
|
[class^="icon-"]:before, [class*=" icon-"]:before {
|
||||||
|
font-family: "Lineicons", sans-serif;
|
||||||
|
font-style: normal;
|
||||||
|
speak: never;
|
||||||
|
display: inline-block;
|
||||||
|
text-decoration: inherit;
|
||||||
|
vertical-align: middle;
|
||||||
|
text-align: center;
|
||||||
|
/* If needed - opacity: .8; */
|
||||||
|
/* Animation center compensation - margins should be symmetric */
|
||||||
|
/* if needed - margin-left: .2rem; */
|
||||||
|
/* if needed - margin-right: .2rem; */
|
||||||
|
/* For safety - reset parent styles, that can break glyph codes*/
|
||||||
|
font-variant: normal;
|
||||||
|
text-transform: none;
|
||||||
|
font-size: 120%;
|
||||||
|
/* Font smoothing. That was taken from TWBS */
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
/**
|
||||||
|
* Uncomment for 3D effect
|
||||||
|
*
|
||||||
|
* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Circular Icons */
|
||||||
|
.circular-icon {
|
||||||
|
@apply box-content bg-secondary rounded-full text-gray-800 inline-block;
|
||||||
|
|
||||||
|
--size: 3rem;
|
||||||
|
height: var(--size);
|
||||||
|
text-align: center;
|
||||||
|
width: var(--size);
|
||||||
|
|
||||||
|
i {
|
||||||
|
display: inline-block;
|
||||||
|
height: var(--size);
|
||||||
|
line-height: var(--size);
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: var(--size);
|
||||||
|
}
|
||||||
|
|
||||||
|
&i::before, span { line-height: var(--size) !important; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* rotate the icon infinitely */
|
||||||
|
.lni-is-spinning { animation: lni-spin 1s infinite linear; }
|
||||||
|
|
||||||
|
@keyframes lni-spin {
|
||||||
|
0% { transform: rotate(0deg); }
|
||||||
|
100% { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* transform */
|
||||||
|
.lni-rotate-90 { transform: rotate(90deg); }
|
||||||
|
.lni-rotate-180 { transform: rotate(180deg); }
|
||||||
|
.lni-rotate-270 { transform: rotate(270deg); }
|
||||||
|
.lni-flip-y { transform: scaleY(-1); }
|
||||||
|
.lni-flip-x { transform: scaleX(-1); }
|
||||||
|
|
||||||
|
/* icons */
|
||||||
|
.lni-500px:before, .icon-500px:before { content: "\ea01"; }
|
||||||
|
.lni-adobe:before, .icon-adobe:before { content: "\ea02"; }
|
||||||
|
.lni-adonis:before, .icon-adonis:before { content: "\ea03"; }
|
||||||
|
.lni-aeroplane-1:before, .icon-aeroplane-1:before { content: "\ea04"; }
|
||||||
|
.lni-agenda:before, .icon-agenda:before { content: "\ea05"; }
|
||||||
|
.lni-airbnb:before, .icon-airbnb:before { content: "\ea06"; }
|
||||||
|
.lni-airtable:before, .icon-airtable:before { content: "\ea07"; }
|
||||||
|
.lni-alarm-1:before, .icon-alarm-1:before { content: "\ea08"; }
|
||||||
|
.lni-align-text-center:before, .icon-align-text-center:before { content: "\ea09"; }
|
||||||
|
.lni-align-text-left:before, .icon-align-text-left:before { content: "\ea0a"; }
|
||||||
|
.lni-align-text-right:before, .icon-align-text-right:before { content: "\ea0b"; }
|
||||||
|
.lni-alpinejs:before, .icon-alpinejs:before { content: "\ea0c"; }
|
||||||
|
.lni-amazon:before, .icon-amazon:before { content: "\ea0d"; }
|
||||||
|
.lni-amazon-original:before, .icon-amazon-original:before { content: "\ea0e"; }
|
||||||
|
.lni-amazon-pay:before, .icon-amazon-pay:before { content: "\ea0f"; }
|
||||||
|
.lni-ambulance-1:before, .icon-ambulance-1:before { content: "\ea10"; }
|
||||||
|
.lni-amd:before, .icon-amd:before { content: "\ea11"; }
|
||||||
|
.lni-amex:before, .icon-amex:before { content: "\ea12"; }
|
||||||
|
.lni-anchor:before, .icon-anchor:before { content: "\ea13"; }
|
||||||
|
.lni-android:before, .icon-android:before { content: "\ea14"; }
|
||||||
|
.lni-android-old:before, .icon-android-old:before { content: "\ea15"; }
|
||||||
|
.lni-angellist:before, .icon-angellist:before { content: "\ea16"; }
|
||||||
|
.lni-angle-double-down:before, .icon-angle-double-down:before { content: "\ea17"; }
|
||||||
|
.lni-angle-double-left:before, .icon-angle-double-left:before { content: "\ea18"; }
|
||||||
|
.lni-angle-double-right:before, .icon-angle-double-right:before { content: "\ea19"; }
|
||||||
|
.lni-angle-double-up:before, .icon-angle-double-up:before { content: "\ea1a"; }
|
||||||
|
.lni-angular:before, .icon-angular:before { content: "\ea1b"; }
|
||||||
|
.lni-app-store:before, .icon-app-store:before { content: "\ea1c"; }
|
||||||
|
.lni-apple-brand:before, .icon-apple-brand:before { content: "\ea1d"; }
|
||||||
|
.lni-apple-music:before, .icon-apple-music:before { content: "\ea1e"; }
|
||||||
|
.lni-apple-music-alt:before, .icon-apple-music-alt:before { content: "\ea1f"; }
|
||||||
|
.lni-apple:before, .icon-apple:before { content: "\ea1d"; }
|
||||||
|
.lni-apple-music:before, .icon-apple-music:before { content: "\ea1e"; }
|
||||||
|
.lni-apple-music-alt:before, .icon-apple-music-alt:before { content: "\ea1f"; }
|
||||||
|
.lni-apple-pay:before, .icon-apple-pay:before { content: "\ea20"; }
|
||||||
|
.lni-arc-browser:before, .icon-arc-browser:before { content: "\ea21"; }
|
||||||
|
.lni-arrow-all-direction:before, .icon-arrow-all-direction:before { content: "\ea22"; }
|
||||||
|
.lni-arrow-angular-top-left:before, .icon-arrow-angular-top-left:before { content: "\ea23"; }
|
||||||
|
.lni-arrow-angular-top-right:before, .icon-arrow-angular-top-right:before { content: "\ea24"; }
|
||||||
|
.lni-arrow-both-direction-horizontal-1:before, .icon-arrow-both-direction-horizontal-1:before { content: "\ea25"; }
|
||||||
|
.lni-arrow-both-direction-vertical-1:before, .icon-arrow-both-direction-vertical-1:before { content: "\ea26"; }
|
||||||
|
.lni-arrow-downward:before, .icon-arrow-downward:before { content: "\ea27"; }
|
||||||
|
.lni-arrow-left:before, .icon-arrow-left:before { content: "\ea28"; }
|
||||||
|
.lni-arrow-left-circle:before, .icon-arrow-left-circle:before { content: "\ea29"; }
|
||||||
|
.lni-arrow-right:before, .icon-arrow-right:before { content: "\ea2a"; }
|
||||||
|
.lni-arrow-right-circle:before, .icon-arrow-right-circle:before { content: "\ea2b"; }
|
||||||
|
.lni-arrow-upward:before, .icon-arrow-upward:before { content: "\ea2c"; }
|
||||||
|
.lni-asana:before, .icon-asana:before { content: "\ea2d"; }
|
||||||
|
.lni-astro:before, .icon-astro:before { content: "\ea2e"; }
|
||||||
|
.lni-atlassian:before, .icon-atlassian:before { content: "\ea2f"; }
|
||||||
|
.lni-audi:before, .icon-audi:before { content: "\ea30"; }
|
||||||
|
.lni-audi-alt:before, .icon-audi-alt:before { content: "\ea31"; }
|
||||||
|
.lni-aws:before, .icon-aws:before { content: "\ea32"; }
|
||||||
|
.lni-azure:before, .icon-azure:before { content: "\ea33"; }
|
||||||
|
.lni-badge-decagram-percent:before, .icon-badge-decagram-percent:before { content: "\ea34"; }
|
||||||
|
.lni-balloons:before, .icon-balloons:before { content: "\ea35"; }
|
||||||
|
.lni-ban-2:before, .icon-ban-2:before { content: "\ea36"; }
|
||||||
|
.lni-bar-chart-4:before, .icon-bar-chart-4:before { content: "\ea37"; }
|
||||||
|
.lni-bar-chart-dollar:before, .icon-bar-chart-dollar:before { content: "\ea38"; }
|
||||||
|
.lni-basket-shopping-3:before, .icon-basket-shopping-3:before { content: "\ea39"; }
|
||||||
|
.lni-beat:before, .icon-beat:before { content: "\ea3a"; }
|
||||||
|
.lni-behance:before, .icon-behance:before { content: "\ea3b"; }
|
||||||
|
.lni-bell-1:before, .icon-bell-1:before { content: "\ea3c"; }
|
||||||
|
.lni-bike:before, .icon-bike:before { content: "\ea3d"; }
|
||||||
|
.lni-bing:before, .icon-bing:before { content: "\ea3e"; }
|
||||||
|
.lni-bitbucket:before, .icon-bitbucket:before { content: "\ea3f"; }
|
||||||
|
.lni-bitcoin:before, .icon-bitcoin:before { content: "\ea40"; }
|
||||||
|
.lni-bittorrent:before, .icon-bittorrent:before { content: "\ea41"; }
|
||||||
|
.lni-blogger:before, .icon-blogger:before { content: "\ea42"; }
|
||||||
|
.lni-blogger-alt:before, .icon-blogger-alt:before { content: "\ea43"; }
|
||||||
|
.lni-bluetooth:before, .icon-bluetooth:before { content: "\ea44"; }
|
||||||
|
.lni-bluetooth-logo:before, .icon-bluetooth-logo:before { content: "\ea45"; }
|
||||||
|
.lni-bmw:before, .icon-bmw:before { content: "\ea46"; }
|
||||||
|
.lni-board-writing-3:before, .icon-board-writing-3:before { content: "\ea47"; }
|
||||||
|
.lni-bold:before, .icon-bold:before { content: "\ea48"; }
|
||||||
|
.lni-bolt-2:before, .icon-bolt-2:before { content: "\ea49"; }
|
||||||
|
.lni-bolt-3:before, .icon-bolt-3:before { content: "\ea4a"; }
|
||||||
|
.lni-book-1:before, .icon-book-1:before { content: "\ea4b"; }
|
||||||
|
.lni-bookmark-1:before, .icon-bookmark-1:before { content: "\ea4c"; }
|
||||||
|
.lni-bookmark-circle:before, .icon-bookmark-circle:before { content: "\ea4d"; }
|
||||||
|
.lni-books-2:before, .icon-books-2:before { content: "\ea4e"; }
|
||||||
|
.lni-bootstrap-5:before, .icon-bootstrap-5:before { content: "\ea4f"; }
|
||||||
|
.lni-bootstrap-5-square:before, .icon-bootstrap-5-square:before { content: "\ea50"; }
|
||||||
|
.lni-box-archive-1:before, .icon-box-archive-1:before { content: "\ea51"; }
|
||||||
|
.lni-box-closed:before, .icon-box-closed:before { content: "\ea52"; }
|
||||||
|
.lni-box-gift-1:before, .icon-box-gift-1:before { content: "\ea53"; }
|
||||||
|
.lni-brave:before, .icon-brave:before { content: "\ea54"; }
|
||||||
|
.lni-bricks:before, .icon-bricks:before { content: "\ea55"; }
|
||||||
|
.lni-bridge-3:before, .icon-bridge-3:before { content: "\ea56"; }
|
||||||
|
.lni-briefcase-1:before, .icon-briefcase-1:before { content: "\ea57"; }
|
||||||
|
.lni-briefcase-2:before, .icon-briefcase-2:before { content: "\ea58"; }
|
||||||
|
.lni-briefcase-plus-1:before, .icon-briefcase-plus-1:before { content: "\ea59"; }
|
||||||
|
.lni-brush-1-rotated:before, .icon-brush-1-rotated:before { content: "\ea5a"; }
|
||||||
|
.lni-brush-2:before, .icon-brush-2:before { content: "\ea5b"; }
|
||||||
|
.lni-btc:before, .icon-btc:before { content: "\ea5c"; }
|
||||||
|
.lni-bug-1:before, .icon-bug-1:before { content: "\ea5d"; }
|
||||||
|
.lni-buildings-1:before, .icon-buildings-1:before { content: "\ea5e"; }
|
||||||
|
.lni-bulb-2:before, .icon-bulb-2:before { content: "\ea5f"; }
|
||||||
|
.lni-bulb-4:before, .icon-bulb-4:before { content: "\ea60"; }
|
||||||
|
.lni-burger-1:before, .icon-burger-1:before { content: "\ea61"; }
|
||||||
|
.lni-burger-drink:before, .icon-burger-drink:before { content: "\ea62"; }
|
||||||
|
.lni-bus-1:before, .icon-bus-1:before { content: "\ea63"; }
|
||||||
|
.lni-busket-ball:before, .icon-busket-ball:before { content: "\ea64"; }
|
||||||
|
.lni-cake-1:before, .icon-cake-1:before { content: "\ea65"; }
|
||||||
|
.lni-calculator-1:before, .icon-calculator-1:before { content: "\ea66"; }
|
||||||
|
.lni-calculator-2:before, .icon-calculator-2:before { content: "\ea67"; }
|
||||||
|
.lni-calendar-days:before, .icon-calendar-days:before { content: "\ea68"; }
|
||||||
|
.lni-camera-1:before, .icon-camera-1:before { content: "\ea69"; }
|
||||||
|
.lni-camera-movie-1:before, .icon-camera-movie-1:before { content: "\ea6a"; }
|
||||||
|
.lni-candy-cane-2:before, .icon-candy-cane-2:before { content: "\ea6b"; }
|
||||||
|
.lni-candy-round-1:before, .icon-candy-round-1:before { content: "\ea6c"; }
|
||||||
|
.lni-canva:before, .icon-canva:before { content: "\ea6d"; }
|
||||||
|
.lni-capsule-1:before, .icon-capsule-1:before { content: "\ea6e"; }
|
||||||
|
.lni-car-2:before, .icon-car-2:before { content: "\ea6f"; }
|
||||||
|
.lni-car-4:before, .icon-car-4:before { content: "\ea70"; }
|
||||||
|
.lni-car-6:before, .icon-car-6:before { content: "\ea71"; }
|
||||||
|
.lni-caravan-1:before, .icon-caravan-1:before { content: "\ea72"; }
|
||||||
|
.lni-cart-1:before, .icon-cart-1:before { content: "\ea73"; }
|
||||||
|
.lni-cart-2:before, .icon-cart-2:before { content: "\ea74"; }
|
||||||
|
.lni-cash-app:before, .icon-cash-app:before { content: "\ea75"; }
|
||||||
|
.lni-certificate-badge-1:before, .icon-certificate-badge-1:before { content: "\ea76"; }
|
||||||
|
.lni-chat-bubble-2:before, .icon-chat-bubble-2:before { content: "\ea77"; }
|
||||||
|
.lni-check:before, .icon-check:before { content: "\ea78"; }
|
||||||
|
.lni-check-circle-1:before, .icon-check-circle-1:before { content: "\ea79"; }
|
||||||
|
.lni-check-square-2:before, .icon-check-square-2:before { content: "\ea7a"; }
|
||||||
|
.lni-chevron-down:before, .icon-chevron-down:before { content: "\ea7b"; }
|
||||||
|
.lni-chevron-down-circle:before, .icon-chevron-down-circle:before { content: "\ea7c"; }
|
||||||
|
.lni-chevron-left:before, .icon-chevron-left:before { content: "\ea7d"; }
|
||||||
|
.lni-chevron-left-circle:before, .icon-chevron-left-circle:before { content: "\ea7e"; }
|
||||||
|
.lni-chevron-right:before, .icon-chevron-right:before { content: "\ea7d"; transform: rotate(180deg); }
|
||||||
|
.lni-chevron-right-circle:before, .icon-chevron-right-circle:before { content: "\ea7f"; }
|
||||||
|
.lni-chevron-up:before, .icon-chevron-up:before { content: "\ea80"; }
|
||||||
|
.lni-chevron-up-circle:before, .icon-chevron-up-circle:before { content: "\ea81"; }
|
||||||
|
.lni-chrome:before, .icon-chrome:before { content: "\ea82"; }
|
||||||
|
.lni-chromecast:before, .icon-chromecast:before { content: "\ea83"; }
|
||||||
|
.lni-cisco:before, .icon-cisco:before { content: "\ea84"; }
|
||||||
|
.lni-claude:before, .icon-claude:before { content: "\ea85"; }
|
||||||
|
.lni-clickup:before, .icon-clickup:before { content: "\ea86"; }
|
||||||
|
.lni-clipboard:before, .icon-clipboard:before { content: "\ea87"; }
|
||||||
|
.lni-cloud-2:before, .icon-cloud-2:before { content: "\ea88"; }
|
||||||
|
.lni-cloud-bolt-1:before, .icon-cloud-bolt-1:before { content: "\ea89"; }
|
||||||
|
.lni-cloud-bolt-2:before, .icon-cloud-bolt-2:before { content: "\ea8a"; }
|
||||||
|
.lni-cloud-check-circle:before, .icon-cloud-check-circle:before { content: "\ea8b"; }
|
||||||
|
.lni-cloud-download:before, .icon-cloud-download:before { content: "\ea8c"; }
|
||||||
|
.lni-cloud-iot-2:before, .icon-cloud-iot-2:before { content: "\ea8d"; }
|
||||||
|
.lni-cloud-rain:before, .icon-cloud-rain:before { content: "\ea8e"; }
|
||||||
|
.lni-cloud-refresh-clockwise:before, .icon-cloud-refresh-clockwise:before { content: "\ea8f"; }
|
||||||
|
.lni-cloud-sun:before, .icon-cloud-sun:before { content: "\ea90"; }
|
||||||
|
.lni-cloud-upload:before, .icon-cloud-upload:before { content: "\ea91"; }
|
||||||
|
.lni-cloudflare:before, .icon-cloudflare:before { content: "\ea92"; }
|
||||||
|
.lni-code-1:before, .icon-code-1:before { content: "\ea93"; }
|
||||||
|
.lni-code-s:before, .icon-code-s:before { content: "\ea94"; }
|
||||||
|
.lni-codepen:before, .icon-codepen:before { content: "\ea95"; }
|
||||||
|
.lni-coffee-cup-2:before, .icon-coffee-cup-2:before { content: "\ea96"; }
|
||||||
|
.lni-coinbase:before, .icon-coinbase:before { content: "\ea97"; }
|
||||||
|
.lni-colour-palette-3:before, .icon-colour-palette-3:before { content: "\ea98"; }
|
||||||
|
.lni-comment-1:before, .icon-comment-1:before { content: "\ea99"; }
|
||||||
|
.lni-comment-1-share:before, .icon-comment-1-share:before { content: "\ea9a"; }
|
||||||
|
.lni-comment-1-text:before, .icon-comment-1-text:before { content: "\ea9b"; }
|
||||||
|
.lni-compass-drafting-2:before, .icon-compass-drafting-2:before { content: "\ea9c"; }
|
||||||
|
.lni-connectdevelop:before, .icon-connectdevelop:before { content: "\ea9d"; }
|
||||||
|
.lni-copilot:before, .icon-copilot:before { content: "\ea9e"; }
|
||||||
|
.lni-coral:before, .icon-coral:before { content: "\ea9f"; }
|
||||||
|
.lni-cpanel:before, .icon-cpanel:before { content: "\eaa0"; }
|
||||||
|
.lni-crane-4:before, .icon-crane-4:before { content: "\eaa1"; }
|
||||||
|
.lni-creative-commons:before, .icon-creative-commons:before { content: "\eaa2"; }
|
||||||
|
.lni-credit-card-multiple:before, .icon-credit-card-multiple:before { content: "\eaa3"; }
|
||||||
|
.lni-crop-2:before, .icon-crop-2:before { content: "\eaa4"; }
|
||||||
|
.lni-crown-3:before, .icon-crown-3:before { content: "\eaa5"; }
|
||||||
|
.lni-css3:before, .icon-css3:before { content: "\eaa6"; }
|
||||||
|
.lni-dashboard-square-1:before, .icon-dashboard-square-1:before { content: "\eaa7"; }
|
||||||
|
.lni-database-2:before, .icon-database-2:before { content: "\eaa8"; }
|
||||||
|
.lni-deno:before, .icon-deno:before { content: "\eaa9"; }
|
||||||
|
.lni-dev:before, .icon-dev:before { content: "\eaaa"; }
|
||||||
|
.lni-dialogflow:before, .icon-dialogflow:before { content: "\eaab"; }
|
||||||
|
.lni-diamonds-1:before, .icon-diamonds-1:before { content: "\eaac"; }
|
||||||
|
.lni-diamonds-2:before, .icon-diamonds-2:before { content: "\eaad"; }
|
||||||
|
.lni-digitalocean:before, .icon-digitalocean:before { content: "\eaae"; }
|
||||||
|
.lni-diners-club:before, .icon-diners-club:before { content: "\eaaf"; }
|
||||||
|
.lni-direction-ltr:before, .icon-direction-ltr:before { content: "\eab0"; }
|
||||||
|
.lni-direction-rtl:before, .icon-direction-rtl:before { content: "\eab1"; }
|
||||||
|
.lni-discord:before, .icon-discord:before { content: "\eab2"; }
|
||||||
|
.lni-discord-chat:before, .icon-discord-chat:before { content: "\eab3"; }
|
||||||
|
.lni-discover:before, .icon-discover:before { content: "\eab4"; }
|
||||||
|
.lni-docker:before, .icon-docker:before { content: "\eab5"; }
|
||||||
|
.lni-dollar:before, .icon-dollar:before { content: "\eab6"; }
|
||||||
|
.lni-dollar-circle:before, .icon-dollar-circle:before { content: "\eab7"; }
|
||||||
|
.lni-double-quotes-end-1:before, .icon-double-quotes-end-1:before { content: "\eab8"; }
|
||||||
|
.lni-download-1:before, .icon-download-1:before { content: "\eab9"; }
|
||||||
|
.lni-download-circle-1:before, .icon-download-circle-1:before { content: "\eaba"; }
|
||||||
|
.lni-dribbble:before, .icon-dribbble:before { content: "\eabb"; }
|
||||||
|
.lni-dribbble-symbol:before, .icon-dribbble-symbol:before { content: "\eabc"; }
|
||||||
|
.lni-drizzle:before, .icon-drizzle:before { content: "\eabd"; }
|
||||||
|
.lni-dropbox:before, .icon-dropbox:before { content: "\eabe"; }
|
||||||
|
.lni-drupal:before, .icon-drupal:before { content: "\eabf"; }
|
||||||
|
.lni-dumbbell-1:before, .icon-dumbbell-1:before { content: "\eac0"; }
|
||||||
|
.lni-edge:before, .icon-edge:before { content: "\eac1"; }
|
||||||
|
.lni-emoji-expressionless:before, .icon-emoji-expressionless:before { content: "\eac2"; }
|
||||||
|
.lni-emoji-expressionless-flat-eyes:before, .icon-emoji-expressionless-flat-eyes:before { content: "\eac3"; }
|
||||||
|
.lni-emoji-grin:before, .icon-emoji-grin:before { content: "\eac4"; }
|
||||||
|
.lni-emoji-sad:before, .icon-emoji-sad:before { content: "\eac5"; }
|
||||||
|
.lni-emoji-smile:before, .icon-emoji-smile:before { content: "\eac6"; }
|
||||||
|
.lni-emoji-smile-side:before, .icon-emoji-smile-side:before { content: "\eac7"; }
|
||||||
|
.lni-emoji-smile-sunglass:before, .icon-emoji-smile-sunglass:before { content: "\eac8"; }
|
||||||
|
.lni-emoji-smile-tongue:before, .icon-emoji-smile-tongue:before { content: "\eac9"; }
|
||||||
|
.lni-enter:before, .icon-enter:before { content: "\eaca"; }
|
||||||
|
.lni-enter-down:before, .icon-enter-down:before { content: "\eacb"; }
|
||||||
|
.lni-envato:before, .icon-envato:before { content: "\eacc"; }
|
||||||
|
.lni-envelope-1:before, .icon-envelope-1:before { content: "\eacd"; }
|
||||||
|
.lni-eraser-1:before, .icon-eraser-1:before { content: "\eace"; }
|
||||||
|
.lni-ethereum-logo:before, .icon-ethereum-logo:before { content: "\eacf"; }
|
||||||
|
.lni-euro:before, .icon-euro:before { content: "\ead0"; }
|
||||||
|
.lni-exit:before, .icon-exit:before { content: "\ead1"; }
|
||||||
|
.lni-exit-up:before, .icon-exit-up:before { content: "\ead2"; }
|
||||||
|
.lni-expand-arrow-1:before, .icon-expand-arrow-1:before { content: "\ead3"; }
|
||||||
|
.lni-expand-square-4:before, .icon-expand-square-4:before { content: "\ead4"; }
|
||||||
|
.lni-expressjs:before, .icon-expressjs:before { content: "\ead5"; }
|
||||||
|
.lni-eye:before, .icon-eye:before { content: "\ead6"; }
|
||||||
|
.lni-facebook:before, .icon-facebook:before { content: "\ead7"; }
|
||||||
|
.lni-facebook-messenger:before, .icon-facebook-messenger:before { content: "\ead8"; }
|
||||||
|
.lni-facebook-rounded:before, .icon-facebook-rounded:before { content: "\ead9"; }
|
||||||
|
.lni-facebook-square:before, .icon-facebook-square:before { content: "\eada"; }
|
||||||
|
.lni-facetime:before, .icon-facetime:before { content: "\eadb"; }
|
||||||
|
.lni-figma:before, .icon-figma:before { content: "\eadc"; }
|
||||||
|
.lni-file-format-zip:before, .icon-file-format-zip:before { content: "\eadd"; }
|
||||||
|
.lni-file-multiple:before, .icon-file-multiple:before { content: "\eade"; }
|
||||||
|
.lni-file-pencil:before, .icon-file-pencil:before { content: "\eadf"; }
|
||||||
|
.lni-file-plus-circle:before, .icon-file-plus-circle:before { content: "\eae0"; }
|
||||||
|
.lni-file-question:before, .icon-file-question:before { content: "\eae1"; }
|
||||||
|
.lni-file-xmark:before, .icon-file-xmark:before { content: "\eae2"; }
|
||||||
|
.lni-firebase:before, .icon-firebase:before { content: "\eae3"; }
|
||||||
|
.lni-firefox:before, .icon-firefox:before { content: "\eae4"; }
|
||||||
|
.lni-firework-rocket-4:before, .icon-firework-rocket-4:before { content: "\eae5"; }
|
||||||
|
.lni-fitbit:before, .icon-fitbit:before { content: "\eae6"; }
|
||||||
|
.lni-flag-1:before, .icon-flag-1:before { content: "\eae7"; }
|
||||||
|
.lni-flag-2:before, .icon-flag-2:before { content: "\eae8"; }
|
||||||
|
.lni-flickr:before, .icon-flickr:before { content: "\eae9"; }
|
||||||
|
.lni-floppy-disk-1:before, .icon-floppy-disk-1:before { content: "\eaea"; }
|
||||||
|
.lni-flower-2:before, .icon-flower-2:before { content: "\eaeb"; }
|
||||||
|
.lni-flutter:before, .icon-flutter:before { content: "\eaec"; }
|
||||||
|
.lni-folder-1:before, .icon-folder-1:before { content: "\eaed"; }
|
||||||
|
.lni-ford:before, .icon-ford:before { content: "\eaee"; }
|
||||||
|
.lni-framer:before, .icon-framer:before { content: "\eaef"; }
|
||||||
|
.lni-funnel-1:before, .icon-funnel-1:before { content: "\eaf0"; }
|
||||||
|
.lni-gallery:before, .icon-gallery:before { content: "\eaf1"; }
|
||||||
|
.lni-game-pad-modern-1:before, .icon-game-pad-modern-1:before { content: "\eaf2"; }
|
||||||
|
.lni-gatsby:before, .icon-gatsby:before { content: "\eaf3"; }
|
||||||
|
.lni-gauge-1:before, .icon-gauge-1:before { content: "\eaf4"; }
|
||||||
|
.lni-gear-1:before, .icon-gear-1:before { content: "\eaf5"; }
|
||||||
|
.lni-gears-3:before, .icon-gears-3:before { content: "\eaf6"; }
|
||||||
|
.lni-gemini:before, .icon-gemini:before { content: "\eaf7"; }
|
||||||
|
.lni-git:before, .icon-git:before { content: "\eaf8"; }
|
||||||
|
.lni-github:before, .icon-github:before { content: "\eaf9"; }
|
||||||
|
.lni-glass-juice-1:before, .icon-glass-juice-1:before { content: "\eafa"; }
|
||||||
|
.lni-globe-1:before, .icon-globe-1:before { content: "\eafb"; }
|
||||||
|
.lni-globe-stand:before, .icon-globe-stand:before { content: "\eafc"; }
|
||||||
|
.lni-go:before, .icon-go:before { content: "\eafd"; }
|
||||||
|
.lni-goodreads:before, .icon-goodreads:before { content: "\eafe"; }
|
||||||
|
.lni-google:before, .icon-google:before { content: "\eaff"; }
|
||||||
|
.lni-google-cloud:before, .icon-google-cloud:before { content: "\eb00"; }
|
||||||
|
.lni-google-drive:before, .icon-google-drive:before { content: "\eb01"; }
|
||||||
|
.lni-google-meet:before, .icon-google-meet:before { content: "\eb02"; }
|
||||||
|
.lni-google-pay:before, .icon-google-pay:before { content: "\eb03"; }
|
||||||
|
.lni-google-wallet:before, .icon-google-wallet:before { content: "\eb04"; }
|
||||||
|
.lni-graduation-cap-1:before, .icon-graduation-cap-1:before { content: "\eb05"; }
|
||||||
|
.lni-grammarly:before, .icon-grammarly:before { content: "\eb06"; }
|
||||||
|
.lni-hacker-news:before, .icon-hacker-news:before { content: "\eb07"; }
|
||||||
|
.lni-hammer-1:before, .icon-hammer-1:before { content: "\eb08"; }
|
||||||
|
.lni-hammer-2:before, .icon-hammer-2:before { content: "\eb09"; }
|
||||||
|
.lni-hand-mic:before, .icon-hand-mic:before { content: "\eb0a"; }
|
||||||
|
.lni-hand-shake:before, .icon-hand-shake:before { content: "\eb0b"; }
|
||||||
|
.lni-hand-stop:before, .icon-hand-stop:before { content: "\eb0c"; }
|
||||||
|
.lni-hand-taking-dollar:before, .icon-hand-taking-dollar:before { content: "\eb0d"; }
|
||||||
|
.lni-hand-taking-leaf-1:before, .icon-hand-taking-leaf-1:before { content: "\eb0e"; }
|
||||||
|
.lni-hand-taking-user:before, .icon-hand-taking-user:before { content: "\eb0f"; }
|
||||||
|
.lni-hashnode:before, .icon-hashnode:before { content: "\eb10"; }
|
||||||
|
.lni-hat-chef-3:before, .icon-hat-chef-3:before { content: "\eb11"; }
|
||||||
|
.lni-headphone-1:before, .icon-headphone-1:before { content: "\eb12"; }
|
||||||
|
.lni-heart:before, .icon-heart:before { content: "\eb13"; }
|
||||||
|
.lni-helicopter-2:before, .icon-helicopter-2:before { content: "\eb14"; }
|
||||||
|
.lni-helmet-safety-1:before, .icon-helmet-safety-1:before { content: "\eb15"; }
|
||||||
|
.lni-hierarchy-1:before, .icon-hierarchy-1:before { content: "\eb16"; }
|
||||||
|
.lni-highlighter-1:before, .icon-highlighter-1:before { content: "\eb17"; }
|
||||||
|
.lni-highlighter-2:before, .icon-highlighter-2:before { content: "\eb18"; }
|
||||||
|
.lni-home-2:before, .icon-home-2:before { content: "\eb19"; }
|
||||||
|
.lni-hospital-2:before, .icon-hospital-2:before { content: "\eb1a"; }
|
||||||
|
.lni-hourglass:before, .icon-hourglass:before { content: "\eb1b"; }
|
||||||
|
.lni-html5:before, .icon-html5:before { content: "\eb1c"; }
|
||||||
|
.lni-ibm:before, .icon-ibm:before { content: "\eb1d"; }
|
||||||
|
.lni-id-card:before, .icon-id-card:before { content: "\eb1e"; }
|
||||||
|
.lni-imdb:before, .icon-imdb:before { content: "\eb1f"; }
|
||||||
|
.lni-indent:before, .icon-indent:before { content: "\eb20"; }
|
||||||
|
.lni-info:before, .icon-info:before { content: "\eb21"; }
|
||||||
|
.lni-injection-1:before, .icon-injection-1:before { content: "\eb22"; }
|
||||||
|
.lni-instagram:before, .icon-instagram:before { content: "\eb23"; }
|
||||||
|
.lni-instagram-logotype:before, .icon-instagram-logotype:before { content: "\eb24"; }
|
||||||
|
.lni-intel:before, .icon-intel:before { content: "\eb25"; }
|
||||||
|
.lni-ios:before, .icon-ios:before { content: "\eb26"; }
|
||||||
|
.lni-island-2:before, .icon-island-2:before { content: "\eb27"; }
|
||||||
|
.lni-jaguar:before, .icon-jaguar:before { content: "\eb28"; }
|
||||||
|
.lni-jamstack:before, .icon-jamstack:before { content: "\eb29"; }
|
||||||
|
.lni-java:before, .icon-java:before { content: "\eb2a"; }
|
||||||
|
.lni-javascript:before, .icon-javascript:before { content: "\eb2b"; }
|
||||||
|
.lni-jcb:before, .icon-jcb:before { content: "\eb2c"; }
|
||||||
|
.lni-joomla:before, .icon-joomla:before { content: "\eb2d"; }
|
||||||
|
.lni-jsfiddle:before, .icon-jsfiddle:before { content: "\eb2e"; }
|
||||||
|
.lni-key-1:before, .icon-key-1:before { content: "\eb2f"; }
|
||||||
|
.lni-keyboard:before, .icon-keyboard:before { content: "\eb30"; }
|
||||||
|
.lni-knife-fork-1:before, .icon-knife-fork-1:before { content: "\eb31"; }
|
||||||
|
.lni-kubernetes:before, .icon-kubernetes:before { content: "\eb32"; }
|
||||||
|
.lni-label-dollar-2:before, .icon-label-dollar-2:before { content: "\eb33"; }
|
||||||
|
.lni-laptop-2:before, .icon-laptop-2:before { content: "\eb34"; }
|
||||||
|
.lni-laptop-phone:before, .icon-laptop-phone:before { content: "\eb35"; }
|
||||||
|
.lni-laravel:before, .icon-laravel:before { content: "\eb36"; }
|
||||||
|
.lni-layers-1:before, .icon-layers-1:before { content: "\eb37"; }
|
||||||
|
.lni-layout-26:before, .icon-layout-26:before { content: "\eb38"; }
|
||||||
|
.lni-layout-9:before, .icon-layout-9:before { content: "\eb39"; }
|
||||||
|
.lni-leaf-1:before, .icon-leaf-1:before { content: "\eb3a"; }
|
||||||
|
.lni-leaf-6:before, .icon-leaf-6:before { content: "\eb3b"; }
|
||||||
|
.lni-lemon-squeezy:before, .icon-lemon-squeezy:before { content: "\eb3c"; }
|
||||||
|
.lni-life-guard-tube-1:before, .icon-life-guard-tube-1:before { content: "\eb3d"; }
|
||||||
|
.lni-line:before, .icon-line:before { content: "\eb3e"; }
|
||||||
|
.lni-line-dashed:before, .icon-line-dashed:before { content: "\eb3f"; }
|
||||||
|
.lni-line-dotted:before, .icon-line-dotted:before { content: "\eb40"; }
|
||||||
|
.lni-line-height:before, .icon-line-height:before { content: "\eb41"; }
|
||||||
|
.lni-lineicons:before, .icon-lineicons:before { content: "\eb42"; }
|
||||||
|
.lni-link-2-angular-right:before, .icon-link-2-angular-right:before { content: "\eb43"; }
|
||||||
|
.lni-linkedin:before, .icon-linkedin:before { content: "\eb44"; }
|
||||||
|
.lni-location-arrow-right:before, .icon-location-arrow-right:before { content: "\eb45"; }
|
||||||
|
.lni-locked-1:before, .icon-locked-1:before { content: "\eb46"; }
|
||||||
|
.lni-locked-2:before, .icon-locked-2:before { content: "\eb47"; }
|
||||||
|
.lni-loom:before, .icon-loom:before { content: "\eb48"; }
|
||||||
|
.lni-magento:before, .icon-magento:before { content: "\eb49"; }
|
||||||
|
.lni-magnet:before, .icon-magnet:before { content: "\eb4a"; }
|
||||||
|
.lni-mailchimp:before, .icon-mailchimp:before { content: "\eb4b"; }
|
||||||
|
.lni-map-marker-1:before, .icon-map-marker-1:before { content: "\eb4c"; }
|
||||||
|
.lni-map-marker-5:before, .icon-map-marker-5:before { content: "\eb4d"; }
|
||||||
|
.lni-map-pin-5:before, .icon-map-pin-5:before { content: "\eb4e"; }
|
||||||
|
.lni-markdown:before, .icon-markdown:before { content: "\eb4f"; }
|
||||||
|
.lni-mastercard:before, .icon-mastercard:before { content: "\eb50"; }
|
||||||
|
.lni-medium:before, .icon-medium:before { content: "\eb51"; }
|
||||||
|
.lni-medium-alt:before, .icon-medium-alt:before { content: "\eb52"; }
|
||||||
|
.lni-megaphone-1:before, .icon-megaphone-1:before { content: "\eb53"; }
|
||||||
|
.lni-menu-cheesburger:before, .icon-menu-cheesburger:before { content: "\eb54"; }
|
||||||
|
.lni-menu-hamburger-1:before, .icon-menu-hamburger-1:before { content: "\eb55"; }
|
||||||
|
.lni-menu-meatballs-1:before, .icon-menu-meatballs-1:before { content: "\eb56"; }
|
||||||
|
.lni-menu-meatballs-2:before, .icon-menu-meatballs-2:before { content: "\eb57"; }
|
||||||
|
.lni-mercedes:before, .icon-mercedes:before { content: "\eb58"; }
|
||||||
|
.lni-message-2:before, .icon-message-2:before { content: "\eb59"; }
|
||||||
|
.lni-message-2-question:before, .icon-message-2-question:before { content: "\eb5a"; }
|
||||||
|
.lni-message-3-text:before, .icon-message-3-text:before { content: "\eb5b"; }
|
||||||
|
.lni-meta:before, .icon-meta:before { content: "\eb5c"; }
|
||||||
|
.lni-meta-alt:before, .icon-meta-alt:before { content: "\eb5d"; }
|
||||||
|
.lni-microphone-1:before, .icon-microphone-1:before { content: "\eb5e"; }
|
||||||
|
.lni-microscope:before, .icon-microscope:before { content: "\eb5f"; }
|
||||||
|
.lni-microsoft:before, .icon-microsoft:before { content: "\eb60"; }
|
||||||
|
.lni-microsoft-edge:before, .icon-microsoft-edge:before { content: "\eb61"; }
|
||||||
|
.lni-microsoft-teams:before, .icon-microsoft-teams:before { content: "\eb62"; }
|
||||||
|
.lni-minus:before, .icon-minus:before { content: "\eb63"; }
|
||||||
|
.lni-minus-circle:before, .icon-minus-circle:before { content: "\eb64"; }
|
||||||
|
.lni-mongodb:before, .icon-mongodb:before { content: "\eb65"; }
|
||||||
|
.lni-monitor:before, .icon-monitor:before { content: "\eb66"; }
|
||||||
|
.lni-monitor-code:before, .icon-monitor-code:before { content: "\eb67"; }
|
||||||
|
.lni-monitor-mac:before, .icon-monitor-mac:before { content: "\eb68"; }
|
||||||
|
.lni-moon-half-right-5:before, .icon-moon-half-right-5:before { content: "\eb69"; }
|
||||||
|
.lni-mountains-2:before, .icon-mountains-2:before { content: "\eb6a"; }
|
||||||
|
.lni-mouse-2:before, .icon-mouse-2:before { content: "\eb6b"; }
|
||||||
|
.lni-mushroom-1:before, .icon-mushroom-1:before { content: "\eb6c"; }
|
||||||
|
.lni-mushroom-5:before, .icon-mushroom-5:before { content: "\eb6d"; }
|
||||||
|
.lni-music:before, .icon-music:before { content: "\eb6e"; }
|
||||||
|
.lni-mysql:before, .icon-mysql:before { content: "\eb6f"; }
|
||||||
|
.lni-nasa:before, .icon-nasa:before { content: "\eb70"; }
|
||||||
|
.lni-netflix:before, .icon-netflix:before { content: "\eb71"; }
|
||||||
|
.lni-netlify:before, .icon-netlify:before { content: "\eb72"; }
|
||||||
|
.lni-next-step-2:before, .icon-next-step-2:before { content: "\eb73"; }
|
||||||
|
.lni-nextjs:before, .icon-nextjs:before { content: "\eb74"; }
|
||||||
|
.lni-nike:before, .icon-nike:before { content: "\eb75"; }
|
||||||
|
.lni-nissan:before, .icon-nissan:before { content: "\eb76"; }
|
||||||
|
.lni-nodejs:before, .icon-nodejs:before { content: "\eb77"; }
|
||||||
|
.lni-nodejs-alt:before, .icon-nodejs-alt:before { content: "\eb78"; }
|
||||||
|
.lni-notebook-1:before, .icon-notebook-1:before { content: "\eb79"; }
|
||||||
|
.lni-notion:before, .icon-notion:before { content: "\eb7a"; }
|
||||||
|
.lni-npm:before, .icon-npm:before { content: "\eb7b"; }
|
||||||
|
.lni-nuxt:before, .icon-nuxt:before { content: "\eb7c"; }
|
||||||
|
.lni-nvidia:before, .icon-nvidia:before { content: "\eb7d"; }
|
||||||
|
.lni-oculus:before, .icon-oculus:before { content: "\eb7e"; }
|
||||||
|
.lni-open-ai:before, .icon-open-ai:before { content: "\eb7f"; }
|
||||||
|
.lni-opera-mini:before, .icon-opera-mini:before { content: "\eb80"; }
|
||||||
|
.lni-oracle:before, .icon-oracle:before { content: "\eb81"; }
|
||||||
|
.lni-outdent:before, .icon-outdent:before { content: "\eb82"; }
|
||||||
|
.lni-paddle:before, .icon-paddle:before { content: "\eb83"; }
|
||||||
|
.lni-page-break-1:before, .icon-page-break-1:before { content: "\eb84"; }
|
||||||
|
.lni-pagination:before, .icon-pagination:before { content: "\eb85"; }
|
||||||
|
.lni-paint-bucket:before, .icon-paint-bucket:before { content: "\eb86"; }
|
||||||
|
.lni-paint-roller-1:before, .icon-paint-roller-1:before { content: "\eb87"; }
|
||||||
|
.lni-paperclip-1:before, .icon-paperclip-1:before { content: "\eb88"; }
|
||||||
|
.lni-party-flags:before, .icon-party-flags:before { content: "\eb89"; }
|
||||||
|
.lni-party-spray:before, .icon-party-spray:before { content: "\eb8a"; }
|
||||||
|
.lni-patreon:before, .icon-patreon:before { content: "\eb8b"; }
|
||||||
|
.lni-pause:before, .icon-pause:before { content: "\eb8c"; }
|
||||||
|
.lni-payoneer:before, .icon-payoneer:before { content: "\eb8d"; }
|
||||||
|
.lni-paypal:before, .icon-paypal:before { content: "\eb8e"; }
|
||||||
|
.lni-pen-to-square:before, .icon-pen-to-square:before { content: "\eb8f"; }
|
||||||
|
.lni-pencil-1:before, .icon-pencil-1:before { content: "\eb90"; }
|
||||||
|
.lni-pepsi:before, .icon-pepsi:before { content: "\eb91"; }
|
||||||
|
.lni-phone:before, .icon-phone:before { content: "\eb92"; }
|
||||||
|
.lni-photos:before, .icon-photos:before { content: "\eb93"; }
|
||||||
|
.lni-php:before, .icon-php:before { content: "\eb94"; }
|
||||||
|
.lni-pie-chart-2:before, .icon-pie-chart-2:before { content: "\eb95"; }
|
||||||
|
.lni-pilcrow:before, .icon-pilcrow:before { content: "\eb96"; }
|
||||||
|
.lni-pimjo-logo:before, .icon-pimjo-logo:before { content: "\eb97"; }
|
||||||
|
.lni-pimjo-symbol:before, .icon-pimjo-symbol:before { content: "\eb98"; }
|
||||||
|
.lni-pinterest:before, .icon-pinterest:before { content: "\eb99"; }
|
||||||
|
.lni-pizza-2:before, .icon-pizza-2:before { content: "\eb9a"; }
|
||||||
|
.lni-placeholder-dollar:before, .icon-placeholder-dollar:before { content: "\eb9b"; }
|
||||||
|
.lni-plantscale:before, .icon-plantscale:before { content: "\eb9c"; }
|
||||||
|
.lni-play:before, .icon-play:before { content: "\eb9d"; }
|
||||||
|
.lni-play-store:before, .icon-play-store:before { content: "\eb9e"; }
|
||||||
|
.lni-playstation:before, .icon-playstation:before { content: "\eb9f"; }
|
||||||
|
.lni-plug-1:before, .icon-plug-1:before { content: "\eba0"; }
|
||||||
|
.lni-plus:before, .icon-plus:before { content: "\eba1"; }
|
||||||
|
.lni-plus-circle:before, .icon-plus-circle:before { content: "\eba2"; }
|
||||||
|
.lni-pnpm:before, .icon-pnpm:before { content: "\eba3"; }
|
||||||
|
.lni-postgresql:before, .icon-postgresql:before { content: "\eba4"; }
|
||||||
|
.lni-postman:before, .icon-postman:before { content: "\eba5"; }
|
||||||
|
.lni-pound:before, .icon-pound:before { content: "\eba6"; }
|
||||||
|
.lni-power-button:before, .icon-power-button:before { content: "\eba7"; }
|
||||||
|
.lni-previous-step-2:before, .icon-previous-step-2:before { content: "\eba8"; }
|
||||||
|
.lni-printer:before, .icon-printer:before { content: "\eba9"; }
|
||||||
|
.lni-prisma:before, .icon-prisma:before { content: "\ebaa"; }
|
||||||
|
.lni-producthunt:before, .icon-producthunt:before { content: "\ebab"; }
|
||||||
|
.lni-proton-mail-logo:before, .icon-proton-mail-logo:before { content: "\ebac"; }
|
||||||
|
.lni-proton-mail-symbol:before, .icon-proton-mail-symbol:before { content: "\ebad"; }
|
||||||
|
.lni-python:before, .icon-python:before { content: "\ebae"; }
|
||||||
|
.lni-question-mark:before, .icon-question-mark:before { content: "\ebaf"; }
|
||||||
|
.lni-question-mark-circle:before, .icon-question-mark-circle:before { content: "\ebb0"; }
|
||||||
|
.lni-quora:before, .icon-quora:before { content: "\ebb1"; }
|
||||||
|
.lni-radis:before, .icon-radis:before { content: "\ebb2"; }
|
||||||
|
.lni-react:before, .icon-react:before { content: "\ebb3"; }
|
||||||
|
.lni-reddit:before, .icon-reddit:before { content: "\ebb4"; }
|
||||||
|
.lni-refresh-circle-1-clockwise:before, .icon-refresh-circle-1-clockwise:before { content: "\ebb5"; }
|
||||||
|
.lni-refresh-dollar-1:before, .icon-refresh-dollar-1:before { content: "\ebb6"; }
|
||||||
|
.lni-refresh-user-1:before, .icon-refresh-user-1:before { content: "\ebb7"; }
|
||||||
|
.lni-remix-js:before, .icon-remix-js:before { content: "\ebb8"; }
|
||||||
|
.lni-road-1:before, .icon-road-1:before { content: "\ebb9"; }
|
||||||
|
.lni-rocket-5:before, .icon-rocket-5:before { content: "\ebba"; }
|
||||||
|
.lni-route-1:before, .icon-route-1:before { content: "\ebbb"; }
|
||||||
|
.lni-rss-right:before, .icon-rss-right:before { content: "\ebbc"; }
|
||||||
|
.lni-ruler-1:before, .icon-ruler-1:before { content: "\ebbd"; }
|
||||||
|
.lni-ruler-pen:before, .icon-ruler-pen:before { content: "\ebbe"; }
|
||||||
|
.lni-rupee:before, .icon-rupee:before { content: "\ebbf"; }
|
||||||
|
.lni-safari:before, .icon-safari:before { content: "\ebc0"; }
|
||||||
|
.lni-sanity:before, .icon-sanity:before { content: "\ebc1"; }
|
||||||
|
.lni-school-bench-1:before, .icon-school-bench-1:before { content: "\ebc2"; }
|
||||||
|
.lni-school-bench-2:before, .icon-school-bench-2:before { content: "\ebc3"; }
|
||||||
|
.lni-scissors-1-vertical:before, .icon-scissors-1-vertical:before { content: "\ebc4"; }
|
||||||
|
.lni-scoter:before, .icon-scoter:before { content: "\ebc5"; }
|
||||||
|
.lni-scroll-down-2:before, .icon-scroll-down-2:before { content: "\ebc6"; }
|
||||||
|
.lni-search-1:before, .icon-search-1:before { content: "\ebc7"; }
|
||||||
|
.lni-search-2:before, .icon-search-2:before { content: "\ebc8"; }
|
||||||
|
.lni-search-minus:before, .icon-search-minus:before { content: "\ebc9"; }
|
||||||
|
.lni-search-plus:before, .icon-search-plus:before { content: "\ebca"; }
|
||||||
|
.lni-search-text:before, .icon-search-text:before { content: "\ebcb"; }
|
||||||
|
.lni-select-cursor-1:before, .icon-select-cursor-1:before { content: "\ebcc"; }
|
||||||
|
.lni-seo-monitor:before, .icon-seo-monitor:before { content: "\ebcd"; }
|
||||||
|
.lni-service-bell-1:before, .icon-service-bell-1:before { content: "\ebce"; }
|
||||||
|
.lni-share-1:before, .icon-share-1:before { content: "\ebcf"; }
|
||||||
|
.lni-share-1-circle:before, .icon-share-1-circle:before { content: "\ebd0"; }
|
||||||
|
.lni-share-2:before, .icon-share-2:before { content: "\ebd1"; }
|
||||||
|
.lni-shield-2:before, .icon-shield-2:before { content: "\ebd2"; }
|
||||||
|
.lni-shield-2-check:before, .icon-shield-2-check:before { content: "\ebd3"; }
|
||||||
|
.lni-shield-dollar:before, .icon-shield-dollar:before { content: "\ebd4"; }
|
||||||
|
.lni-shift-left:before, .icon-shift-left:before { content: "\ebd5"; }
|
||||||
|
.lni-shift-right:before, .icon-shift-right:before { content: "\ebd6"; }
|
||||||
|
.lni-ship-1:before, .icon-ship-1:before { content: "\ebd7"; }
|
||||||
|
.lni-shirt-1:before, .icon-shirt-1:before { content: "\ebd8"; }
|
||||||
|
.lni-shopify:before, .icon-shopify:before { content: "\ebd9"; }
|
||||||
|
.lni-shovel:before, .icon-shovel:before { content: "\ebda"; }
|
||||||
|
.lni-shuffle:before, .icon-shuffle:before { content: "\ebdb"; }
|
||||||
|
.lni-sign-post-left:before, .icon-sign-post-left:before { content: "\ebdc"; }
|
||||||
|
.lni-signal-app:before, .icon-signal-app:before { content: "\ebdd"; }
|
||||||
|
.lni-signs-post-2:before, .icon-signs-post-2:before { content: "\ebde"; }
|
||||||
|
.lni-sketch:before, .icon-sketch:before { content: "\ebdf"; }
|
||||||
|
.lni-skype:before, .icon-skype:before { content: "\ebe0"; }
|
||||||
|
.lni-slack:before, .icon-slack:before { content: "\ebe1"; }
|
||||||
|
.lni-slice-2:before, .icon-slice-2:before { content: "\ebe2"; }
|
||||||
|
.lni-sliders-horizontal-square-2:before, .icon-sliders-horizontal-square-2:before { content: "\ebe3"; }
|
||||||
|
.lni-slideshare:before, .icon-slideshare:before { content: "\ebe4"; }
|
||||||
|
.lni-snapchat:before, .icon-snapchat:before { content: "\ebe5"; }
|
||||||
|
.lni-sort-alphabetical:before, .icon-sort-alphabetical:before { content: "\ebe6"; }
|
||||||
|
.lni-sort-high-to-low:before, .icon-sort-high-to-low:before { content: "\ebe7"; }
|
||||||
|
.lni-soundcloud:before, .icon-soundcloud:before { content: "\ebe8"; }
|
||||||
|
.lni-spacex:before, .icon-spacex:before { content: "\ebe9"; }
|
||||||
|
.lni-spellcheck:before, .icon-spellcheck:before { content: "\ebea"; }
|
||||||
|
.lni-spinner-2-sacle:before, .icon-spinner-2-sacle:before { content: "\ebeb"; }
|
||||||
|
.lni-spinner-3:before, .icon-spinner-3:before { content: "\ebec"; }
|
||||||
|
.lni-sports:before, .icon-sports:before { content: "\ebed"; }
|
||||||
|
.lni-spotify:before, .icon-spotify:before { content: "\ebee"; }
|
||||||
|
.lni-spotify-alt:before, .icon-spotify-alt:before { content: "\ebef"; }
|
||||||
|
.lni-squarespace:before, .icon-squarespace:before { content: "\ebf0"; }
|
||||||
|
.lni-stackoverflow:before, .icon-stackoverflow:before { content: "\ebf1"; }
|
||||||
|
.lni-stamp:before, .icon-stamp:before { content: "\ebf2"; }
|
||||||
|
.lni-star-fat:before, .icon-star-fat:before { content: "\ebf3"; }
|
||||||
|
.lni-star-fat-half-2:before, .icon-star-fat-half-2:before { content: "\ebf4"; }
|
||||||
|
.lni-star-sharp-disabled:before, .icon-star-sharp-disabled:before { content: "\ebf5"; }
|
||||||
|
.lni-statista:before, .icon-statista:before { content: "\ebf6"; }
|
||||||
|
.lni-steam:before, .icon-steam:before { content: "\ebf7"; }
|
||||||
|
.lni-stethoscope-1:before, .icon-stethoscope-1:before { content: "\ebf8"; }
|
||||||
|
.lni-stopwatch:before, .icon-stopwatch:before { content: "\ebf9"; }
|
||||||
|
.lni-storage-hdd-2:before, .icon-storage-hdd-2:before { content: "\ebfa"; }
|
||||||
|
.lni-strikethrough-1:before, .icon-strikethrough-1:before { content: "\ebfb"; }
|
||||||
|
.lni-stripe:before, .icon-stripe:before { content: "\ebfc"; }
|
||||||
|
.lni-stumbleupon:before, .icon-stumbleupon:before { content: "\ebfd"; }
|
||||||
|
.lni-sun-1:before, .icon-sun-1:before { content: "\ebfe"; }
|
||||||
|
.lni-supabase:before, .icon-supabase:before { content: "\ebff"; }
|
||||||
|
.lni-surfboard-2:before, .icon-surfboard-2:before { content: "\ec00"; }
|
||||||
|
.lni-svelte:before, .icon-svelte:before { content: "\ec01"; }
|
||||||
|
.lni-swift:before, .icon-swift:before { content: "\ec02"; }
|
||||||
|
.lni-tab:before, .icon-tab:before { content: "\ec03"; }
|
||||||
|
.lni-tailwindcss:before, .icon-tailwindcss:before { content: "\ec04"; }
|
||||||
|
.lni-target-user:before, .icon-target-user:before { content: "\ec05"; }
|
||||||
|
.lni-telegram:before, .icon-telegram:before { content: "\ec06"; }
|
||||||
|
.lni-telephone-1:before, .icon-telephone-1:before { content: "\ec07"; }
|
||||||
|
.lni-telephone-3:before, .icon-telephone-3:before { content: "\ec08"; }
|
||||||
|
.lni-tesla:before, .icon-tesla:before { content: "\ec09"; }
|
||||||
|
.lni-text-format:before, .icon-text-format:before { content: "\ec0a"; }
|
||||||
|
.lni-text-format-remove:before, .icon-text-format-remove:before { content: "\ec0b"; }
|
||||||
|
.lni-text-paragraph:before, .icon-text-paragraph:before { content: "\ec0c"; }
|
||||||
|
.lni-thumbs-down-3:before, .icon-thumbs-down-3:before { content: "\ec0d"; }
|
||||||
|
.lni-thumbs-up-3:before, .icon-thumbs-up-3:before { content: "\ec0e"; }
|
||||||
|
.lni-ticket-1:before, .icon-ticket-1:before { content: "\ec0f"; }
|
||||||
|
.lni-tickets-3:before, .icon-tickets-3:before { content: "\ec10"; }
|
||||||
|
.lni-tiktok:before, .icon-tiktok:before { content: "\ec11"; }
|
||||||
|
.lni-tiktok-alt:before, .icon-tiktok-alt:before { content: "\ec12"; }
|
||||||
|
.lni-tower-broadcast-1:before, .icon-tower-broadcast-1:before { content: "\ec13"; }
|
||||||
|
.lni-toyota:before, .icon-toyota:before { content: "\ec14"; }
|
||||||
|
.lni-train-1:before, .icon-train-1:before { content: "\ec15"; }
|
||||||
|
.lni-train-3:before, .icon-train-3:before { content: "\ec16"; }
|
||||||
|
.lni-trash-3:before, .icon-trash-3:before { content: "\ec17"; }
|
||||||
|
.lni-tree-2:before, .icon-tree-2:before { content: "\ec18"; }
|
||||||
|
.lni-trees-3:before, .icon-trees-3:before { content: "\ec19"; }
|
||||||
|
.lni-trello:before, .icon-trello:before { content: "\ec1a"; }
|
||||||
|
.lni-trend-down-1:before, .icon-trend-down-1:before { content: "\ec1b"; }
|
||||||
|
.lni-trend-up-1:before, .icon-trend-up-1:before { content: "\ec1c"; }
|
||||||
|
.lni-trophy-1:before, .icon-trophy-1:before { content: "\ec1d"; }
|
||||||
|
.lni-trowel-1:before, .icon-trowel-1:before { content: "\ec1e"; }
|
||||||
|
.lni-truck-delivery-1:before, .icon-truck-delivery-1:before { content: "\ec1f"; }
|
||||||
|
.lni-tumblr:before, .icon-tumblr:before { content: "\ec20"; }
|
||||||
|
.lni-turborepo:before, .icon-turborepo:before { content: "\ec21"; }
|
||||||
|
.lni-twitch:before, .icon-twitch:before { content: "\ec22"; }
|
||||||
|
.lni-twitter-old:before, .icon-twitter-old:before { content: "\ec23"; }
|
||||||
|
.lni-typescript:before, .icon-typescript:before { content: "\ec24"; }
|
||||||
|
.lni-uber:before, .icon-uber:before { content: "\ec25"; }
|
||||||
|
.lni-uber-symbol:before, .icon-uber-symbol:before { content: "\ec26"; }
|
||||||
|
.lni-ubuntu:before, .icon-ubuntu:before { content: "\ec27"; }
|
||||||
|
.lni-underline:before, .icon-underline:before { content: "\ec28"; }
|
||||||
|
.lni-unlink-2-angular-eft:before, .icon-unlink-2-angular-eft:before { content: "\ec29"; }
|
||||||
|
.lni-unlocked-2:before, .icon-unlocked-2:before { content: "\ec2a"; }
|
||||||
|
.lni-unsplash:before, .icon-unsplash:before { content: "\ec2b"; }
|
||||||
|
.lni-upload-1:before, .icon-upload-1:before { content: "\ec2c"; }
|
||||||
|
.lni-upload-circle-1:before, .icon-upload-circle-1:before { content: "\ec2d"; }
|
||||||
|
.lni-user-4:before, .icon-user-4:before { content: "\ec2e"; }
|
||||||
|
.lni-user-multiple-4:before, .icon-user-multiple-4:before { content: "\ec2f"; }
|
||||||
|
.lni-vector-nodes-6:before, .icon-vector-nodes-6:before { content: "\ec30"; }
|
||||||
|
.lni-vector-nodes-7:before, .icon-vector-nodes-7:before { content: "\ec31"; }
|
||||||
|
.lni-vercel:before, .icon-vercel:before { content: "\ec32"; }
|
||||||
|
.lni-vimeo:before, .icon-vimeo:before { content: "\ec33"; }
|
||||||
|
.lni-visa:before, .icon-visa:before { content: "\ec34"; }
|
||||||
|
.lni-vite:before, .icon-vite:before { content: "\ec35"; }
|
||||||
|
.lni-vk:before, .icon-vk:before { content: "\ec36"; }
|
||||||
|
.lni-vmware:before, .icon-vmware:before { content: "\ec37"; }
|
||||||
|
.lni-volkswagen:before, .icon-volkswagen:before { content: "\ec38"; }
|
||||||
|
.lni-volume-1:before, .icon-volume-1:before { content: "\ec39"; }
|
||||||
|
.lni-volume-high:before, .icon-volume-high:before { content: "\ec3a"; }
|
||||||
|
.lni-volume-low:before, .icon-volume-low:before { content: "\ec3b"; }
|
||||||
|
.lni-volume-mute:before, .icon-volume-mute:before { content: "\ec3c"; }
|
||||||
|
.lni-volume-off:before, .icon-volume-off:before { content: "\ec3d"; }
|
||||||
|
.lni-vs-code:before, .icon-vs-code:before { content: "\ec3e"; }
|
||||||
|
.lni-vuejs:before, .icon-vuejs:before { content: "\ec3f"; }
|
||||||
|
.lni-wallet-1:before, .icon-wallet-1:before { content: "\ec40"; }
|
||||||
|
.lni-watch-beat-1:before, .icon-watch-beat-1:before { content: "\ec41"; }
|
||||||
|
.lni-water-drop-1:before, .icon-water-drop-1:before { content: "\ec42"; }
|
||||||
|
.lni-webflow:before, .icon-webflow:before { content: "\ec43"; }
|
||||||
|
.lni-webhooks:before, .icon-webhooks:before { content: "\ec44"; }
|
||||||
|
.lni-wechat:before, .icon-wechat:before { content: "\ec45"; }
|
||||||
|
.lni-weight-machine-1:before, .icon-weight-machine-1:before { content: "\ec46"; }
|
||||||
|
.lni-whatsapp:before, .icon-whatsapp:before { content: "\ec47"; }
|
||||||
|
.lni-wheelbarrow-empty:before, .icon-wheelbarrow-empty:before { content: "\ec48"; }
|
||||||
|
.lni-wheelchair-1:before, .icon-wheelchair-1:before { content: "\ec49"; }
|
||||||
|
.lni-windows:before, .icon-windows:before { content: "\ec4a"; }
|
||||||
|
.lni-wise:before, .icon-wise:before { content: "\ec4b"; }
|
||||||
|
.lni-wordpress:before, .icon-wordpress:before { content: "\ec4c"; }
|
||||||
|
.lni-www:before, .icon-www:before { content: "\ec4d"; }
|
||||||
|
.lni-www-cursor:before, .icon-www-cursor:before { content: "\ec4e"; }
|
||||||
|
.lni-x:before, .icon-x:before { content: "\ec4f"; }
|
||||||
|
.lni-xampp:before, .icon-xampp:before { content: "\ec50"; }
|
||||||
|
.lni-xbox:before, .icon-xbox:before { content: "\ec51"; }
|
||||||
|
.lni-xmark:before, .icon-xmark:before { content: "\ec52"; }
|
||||||
|
.lni-xmark-circle:before, .icon-xmark-circle:before { content: "\ec53"; }
|
||||||
|
.lni-xrp:before, .icon-xrp:before { content: "\ec54"; }
|
||||||
|
.lni-yahoo:before, .icon-yahoo:before { content: "\ec55"; }
|
||||||
|
.lni-yarn:before, .icon-yarn:before { content: "\ec56"; }
|
||||||
|
.lni-ycombinator:before, .icon-ycombinator:before { content: "\ec57"; }
|
||||||
|
.lni-yen:before, .icon-yen:before { content: "\ec58"; }
|
||||||
|
.lni-youtube:before, .icon-youtube:before { content: "\ec59"; }
|
||||||
|
.lni-youtube-kids:before, .icon-youtube-kids:before { content: "\ec5a"; }
|
||||||
|
.lni-youtube-music:before, .icon-youtube-music:before { content: "\ec5b"; }
|
||||||
|
.lni-zapier:before, .icon-zapier:before { content: "\ec5c"; }
|
||||||
|
.lni-zero-size:before, .icon-zero-size:before { content: "\ec5d"; }
|
||||||
|
.lni-zoom:before, .icon-zoom:before { content: "\ec5e"; }
|
||||||
|
|
||||||
|
.icon-chevron-right-after {
|
||||||
|
align-items: flex-start;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
line-height: 1;
|
||||||
|
margin-top: 0;
|
||||||
|
padding-top: 0;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: "\ea7d";
|
||||||
|
margin-top: .25rem;
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* Navigation component
|
||||||
|
* A composite component consisting of
|
||||||
|
* following components:
|
||||||
|
* - nav-main-mega.php
|
||||||
|
* - menu-items
|
||||||
|
* - index.php
|
||||||
|
* - nav-functional.php
|
||||||
|
*
|
||||||
|
* Desktop Navigation Styles:
|
||||||
|
* Choose one or the other for the main navigation, based on theme needs.
|
||||||
|
* @import 'nav-main-default'; (standard dropdown)
|
||||||
|
* @import 'nav-main-mega'; (mega menu style)
|
||||||
|
*
|
||||||
|
* Mobile Navigation Styles:
|
||||||
|
* Choose one for mobile navigation behavior:
|
||||||
|
* @import 'nav-mobile-accordion'; (traditional dropdown/accordion style)
|
||||||
|
* @import 'nav-mobile-sliding'; (sliding viewport style)
|
||||||
|
*/
|
||||||
|
|
||||||
|
@import "./nav-functional.css";
|
||||||
|
@import "./nav-aux.css";
|
||||||
|
|
||||||
|
/* Mobile Navigation Style - Choose one of the following: */
|
||||||
|
/* Traditional dropdown style */
|
||||||
|
@import "./nav-main-default.css";
|
||||||
|
/* Mega menu style */
|
||||||
|
/* @import "./nav-main-mega.css"; */
|
||||||
|
|
||||||
|
/* Mobile Navigation Style - Choose one of the following: */
|
||||||
|
/* Accordion/dropdown style */
|
||||||
|
/* @import "./nav-mobile-accordion.css"; */
|
||||||
|
/* Sliding viewport style */
|
||||||
|
@import "./nav-mobile-sliding.css";
|
||||||
|
|
||||||
|
@import "./nav-footer.css";
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* VDI Navs & Menu - Auxiliary Nav Styles
|
||||||
|
*
|
||||||
|
* Please review documentation upon first use, and, as-needed:
|
||||||
|
* https://docs.vincentdevelopment.ca/docs/starter-v3-enhancements/navigation/
|
||||||
|
*/
|
||||||
|
|
||||||
|
.nav-aux {
|
||||||
|
@apply relative flex flex-wrap gap-2 items-center justify-end p-0 m-0;
|
||||||
|
|
||||||
|
.menu-vdi {
|
||||||
|
@apply relative flex flex-wrap gap-4 items-center gap-y-2 gap-x-4 p-0 m-0;
|
||||||
|
|
||||||
|
.menu-vdi__toggle {
|
||||||
|
/* styles */
|
||||||
|
@apply flex items-center gap-2;
|
||||||
|
/* interaction */
|
||||||
|
@apply focus-visible:underline hover:underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* desktop overrides */
|
||||||
|
@media screen and (min-width: 62.5rem) {
|
||||||
|
.nav-aux {
|
||||||
|
@apply gap-4;
|
||||||
|
|
||||||
|
.menu-vdi {
|
||||||
|
@apply justify-end;
|
||||||
|
|
||||||
|
.menu-vdi__toggle {
|
||||||
|
@apply flex items-center gap-2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
/**
|
||||||
|
* VDI Navs & Menu - Footer Navigation
|
||||||
|
*
|
||||||
|
* Please review documentation upon first use, and, as-needed:
|
||||||
|
* ___Link_Here___
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* desktop */
|
||||||
|
@media screen and (min-width: 62.5rem) {
|
||||||
|
.nav-footer .menu-vdi {
|
||||||
|
@apply flex flex-col items-start justify-start p-0 m-0;
|
||||||
|
|
||||||
|
>li {
|
||||||
|
>a {
|
||||||
|
/* text */
|
||||||
|
@apply font-normal leading-snug text-secondary text-18px;
|
||||||
|
/* spacing & display */
|
||||||
|
@apply mx-0 p-0 no-underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mobile */
|
||||||
|
@media screen and (max-width: 62.5rem) {
|
||||||
|
.nav-footer {
|
||||||
|
.nav-footer__toggle {
|
||||||
|
/* display */
|
||||||
|
@apply text-primary p-3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-vdi {
|
||||||
|
@apply flex-col w-[95%] py-6;
|
||||||
|
|
||||||
|
.menu-vdi__submenu {
|
||||||
|
@apply py-2 px-7 flex-col;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-vdi__item {
|
||||||
|
a,
|
||||||
|
button {
|
||||||
|
/* text */
|
||||||
|
@apply font-normal leading-snug text-lg;
|
||||||
|
/* spacing & display */
|
||||||
|
@apply block w-full p-4;
|
||||||
|
/* interaction */
|
||||||
|
@apply focus-visible:bg-secondary-200 hover:bg-secondary-200;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
@apply block w-full;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
@apply flex w-full justify-between;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 62.5rem) {
|
||||||
|
.nav-footer .menu-vdi {
|
||||||
|
.menu-vdi__toggle {
|
||||||
|
@apply font-semibold underline text-20px mt-3 pb-1;
|
||||||
|
|
||||||
|
>svg {
|
||||||
|
@apply hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-vdi__item--parent {
|
||||||
|
@apply static;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-vdi__submenu {
|
||||||
|
@apply static block m-0 mb-3 p-0 pl-2 shadow-none;
|
||||||
|
|
||||||
|
>li {
|
||||||
|
@apply w-full m-0 p-0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-vdi__item {
|
||||||
|
/* text */
|
||||||
|
@apply font-normal leading-snug text-18px;
|
||||||
|
/* spacing & display */
|
||||||
|
@apply block w-full;
|
||||||
|
/* interaction */
|
||||||
|
@apply focus-visible:bg-secondary-200 hover:bg-secondary-200;
|
||||||
|
|
||||||
|
a {
|
||||||
|
@apply block w-full;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a.menu-vdi__item,
|
||||||
|
.menu-vdi__item a {
|
||||||
|
@apply p-0 text-secondary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
/**
|
||||||
|
* VDI Navs & Menu - Functional Styles
|
||||||
|
*
|
||||||
|
* Please review documentation upon first use, and, as-needed:
|
||||||
|
* https://docs.vincentdevelopment.ca/docs/starter-v3-enhancements/navigation/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* all sizes */
|
||||||
|
.menu-vdi {
|
||||||
|
@apply hidden;
|
||||||
|
|
||||||
|
>li {
|
||||||
|
@apply list-none;
|
||||||
|
>a {
|
||||||
|
@apply focus-visible:underline hover:underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
a[aria-current="true"] {
|
||||||
|
@apply underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-vdi__toggle {
|
||||||
|
&[aria-expanded="true"] {
|
||||||
|
svg {
|
||||||
|
@apply rotate-180;
|
||||||
|
}
|
||||||
|
|
||||||
|
+.menu-vdi__submenu {
|
||||||
|
@apply flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-vdi__submenu {
|
||||||
|
@apply hidden container z-10;
|
||||||
|
|
||||||
|
/* should also put current page here */
|
||||||
|
.menu-vdi__item--grandchild a {
|
||||||
|
@apply no-underline focus-visible:underline hover:underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mobile */
|
||||||
|
@media screen and (max-width: 62.5rem) {
|
||||||
|
#app:has(.nav-main__toggle[aria-expanded="true"]) { height: calc(100vh - var(--hgtHeader)); }
|
||||||
|
|
||||||
|
.nav-main__toggle {
|
||||||
|
.nav-toggle-hamburger { display: inline-block !important; }
|
||||||
|
|
||||||
|
.nav-toggle-x { display: none !important; }
|
||||||
|
|
||||||
|
&[aria-expanded="true"] {
|
||||||
|
.nav-toggle-hamburger { display: none !important; }
|
||||||
|
|
||||||
|
.nav-toggle-x { display: inline-block !important; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.nav-main {
|
||||||
|
.nav-main__toggle[aria-expanded="true"] {
|
||||||
|
+ul {
|
||||||
|
@apply absolute flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-vdi {
|
||||||
|
@apply absolute right-0 z-10;
|
||||||
|
|
||||||
|
.menu-vdi__toggle {
|
||||||
|
@apply flex items-center gap-2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-aux {
|
||||||
|
.menu-vdi__submenu {
|
||||||
|
@apply absolute list-none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Desktop */
|
||||||
|
@media screen and (min-width: 62.5rem) {
|
||||||
|
.nav-main__toggle {
|
||||||
|
@apply hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-vdi {
|
||||||
|
@apply flex list-none;
|
||||||
|
|
||||||
|
.menu-vdi__toggle {
|
||||||
|
@apply flex items-center gap-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-vdi__submenu {
|
||||||
|
@apply absolute list-none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/**
|
||||||
|
* VDI Navs & Menu - Main Navigation + Default Dropdown Menu Styles (Desktop Only)
|
||||||
|
*
|
||||||
|
* This file contains only desktop navigation styles.
|
||||||
|
* For mobile navigation, choose one of:
|
||||||
|
* - nav-mobile-accordion.css (traditional dropdown/accordion style)
|
||||||
|
* - nav-mobile-sliding.css (sliding viewport style)
|
||||||
|
*
|
||||||
|
* Please review documentation upon first use, and, as-needed:
|
||||||
|
* TODO: Add documenation link here
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* desktop */
|
||||||
|
@media screen and (min-width: 62.5rem) {
|
||||||
|
.nav-main .menu-vdi {
|
||||||
|
@apply flex items-center justify-end p-0 m-0;
|
||||||
|
|
||||||
|
>li {
|
||||||
|
>a,
|
||||||
|
>.menu-vdi__toggle {
|
||||||
|
/* text*/
|
||||||
|
@apply font-bold text-20px text-black hover:text-light no-underline leading-snug;
|
||||||
|
/* spacing & display */
|
||||||
|
@apply mx-4 p-0 no-underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 62.5rem) {
|
||||||
|
.menu-vdi {
|
||||||
|
.menu-vdi__toggle {
|
||||||
|
@apply flex items-center gap-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-vdi__item--parent {
|
||||||
|
@apply relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-vdi__submenu {
|
||||||
|
@apply bg-white shadow-lg left-4 w-64 flex-col;
|
||||||
|
top: calc(100% + 1rem);
|
||||||
|
|
||||||
|
>li {
|
||||||
|
@apply w-full;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-vdi__item {
|
||||||
|
/* text */
|
||||||
|
@apply font-bold text-18px text-black hover:text-light no-underline leading-snug;
|
||||||
|
/* spacing & display */
|
||||||
|
@apply block w-full;
|
||||||
|
/* interaction */
|
||||||
|
@apply focus-visible:bg-secondary-200 hover:bg-secondary-200;
|
||||||
|
|
||||||
|
a {
|
||||||
|
@apply block w-full;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a.menu-vdi__item,
|
||||||
|
.menu-vdi__item a {
|
||||||
|
@apply p-4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
/**
|
||||||
|
* VDI Navs & Menu - Main Navigation + Mega Menu Styles
|
||||||
|
*
|
||||||
|
* Please review documentation upon first use, and, as-needed:
|
||||||
|
* https://docs.vincentdevelopment.ca/docs/starter-v3-enhancements/navigation/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* all sizes */
|
||||||
|
.nav-main .menu-vdi {
|
||||||
|
.menu-vdi__toggle {
|
||||||
|
@apply flex items-center gap-2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mobile */
|
||||||
|
@media screen and (max-width: 62.5rem) {
|
||||||
|
.nav-main {
|
||||||
|
.nav-main__toggle {
|
||||||
|
/* display */
|
||||||
|
@apply text-white p-3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-vdi {
|
||||||
|
@apply flex-col bg-white w-[95%] right-0 z-10 py-6;
|
||||||
|
top: var(--hgtHeader);
|
||||||
|
min-height: calc(100vh - var(--hgtHeader));
|
||||||
|
|
||||||
|
.menu-vdi__submenu {
|
||||||
|
@apply py-2 px-7 flex-col;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-vdi__item {
|
||||||
|
a,
|
||||||
|
button {
|
||||||
|
/* text */
|
||||||
|
@apply font-bold text-20px text-black hover:text-light no-underline leading-snug;
|
||||||
|
/* spacing & display */
|
||||||
|
@apply block w-full p-4;
|
||||||
|
/* interaction */
|
||||||
|
@apply focus-visible:bg-secondary-200 hover:bg-secondary-200;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
@apply block w-full;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
@apply flex w-full justify-between;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* desktop */
|
||||||
|
@media screen and (min-width: 62.5rem) {
|
||||||
|
.nav-main .menu-vdi {
|
||||||
|
@apply flex items-center justify-end p-0 m-0;
|
||||||
|
|
||||||
|
>li {
|
||||||
|
>a,
|
||||||
|
>.menu-vdi__toggle {
|
||||||
|
/* text */
|
||||||
|
@apply font-bold text-20px text-black hover:text-light no-underline leading-snug;
|
||||||
|
/* spacing & display */
|
||||||
|
@apply w-max mx-4 p-0 no-underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-vdi__toggle {
|
||||||
|
@apply flex items-center gap-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-vdi__item--parent {
|
||||||
|
@apply relative;
|
||||||
|
|
||||||
|
/* Mega Menu */
|
||||||
|
&:has(.menu-vdi__item--grandchild) {
|
||||||
|
@apply static;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-vdi__submenu {
|
||||||
|
@apply bg-white shadow-lg left-4 w-64 flex-col;
|
||||||
|
|
||||||
|
top: calc(100% + 1rem);
|
||||||
|
|
||||||
|
>li {
|
||||||
|
@apply w-full;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-vdi__item {
|
||||||
|
/* text */
|
||||||
|
@apply font-bold text-18px text-black hover:text-light no-underline leading-snug;
|
||||||
|
/* spacing & display */
|
||||||
|
@apply block w-full;
|
||||||
|
/* interaction */
|
||||||
|
@apply focus-visible:bg-secondary-200 hover:bg-secondary-200;
|
||||||
|
|
||||||
|
a {
|
||||||
|
@apply block w-max;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a.menu-vdi__item,
|
||||||
|
.menu-vdi__item a {
|
||||||
|
@apply p-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mega Menu */
|
||||||
|
&:has(.menu-vdi__item--grandchild) {
|
||||||
|
@apply flex-row gap-x-8 right-0 ml-auto mr-0 p-4 w-max;
|
||||||
|
|
||||||
|
span {
|
||||||
|
@apply font-bold text-xl underline w-max;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.menu-vdi__item,
|
||||||
|
.menu-vdi__item a {
|
||||||
|
@apply p-0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-vdi__megaCol {
|
||||||
|
@apply px-0 w-max;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* VDI Navs & Menu - Mobile Accordion Navigation
|
||||||
|
*
|
||||||
|
* Traditional mobile accordion/dropdown style navigation
|
||||||
|
* Include this file for accordion-style mobile navigation
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Mobile accordion navigation */
|
||||||
|
@media screen and (max-width: 62.5rem) {
|
||||||
|
.nav-main {
|
||||||
|
.nav-main__toggle {
|
||||||
|
/* display */
|
||||||
|
@apply text-white p-3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-vdi {
|
||||||
|
@apply flex-col bg-white w-[95%] right-0 z-10 py-6;
|
||||||
|
@apply absolute hidden; /* Hidden by default */
|
||||||
|
top: var(--hgtHeader);
|
||||||
|
min-height: calc(100vh - var(--hgtHeader));
|
||||||
|
|
||||||
|
.menu-vdi__submenu {
|
||||||
|
@apply py-2 px-7 flex-col;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-vdi__item {
|
||||||
|
a,
|
||||||
|
button {
|
||||||
|
/* text */
|
||||||
|
@apply font-bold text-20px text-black hover:text-light no-underline leading-snug;
|
||||||
|
/* spacing & display */
|
||||||
|
@apply block w-full p-4;
|
||||||
|
/* interaction */
|
||||||
|
@apply focus-visible:bg-secondary-200 hover:bg-secondary-200;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
@apply block w-full;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
@apply flex w-full justify-between;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Show menu when toggle button is expanded */
|
||||||
|
.nav-main__toggle[aria-expanded="true"] ~ .menu-vdi:not(.menu-vdi--sliding) {
|
||||||
|
@apply !flex; /* Use !important to override hidden */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
/**
|
||||||
|
* VDI Navs & Menu - Mobile Sliding Viewport Navigation
|
||||||
|
*
|
||||||
|
* Sliding viewport style for mobile navigation where
|
||||||
|
* users can navigate through menu levels by sliding between views
|
||||||
|
* Include this file for sliding-style mobile navigation
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Mobile sliding viewport navigation */
|
||||||
|
@media screen and (max-width: 62.5rem) {
|
||||||
|
.nav-main {
|
||||||
|
.nav-main__toggle {
|
||||||
|
/* display */
|
||||||
|
@apply text-white p-3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-vdi--sliding {
|
||||||
|
@apply relative overflow-hidden bg-white w-[95%] right-0 z-10 py-6;
|
||||||
|
@apply absolute hidden; /* Hidden by default */
|
||||||
|
top: var(--hgtHeader);
|
||||||
|
min-height: calc(100vh - var(--hgtHeader));
|
||||||
|
|
||||||
|
/* Container for all navigation levels */
|
||||||
|
.menu-vdi__viewport {
|
||||||
|
@apply flex transition-transform duration-300 ease-in-out;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Each navigation level */
|
||||||
|
.menu-vdi__level {
|
||||||
|
@apply w-full flex-shrink-0 flex-col;
|
||||||
|
min-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Back button for secondary levels */
|
||||||
|
.menu-vdi__back {
|
||||||
|
@apply flex items-center gap-2 p-4 border-b border-gray-200 font-bold text-black hover:bg-secondary-200 focus-visible:bg-secondary-200 cursor-pointer;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
@apply w-5 h-5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Level indicator for context */
|
||||||
|
.menu-vdi__level-title {
|
||||||
|
@apply p-4 border-b border-gray-200 font-bold text-lg text-center bg-gray-50;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Navigation items in sliding mode */
|
||||||
|
.menu-vdi__item {
|
||||||
|
a,
|
||||||
|
button {
|
||||||
|
/* text */
|
||||||
|
@apply font-bold text-20px text-black hover:text-light no-underline leading-snug;
|
||||||
|
/* spacing & display */
|
||||||
|
@apply block w-full p-4;
|
||||||
|
/* interaction */
|
||||||
|
@apply focus-visible:bg-secondary-200 hover:bg-secondary-200;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
@apply block w-full;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
@apply flex w-full justify-between items-center;
|
||||||
|
|
||||||
|
/* Arrow indicator for items with children */
|
||||||
|
svg {
|
||||||
|
@apply w-5 h-5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide submenu toggles in sliding mode as they become navigation buttons */
|
||||||
|
.menu-vdi__toggle {
|
||||||
|
/* Override the accordion toggle behavior */
|
||||||
|
&[aria-expanded="true"] {
|
||||||
|
svg {
|
||||||
|
@apply rotate-0; /* Don't rotate arrow */
|
||||||
|
}
|
||||||
|
|
||||||
|
+.menu-vdi__submenu {
|
||||||
|
@apply hidden; /* Don't show dropdown */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide traditional submenus in sliding mode */
|
||||||
|
.menu-vdi__submenu {
|
||||||
|
@apply hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure menu items in sliding viewport have proper styling */
|
||||||
|
.menu-vdi__level-items {
|
||||||
|
@apply flex-col;
|
||||||
|
|
||||||
|
.menu-vdi__item {
|
||||||
|
@apply w-full;
|
||||||
|
|
||||||
|
a {
|
||||||
|
@apply p-4 block w-full no-underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
@apply p-4 block w-full font-bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style nested items that were converted from submenus */
|
||||||
|
.menu-vdi__nested-items {
|
||||||
|
@apply block;
|
||||||
|
|
||||||
|
.menu-vdi__item {
|
||||||
|
@apply w-full;
|
||||||
|
|
||||||
|
a {
|
||||||
|
@apply p-4 pl-8 block w-full no-underline; /* Add indent for nested items */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Show sliding menu when toggle button is expanded and menu has sliding class */
|
||||||
|
.nav-main__toggle[aria-expanded="true"] + .menu-vdi--sliding {
|
||||||
|
@apply !block; /* Use !important to override hidden */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/* Tailwind setup */
|
||||||
|
|
||||||
|
@import "tailwindcss";
|
||||||
|
|
||||||
|
/* Base styles */
|
||||||
|
@import "./base/index.css";
|
||||||
|
@import "./navigation/index.css";
|
||||||
|
|
||||||
|
/* Lineicons icon font */
|
||||||
|
@import "./fonts/lineicons.css";
|
||||||
|
|
||||||
|
/* Import *-break-out utilities (replicating the non-functional "tailwind-container-break-out" plugin) */
|
||||||
|
@import "./base/break-out.css";
|
||||||
|
|
||||||
|
/* Components */
|
||||||
|
@import "./components/index.css";
|
||||||
|
|
||||||
|
/* Blocks */
|
||||||
|
@import "./blocks/index.css";
|
||||||
|
|
||||||
|
/* Import Tailwind typography plugin */
|
||||||
|
@plugin "@tailwindcss/typography";
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
const { test, expect } = require('@playwright/test');
|
||||||
|
const AxeBuilder = require('@axe-core/playwright').default;
|
||||||
|
|
||||||
|
const domain = 'http://domain.local/';
|
||||||
|
test.use({
|
||||||
|
viewport: { width: 1920, height: 1080 },
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe('site-test', () => {
|
||||||
|
test('Homepage Test', async ({ page }, testInfo) => {
|
||||||
|
await page.goto(domain);
|
||||||
|
|
||||||
|
await page.screenshot({ path: 'test-results/homepage.png', fullPage: true });
|
||||||
|
|
||||||
|
const accessibilityScanResults = await new AxeBuilder({ page })
|
||||||
|
.withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'wcag22a', 'wcag22aa'])
|
||||||
|
.analyze();
|
||||||
|
|
||||||
|
await testInfo.attach('accessibility-scan-results', {
|
||||||
|
body: JSON.stringify(accessibilityScanResults, null, 2),
|
||||||
|
contentType: 'application/json'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(accessibilityScanResults.violations).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Blog Index Page Test', async ({ page }, testInfo) => {
|
||||||
|
await page.goto(`${domain}news/`);
|
||||||
|
|
||||||
|
await page.screenshot({ path: 'test-results/blog-index.png', fullPage: true });
|
||||||
|
|
||||||
|
const accessibilityScanResults = await new AxeBuilder({ page })
|
||||||
|
.withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'wcag22a', 'wcag22aa'])
|
||||||
|
.analyze();
|
||||||
|
|
||||||
|
await testInfo.attach('accessibility-scan-results', {
|
||||||
|
body: JSON.stringify(accessibilityScanResults, null, 2),
|
||||||
|
contentType: 'application/json'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(accessibilityScanResults.violations).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('404 Page Test', async ({ page }, testInfo) => {
|
||||||
|
await page.goto(`${domain}yaya/`);
|
||||||
|
|
||||||
|
await page.screenshot({ path: 'test-results/404.png', fullPage: true });
|
||||||
|
|
||||||
|
const accessibilityScanResults = await new AxeBuilder({ page })
|
||||||
|
.withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'wcag22a', 'wcag22aa'])
|
||||||
|
.analyze();
|
||||||
|
|
||||||
|
await testInfo.attach('accessibility-scan-results', {
|
||||||
|
body: JSON.stringify(accessibilityScanResults, null, 2),
|
||||||
|
contentType: 'application/json'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(accessibilityScanResults.violations).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
+184
@@ -0,0 +1,184 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://schemas.wp.org/trunk/theme.json",
|
||||||
|
"version": 3,
|
||||||
|
"settings": {
|
||||||
|
"layout": {
|
||||||
|
"contentSize": "100%",
|
||||||
|
"wideSize": "1536px"
|
||||||
|
},
|
||||||
|
"color": {
|
||||||
|
"palette": [
|
||||||
|
{
|
||||||
|
"slug": "black",
|
||||||
|
"color": "#000",
|
||||||
|
"name": "Black"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "white",
|
||||||
|
"color": "#fff",
|
||||||
|
"name": "White"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "theme-bg",
|
||||||
|
"color": "var(--color-background)",
|
||||||
|
"name": "Theme Background"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "theme-text",
|
||||||
|
"color": "var(--color-text)",
|
||||||
|
"name": "Theme Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "theme-primary",
|
||||||
|
"color": "var(--color-primary)",
|
||||||
|
"name": "Theme Primary"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "theme-secondary",
|
||||||
|
"color": "var(--color-secondary)",
|
||||||
|
"name": "Theme Secondary"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "theme-bodylinks",
|
||||||
|
"color": "var(--color-bodylinks)",
|
||||||
|
"name": "Theme Body Links"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "theme-footerlinks",
|
||||||
|
"color": "var(--color-footlinks)",
|
||||||
|
"name": "Theme Footer Links"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "theme-success",
|
||||||
|
"color": "var(--color-success)",
|
||||||
|
"name": "Theme Success"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "theme-warning",
|
||||||
|
"color": "var(--color-warning)",
|
||||||
|
"name": "Theme Warning"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "theme-danger",
|
||||||
|
"color": "var(--color-danger)",
|
||||||
|
"name": "Theme Danger"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "theme-info",
|
||||||
|
"color": "var(--color-info)",
|
||||||
|
"name": "Theme Info"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"typography": {
|
||||||
|
"fontFamilies": [
|
||||||
|
{
|
||||||
|
"fontFamily": "var(--font-sans)",
|
||||||
|
"slug": "theme-sans",
|
||||||
|
"name": "Theme Sans"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fontSizes": [
|
||||||
|
{
|
||||||
|
"slug": "base",
|
||||||
|
"size": "var(--text-base)",
|
||||||
|
"name": "Base"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "text-14px",
|
||||||
|
"size": "var(--text-14px)",
|
||||||
|
"name": "Text 14px"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "text-16px",
|
||||||
|
"size": "var(--text-16px)",
|
||||||
|
"name": "Text 16px"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "text-18px",
|
||||||
|
"size": "var(--text-18px)",
|
||||||
|
"name": "Text 18px"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "text-20px",
|
||||||
|
"size": "var(--text-20px)",
|
||||||
|
"name": "Text 20px"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "text-22px",
|
||||||
|
"size": "var(--text-22px)",
|
||||||
|
"name": "Text 22px"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "text-25px",
|
||||||
|
"size": "var(--text-25px)",
|
||||||
|
"name": "Text 25px"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "text-30px",
|
||||||
|
"size": "var(--text-30px)",
|
||||||
|
"name": "Text 30px"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "text-35px",
|
||||||
|
"size": "var(--text-35px)",
|
||||||
|
"name": "Text 35px"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "text-38px",
|
||||||
|
"size": "var(--text-38px)",
|
||||||
|
"name": "Text 38px"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "text-40px",
|
||||||
|
"size": "var(--text-40px)",
|
||||||
|
"name": "Text 40px"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "text-45px",
|
||||||
|
"size": "var(--text-45px)",
|
||||||
|
"name": "Text 45px"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "text-50px",
|
||||||
|
"size": "var(--text-50px)",
|
||||||
|
"name": "Text 50px"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "text-70px",
|
||||||
|
"size": "var(--text-70px)",
|
||||||
|
"name": "Text 70px"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "text-75px",
|
||||||
|
"size": "var(--text-75px)",
|
||||||
|
"name": "Text 75px"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lineHeight": true
|
||||||
|
},
|
||||||
|
"spacing": {
|
||||||
|
"padding": true,
|
||||||
|
"margin": true,
|
||||||
|
"units": [ "px", "em", "rem", "vh", "vw", "%" ]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"styles": {
|
||||||
|
"color": {
|
||||||
|
"background": "var(--wp--preset--color--background)",
|
||||||
|
"text": "var(--wp--preset--color--text)"
|
||||||
|
},
|
||||||
|
"elements": {
|
||||||
|
"link": {
|
||||||
|
"color": {
|
||||||
|
"text": "var(--wp--preset--color--theme-bodylinks)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"typography": {
|
||||||
|
"fontSize": "var(--wp--preset--font-size--base)",
|
||||||
|
"fontFamily": "var(--wp--preset--font-family--theme-sans)",
|
||||||
|
"lineHeight": "1.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/* Accordion block styles */
|
||||||
|
|
||||||
|
.accordion {
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
border: 1px solid var(--color-dark);
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
details.accBody {
|
||||||
|
border-bottom: 1px solid var(--color-dark);
|
||||||
|
max-height: 3.7rem;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 1rem;
|
||||||
|
transition: 0.75s max-height ease-in-out;
|
||||||
|
transition-behavior: allow-discrete;
|
||||||
|
|
||||||
|
&:last-of-type { border: none; }
|
||||||
|
|
||||||
|
summary.accHeader {
|
||||||
|
cursor: pointer;
|
||||||
|
list-style-type: none;
|
||||||
|
padding-right: 2rem;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::-webkit-details-marker { display: none; }
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
color: var(--color-dark);
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 500;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg.marker {
|
||||||
|
color: var(--color-dark);
|
||||||
|
fill: var(--color-dark);
|
||||||
|
height: 1rem;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0.25rem;
|
||||||
|
width: 1.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
div.accContent {
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[open] {
|
||||||
|
background-color: var(--color-dark);
|
||||||
|
border-color: var(--color-light);
|
||||||
|
color: var(--color-light);
|
||||||
|
max-height: 20rem;
|
||||||
|
transition: 0.75s max-height ease-in-out;
|
||||||
|
transition-behavior: allow-discrete;
|
||||||
|
|
||||||
|
summary.accHeader {
|
||||||
|
h2 { color: var(--color-light); }
|
||||||
|
|
||||||
|
svg.marker {
|
||||||
|
color: var(--color-light);
|
||||||
|
fill: var(--color-light);
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Block Name: Accordion
|
||||||
|
*
|
||||||
|
* This is the template that renders the Accordion block.
|
||||||
|
*
|
||||||
|
* @package BasicWP
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace BasicWP;
|
||||||
|
|
||||||
|
$open = get_field( 'open' );
|
||||||
|
$group = get_field( 'group_items' );
|
||||||
|
$accItems = get_field( 'accordion_items' );
|
||||||
|
|
||||||
|
if ( $accItems ) :
|
||||||
|
$classes = 'accordion';
|
||||||
|
$wrapper = blockWrapperAttributes( $classes, $is_preview );
|
||||||
|
?>
|
||||||
|
|
||||||
|
<section <?php echo wp_kses_post( $wrapper ); ?>>
|
||||||
|
<?php foreach ( $accItems as $index => $item ) : ?>
|
||||||
|
<?php
|
||||||
|
$itemID = 'accordion-' . ( $index + 1 );
|
||||||
|
$isOpen = ( $index === 0 && $open ) ? 'open' : '';
|
||||||
|
?>
|
||||||
|
<details <?php echo esc_attr( $group ) ? 'name="' . esc_attr( $group ) . '"' : ''; ?> <?php echo esc_attr( $isOpen ); ?> class="accBody">
|
||||||
|
<summary class="accHeader">
|
||||||
|
<h2><?php echo esc_html( $item['title'] ); ?></h2>
|
||||||
|
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="marker" fill="none" height="1rem" width="1rem" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5" aria-labelledby="<?php echo esc_attr( $itemID ); ?>-title <?php echo esc_attr( $itemID ); ?>-desc">
|
||||||
|
<title id="<?php echo esc_attr( $itemID ); ?>-title">Open icon</title>
|
||||||
|
<desc id="<?php echo esc_attr( $itemID ); ?>-desc">icon that represents the state of the summary</desc>
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4" />
|
||||||
|
</svg>
|
||||||
|
</summary>
|
||||||
|
|
||||||
|
<div id="<?php echo esc_attr( $itemID ); ?>" class="accContent">
|
||||||
|
<?php echo wp_kses_post( $item['content'] ); ?>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</section>
|
||||||
|
<?php endif; ?>
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"name": "acf/accordion",
|
||||||
|
"title": "Accordion",
|
||||||
|
"description": "Accordion block built with details and summary elements.",
|
||||||
|
"style": [
|
||||||
|
"file:./accordion.css"
|
||||||
|
],
|
||||||
|
"category": "vdi-block",
|
||||||
|
"icon": "block-default",
|
||||||
|
"keywords": [
|
||||||
|
"accordion",
|
||||||
|
"faq"
|
||||||
|
],
|
||||||
|
"acf": {
|
||||||
|
"mode": "preview",
|
||||||
|
"renderTemplate": "accordion.php"
|
||||||
|
},
|
||||||
|
"supports": {
|
||||||
|
"align": true,
|
||||||
|
"anchor": false,
|
||||||
|
"color": true,
|
||||||
|
"html": true,
|
||||||
|
"jsx": true,
|
||||||
|
"mode": true,
|
||||||
|
"multiple": true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"name": "acf/boilerplate",
|
||||||
|
"title": "Block Boilerplate",
|
||||||
|
"description": "Boilerplate code to create ACF blocks.",
|
||||||
|
"style": [
|
||||||
|
"file:./boilerplate.css"
|
||||||
|
],
|
||||||
|
"category": "vdi-blocks",
|
||||||
|
"icon": "block-default",
|
||||||
|
"keywords": [
|
||||||
|
"boilerplate"
|
||||||
|
],
|
||||||
|
"acf": {
|
||||||
|
"mode": "preview",
|
||||||
|
"renderTemplate": "boilerplate.php"
|
||||||
|
},
|
||||||
|
"supports": {
|
||||||
|
"align": true,
|
||||||
|
"anchor": true,
|
||||||
|
"color": true,
|
||||||
|
"html": false,
|
||||||
|
"jsx": false,
|
||||||
|
"mode": true,
|
||||||
|
"multiple": false
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user