├── .github └── FUNDING.yml ├── .gitignore ├── fonts ├── ptam.eot ├── ptam.ttf ├── ptam.woff ├── ptam.woff2 └── ptam.svg ├── img ├── logo.png ├── loading.png ├── term-grid-block.jpg ├── featured-posts-block.jpg └── custom-post-types-block.jpg ├── src ├── fonts │ ├── ptam.eot │ ├── ptam.ttf │ ├── ptam.woff │ ├── ptam.woff2 │ └── ptam.svg ├── block │ ├── editor.scss │ ├── featured-posts │ │ ├── block.js │ │ └── block.json │ ├── components │ │ ├── Loading.js │ │ └── TermListControl.js │ ├── term-grid │ │ ├── block.js │ │ └── block.json │ ├── custom-post-one │ │ ├── block.js │ │ └── block.json │ └── style.scss ├── index.js ├── scss │ └── admin.scss └── common.scss ├── .eslintignore ├── uninstall.php ├── phpunit.xml.dist ├── .editorconfig ├── .vscode └── launch.json ├── phpcs.xml ├── includes ├── admin │ ├── tabs │ │ ├── class-tabs.php │ │ ├── class-settings.php │ │ └── class-support.php │ ├── class-gutenberg.php │ ├── js │ │ └── app-dismiss.js │ ├── class-page-columns.php │ ├── class-options.php │ └── class-admin-settings.php ├── class-yoast.php ├── class-enqueue.php └── class-functions.php ├── Gruntfile.js ├── webpack.config.js ├── dist ├── admin.css └── blockstyles.css ├── autoloader.php ├── package.json ├── README.md ├── .travis.yml ├── gulpfile.js ├── .eslintrc.json ├── languages └── post-type-archive-mapping.pot ├── readme.txt └── post-type-archive-mapping.php /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [mediaron] 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | post-type-archive-mapping.zip 4 | -------------------------------------------------------------------------------- /fonts/ptam.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MediaRon/post-type-archive-mapping/HEAD/fonts/ptam.eot -------------------------------------------------------------------------------- /fonts/ptam.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MediaRon/post-type-archive-mapping/HEAD/fonts/ptam.ttf -------------------------------------------------------------------------------- /img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MediaRon/post-type-archive-mapping/HEAD/img/logo.png -------------------------------------------------------------------------------- /fonts/ptam.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MediaRon/post-type-archive-mapping/HEAD/fonts/ptam.woff -------------------------------------------------------------------------------- /fonts/ptam.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MediaRon/post-type-archive-mapping/HEAD/fonts/ptam.woff2 -------------------------------------------------------------------------------- /img/loading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MediaRon/post-type-archive-mapping/HEAD/img/loading.png -------------------------------------------------------------------------------- /src/fonts/ptam.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MediaRon/post-type-archive-mapping/HEAD/src/fonts/ptam.eot -------------------------------------------------------------------------------- /src/fonts/ptam.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MediaRon/post-type-archive-mapping/HEAD/src/fonts/ptam.ttf -------------------------------------------------------------------------------- /src/fonts/ptam.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MediaRon/post-type-archive-mapping/HEAD/src/fonts/ptam.woff -------------------------------------------------------------------------------- /src/fonts/ptam.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MediaRon/post-type-archive-mapping/HEAD/src/fonts/ptam.woff2 -------------------------------------------------------------------------------- /img/term-grid-block.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MediaRon/post-type-archive-mapping/HEAD/img/term-grid-block.jpg -------------------------------------------------------------------------------- /img/featured-posts-block.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MediaRon/post-type-archive-mapping/HEAD/img/featured-posts-block.jpg -------------------------------------------------------------------------------- /img/custom-post-types-block.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MediaRon/post-type-archive-mapping/HEAD/img/custom-post-types-block.jpg -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | **/*.min.js 2 | **/*.build.js 3 | **/node_modules/** 4 | **/vendor/** 5 | build 6 | dist 7 | coverage 8 | cypress 9 | node_modules 10 | vendor 11 | google-fonts.js 12 | -------------------------------------------------------------------------------- /uninstall.php: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | ./tests/ 13 | ./tests/test-sample.php 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # editorconfig.org 3 | 4 | # WordPress Coding Standards 5 | # https://make.wordpress.org/core/handbook/coding-standards/ 6 | 7 | root = true 8 | 9 | [*] 10 | charset = utf-8 11 | end_of_line = lf 12 | insert_final_newline = true 13 | trim_trailing_whitespace = true 14 | indent_style = tab 15 | 16 | [*.yml] 17 | indent_style = space 18 | indent_size = 2 19 | 20 | [*.md] 21 | trim_trailing_whitespace = false 22 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Listen for XDebug", 9 | "type": "php", 10 | "request": "launch", 11 | "port": 9000 12 | }, 13 | { 14 | "name": "Launch currently open script", 15 | "type": "php", 16 | "request": "launch", 17 | "program": "${file}", 18 | "cwd": "${fileDirname}", 19 | "port": 9000 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /phpcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Generally-applicable sniffs for WordPress plugins 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | . 13 | */node_modules/* 14 | */vendor/* 15 | */tests/* 16 | */package/* 17 | *.js 18 | *.css 19 | 20 | -------------------------------------------------------------------------------- /src/block/editor.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Editor styles for the admin 3 | */ 4 | 5 | .ptam-block-post-grid { 6 | h2 a { 7 | text-decoration: none; 8 | } 9 | h2.ptam-block-post-grid-title { 10 | @media only screen and (min-width: 600px) { 11 | font-size: 34px; 12 | } 13 | } 14 | h3.ptam-block-post-grid-title { 15 | @media only screen and (min-width: 600px) { 16 | font-size: 34px; 17 | } 18 | } 19 | h4.ptam-block-post-grid-title { 20 | @media only screen and (min-width: 600px) { 21 | font-size: 28px; 22 | } 23 | } 24 | h5.ptam-block-post-grid-title { 25 | @media only screen and (min-width: 600px) { 26 | font-size: 22px; 27 | } 28 | } 29 | h6.ptam-block-post-grid-title { 30 | @media only screen and (min-width: 600px) { 31 | font-size: 18px; 32 | } 33 | } 34 | } 35 | button.ptam-media-alt-upload.components-button { 36 | margin-bottom: 20px; 37 | } 38 | button.ptam-media-alt-reset.components-button { 39 | margin: 20px 0; 40 | } -------------------------------------------------------------------------------- /includes/admin/tabs/class-tabs.php: -------------------------------------------------------------------------------- 1 | { 18 | // Make sure arr is an array and object has a field of id. 19 | if ( ! Array.isArray( arr ) || ! object.hasOwnProperty( 'id' ) ) { 20 | return -1; 21 | } 22 | // Use the findIndex method of array 23 | const indexId = object.id; 24 | return arr.findIndex(function(element) { 25 | return element.id === indexId; 26 | }); 27 | } 28 | } 29 | 30 | import './block/custom-post-one/block.js'; // Import main block. 31 | import './block/term-grid/block.js'; // Import term grid block. 32 | import './block/featured-posts/block.js'; // Import Featured Posts Block. 33 | -------------------------------------------------------------------------------- /includes/admin/class-gutenberg.php: -------------------------------------------------------------------------------- 1 | 'ptam-custom-query-blocks', 42 | 'title' => __( 'Custom Query Blocks', 'post-type-archive-mapping' ), 43 | ), 44 | ) 45 | ); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/block/featured-posts/block.js: -------------------------------------------------------------------------------- 1 | import { registerBlockType } from '@wordpress/blocks'; 2 | 3 | // Import JS 4 | import edit from './edit'; 5 | 6 | import metadata from './block.json'; 7 | 8 | export const name = 'ptam/featured-posts'; 9 | 10 | registerBlockType( metadata, { 11 | // Block name. Block names must be string that contains a namespace prefix. Example: my-plugin/my-custom-block. 12 | icon: ( 13 | 33 | ), 34 | edit, 35 | 36 | // Render via PHP 37 | save() { 38 | return null; 39 | }, 40 | } ); 41 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | grunt.initConfig({ 3 | compress: { 4 | main: { 5 | options: { 6 | archive: 'post-type-archive-mapping.zip' 7 | }, 8 | files: [ 9 | {src: ['post-type-archive-mapping.php'], dest: '/', filter: 'isFile'}, // includes files in path 10 | {src: ['autoloader.php'], dest: '/', filter: 'isFile'}, // includes files in path 11 | {src: ['readme.txt'], dest: '/', filter: 'isFile'}, // includes files in path 12 | {src: ['uninstall.php'], dest: '/', filter: 'isFile'}, // includes files in path 13 | {src: ['fonts/**'], dest: '/'}, // includes files in path and its subdirs 14 | {src: ['dist/**'], dest: '/'}, // includes files in path and its subdirs 15 | {src: ['build/**'], dest: '/'}, // includes files in path and its subdirs 16 | {src: ['img/**'], dest: '/'}, // includes files in path and its subdirs 17 | {src: ['includes/**'], dest: '/'}, // includes files in path and its subdirs 18 | {src: ['languages/**'], dest: '/'}, // includes files in path and its subdirs 19 | ] 20 | } 21 | } 22 | }); 23 | grunt.registerTask('default', ["compress"]); 24 | 25 | 26 | 27 | grunt.loadNpmTasks( 'grunt-contrib-compress' ); 28 | 29 | }; 30 | -------------------------------------------------------------------------------- /src/block/components/Loading.js: -------------------------------------------------------------------------------- 1 | const Loading = ( 2 | { 3 | cssClass='ptam-loading' 4 | } 5 | ) => ( 6 |
7 |
8 | ); 9 | export default Loading; -------------------------------------------------------------------------------- /src/block/term-grid/block.js: -------------------------------------------------------------------------------- 1 | import { registerBlockType } from '@wordpress/blocks'; 2 | 3 | // Import JS 4 | import edit from './edit'; 5 | 6 | import metadata from './block.json'; 7 | 8 | registerBlockType( metadata, { 9 | icon: ( 10 | 34 | ), 35 | edit, 36 | 37 | // Render via PHP 38 | save() { 39 | return null; 40 | }, 41 | } ); 42 | 43 | -------------------------------------------------------------------------------- /includes/admin/js/app-dismiss.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Onload, set up dismiss events. Vanilla JS. 3 | */ 4 | document.addEventListener('readystatechange', function() { 5 | if (document.readyState !== "complete") { 6 | return; 7 | } 8 | // Set up function to make ajax call. 9 | function dismissNotice( noticeElement ) { 10 | // do fetch request to ajax endpoint. 11 | fetch( ajaxurl, { 12 | method: 'POST', 13 | credentials: 'same-origin', 14 | headers: { 15 | 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8', 16 | }, 17 | body: 'action=ptam_dismiss_notice&_ajax_nonce=' + ptam_app_dismiss.nonce, 18 | } ) 19 | .then( function( response ) { 20 | return response.json(); 21 | } ) 22 | .then( function( json ) { 23 | if ( json.success ) { 24 | // Hide the notice. 25 | noticeElement.style.display = 'none'; 26 | } 27 | } ); 28 | } 29 | 30 | // Set up button events. 31 | var ratingNotice = document.querySelector( '.is-dismissible' ); 32 | if ( null !== ratingNotice ) { 33 | // Get the dismiss button. 34 | var dismissButton = ratingNotice.querySelector( '.notice-dismiss' ); 35 | // Set up event. 36 | dismissButton.addEventListener( 'click', function( event ) { 37 | event.preventDefault(); 38 | // Hide the notice. 39 | dismissNotice( ratingNotice ); 40 | } ); 41 | } 42 | } ); -------------------------------------------------------------------------------- /src/block/custom-post-one/block.js: -------------------------------------------------------------------------------- 1 | import { registerBlockType } from '@wordpress/blocks'; 2 | 3 | // Import JS 4 | import edit from './edit'; 5 | 6 | import metadata from './block.json'; 7 | 8 | export const name = 'ptam/custom-posts'; 9 | 10 | registerBlockType( metadata, { 11 | icon: { 12 | src: ( 13 | 37 | ), 38 | }, 39 | edit, 40 | 41 | // Render via PHP 42 | save() { 43 | return null; 44 | }, 45 | } ); 46 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require( 'path' ); 2 | const RemoveEmptyScriptsPlugin = require( 'webpack-remove-empty-scripts' ); 3 | const MiniCssExtractPlugin = require( 'mini-css-extract-plugin' ); 4 | const defaultConfig = require( '@wordpress/scripts/config/webpack.config' ); 5 | 6 | module.exports = ( env ) => { 7 | return [ 8 | { 9 | ...defaultConfig, 10 | module: { 11 | ...defaultConfig.module, 12 | rules: [ ...defaultConfig.module.rules ], 13 | }, 14 | mode: env.mode, 15 | devtool: 'source-map', 16 | }, 17 | { 18 | mode: env.mode, 19 | entry: { 20 | blockstyles: { import: './src/block/style.scss' }, 21 | admin: [ './src/scss/admin.scss' ], 22 | }, 23 | output: { 24 | assetModuleFilename: 'fonts/[name][ext]', 25 | clean: true, 26 | }, 27 | module: { 28 | rules: [ 29 | { 30 | test: /\.scss$/, 31 | exclude: /(node_modules|bower_components)/, 32 | use: [ 33 | { 34 | loader: MiniCssExtractPlugin.loader, 35 | }, 36 | { 37 | loader: 'css-loader', 38 | options: { 39 | sourceMap: true, 40 | url: false, 41 | }, 42 | }, 43 | 'sass-loader', 44 | ], 45 | }, 46 | { 47 | test: /\.(woff2?|ttf|otf|eot|svg)$/, 48 | include: [ path.resolve( __dirname, 'fonts' ) ], 49 | exclude: /(node_modules|bower_components)/, 50 | type: 'asset/resource', 51 | }, 52 | ], 53 | }, 54 | plugins: [ new RemoveEmptyScriptsPlugin(), new MiniCssExtractPlugin() ], 55 | }, 56 | ]; 57 | }; 58 | -------------------------------------------------------------------------------- /dist/admin.css: -------------------------------------------------------------------------------- 1 | .ptam-admin-reading-cpt{margin-bottom:1.2em}.ptam-admin-reading-cpt h3{margin-top:.2em}.ptam-admin-wrap h1{vertical-align:middle}.ptam-admin-logo{vertical-align:middle}.ptam-admin-logo img{max-width:50px}.ptam-button{padding:10px 20px;border-radius:5px;background:#722727;color:#fff;cursor:pointer;border:1px solid #e0e4e9;transition:background-color .5s ease;text-decoration:none;display:inline-block;vertical-align:middle;font-size:14px}.ptam-button:hover{color:#fff;background:#983434}.ptam-button.ptam-button-info{background:#6c757d;color:#fff}.ptam-button.ptam-button-info:hover{background:#868e96}.ptam-button.ptam-button-danger{background:#721c24;color:#fff}.ptam-button.ptam-button-danger:hover{background:#9b2631}.ptam-button.ptam-button-edit{background:#f8f9fa;color:#000}.ptam-button.ptam-button-edit:hover{background:#fff}.ptam-button.ptam-button-delete{background:#721c24;color:#fff}.ptam-button.ptam-button-delete:hover{background:#9b2631}.ptam-button.ptam-button-lg{padding:20px 30px;font-size:2em}.ptam-button.ptam-button-save{background:#22721c;color:#fff}.ptam-button.ptam-button-save:hover{color:#fff;background:#2e9b26}.ptam-button .ptam-icon-button{text-align:middle;display:inline-block;width:16px;height:16px}.ptam-button svg{width:16px;height:16px;vertical-align:middle}.ptam-button .ptam-icon-yellow{color:#f52a39}h3.ptam-panel-heading{color:#6c757d;font-size:1.8em;font-weight:700;padding-bottom:2px;margin:0;padding-bottom:.7em;line-height:1.3}.ptam-admin-panel-area{position:relative;background-color:#fff;border:1px solid #ddd;box-shadow:1px 1px 7px 2px rgba(221,221,221,.6);padding:20px;margin-top:25px}.ptam-panel-row{margin-bottom:15px}.ptam-panel-row:last-of-type{margin-bottom:0} 2 | -------------------------------------------------------------------------------- /autoloader.php: -------------------------------------------------------------------------------- 1 | 12 |
  • Select a Private or Public page to use as your post type archive page.
  • 13 |
  • View the archive and you will see the page content instead of the archive content.
  • 14 |
  • Use page templates on your pages for flexibility.
  • 15 | 16 | 17 | ## Note 18 | 19 | Your post types need to have `has_archive` set to true. 20 | 21 | Installation 22 | --------------------- 23 | Go to Settings->Reading. At the bottom you will see a place to map your post types. 24 | 25 | DEVS 26 | --------------------- 27 | 28 | 1. Clone the repo to any location you choose. 29 | 2. Run ```npm install``` inside the folder. 30 | 3. Run ```npm run build``` inside the folder. 31 | 4. Set up a symlink to your WordPress installation using the folder as the base. 32 | 5. Run ```npm run watch``` to make changes and then ```npm run build``` when you're done. 33 | 34 | 1. To edit the block, they are in ```/blocks/load.js``` and ```/blocks/edit.js```. 35 | 2. The REST API is created and passed in ```/blocks.init.php```. 36 | 3. The attributes and output are in ```/blocks/class-post-type-select-posts.php```. 37 | 38 | Credit 39 | ------------- 40 | Chris Logan for coming up with the idea. 41 | 42 | # Security Policy 43 | 44 | ## Reporting Security Bugs Please report security bugs found in the Custom Query Blocks plugin's source code through the [Patchstack Vulnerability Disclosure Program](https://patchstack.com/database/report-preview/fe816fb9-144f-4dd1-998a-a465439d87e0?pin=IFOiN16e7SpHRdJF). The Patchstack team will assist you with verification, CVE assignment, and notify the developers of this plugin. -------------------------------------------------------------------------------- /src/block/components/TermListControl.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react'; 2 | import { __ } from '@wordpress/i18n'; 3 | import { useForm, Controller, useWatch } from 'react-hook-form'; 4 | import { CheckboxControl } from '@wordpress/components'; 5 | 6 | const TermListControl = ( props ) => { 7 | 8 | const { terms, onChange, hasSelectAll = false } = props; 9 | 10 | const getDefaultValues = () => { 11 | return { 12 | terms: terms, 13 | }; 14 | }; 15 | 16 | const { control, setValue, getValues } = useForm( { 17 | defaultValues: getDefaultValues(), 18 | } ); 19 | 20 | const formValues = useWatch( { control } ); 21 | 22 | if ( ! formValues.terms ) { 23 | return null; 24 | } 25 | 26 | const isDisabled = ( term_id ) => { 27 | if ( ! hasSelectAll || 0 === term_id ) { 28 | return false; 29 | } else { 30 | // Check if term ID 0 is selected. 31 | const termZero = formValues.terms.find( ( term ) => term.id === 0 ); 32 | return termZero.selected; 33 | } 34 | } 35 | 36 | return ( 37 |
    38 | { 39 | terms.map( ( term, index ) => { 40 | return ( 41 |
    42 | ( 46 | { 50 | term.selected = newValue; 51 | setValue( `terms[${ index }]`, term ); 52 | 53 | // Get selected terms. 54 | const selectedTerms = getValues().terms.filter( ( term ) => term.selected ); 55 | props.onChange( selectedTerms ); 56 | } } 57 | disabled={ isDisabled( term.id ) } 58 | /> 59 | ) } 60 | /> 61 |
    62 | ); 63 | } ) 64 | } 65 |
    66 | ) 67 | }; 68 | export default TermListControl; -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | dist: trusty 3 | 4 | language: php 5 | 6 | notifications: 7 | email: 8 | on_success: never 9 | on_failure: change 10 | 11 | branches: 12 | only: 13 | - master 14 | 15 | cache: 16 | directories: 17 | - $HOME/.composer/cache 18 | 19 | matrix: 20 | include: 21 | - php: 5.6 22 | env: WP_TRAVISCI=phpcs 23 | 24 | before_install: 25 | - if [[ "$SNIFF" == "1" ]]; then export PHPCS_DIR=/tmp/phpcs; fi 26 | - if [[ "$SNIFF" == "1" ]]; then export SNIFFS_DIR=/tmp/sniffs; fi 27 | # Install PHP_CodeSniffer. 28 | - if [[ "$SNIFF" == "1" ]]; then git clone -b master --depth 1 https://github.com/squizlabs/PHP_CodeSniffer.git $PHPCS_DIR; fi 29 | # Install WordPress Coding Standards. 30 | - if [[ "$SNIFF" == "1" ]]; then git clone -b master --depth 1 https://github.com/WordPress/WordPress-Coding-Standards.git $SNIFFS_DIR; fi 31 | # Install Metronet Profile Picture 32 | - if [[ "$SNIFF" == "1" ]]; then git clone -b master --depth 1 https://github.com/ronalfy/user-profile-picture.git $SNIFFS_DIR; fi 33 | # Set install path for WordPress Coding Standards. 34 | - if [[ "$SNIFF" == "1" ]]; then $PHPCS_DIR/bin/phpcs --config-set installed_paths $SNIFFS_DIR; fi 35 | # After CodeSniffer install you should refresh your path. 36 | - if [[ "$SNIFF" == "1" ]]; then phpenv rehash; fi 37 | 38 | before_script: 39 | - export PATH="$HOME/.composer/vendor/bin:$PATH" 40 | - | 41 | if [ -f ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini ]; then 42 | phpenv config-rm xdebug.ini 43 | else 44 | echo "xdebug.ini does not exist" 45 | fi 46 | - | 47 | if [[ "$WP_TRAVISCI" == "phpcs" ]] ; then 48 | composer global require wp-coding-standards/wpcs 49 | phpcs --config-set installed_paths $HOME/.composer/vendor/wp-coding-standards/wpcs 50 | fi 51 | 52 | script: 53 | - | 54 | if [[ ! -z "$WP_VERSION" ]] ; then 55 | phpunit 56 | WP_MULTISITE=1 phpunit 57 | fi 58 | - | 59 | if [[ "$WP_TRAVISCI" == "phpcs" ]] ; then 60 | phpcs 61 | fi 62 | -------------------------------------------------------------------------------- /includes/admin/class-page-columns.php: -------------------------------------------------------------------------------- 1 | value columns. 27 | * 28 | * @return array Updated list of columns. 29 | */ 30 | public function add_columns( $columns ) { 31 | /** 32 | * Allow others to programatically disable columns. 33 | * 34 | * @since 3.3.5 35 | * 36 | * @param bool true default. 37 | */ 38 | if ( ! apply_filters( 'ptam_add_pages_column', true ) ) { 39 | return $columns; 40 | } 41 | $columns['ptam'] = __( 'Archive Mapping', 'post-type-archive-mapping' ); 42 | return $columns; 43 | } 44 | 45 | /** 46 | * Populate the column vaues for the mapped posts. 47 | * 48 | * @param string $column_name The column name. 49 | * @param int $page_id The Page ID. 50 | */ 51 | public function column_values( $column_name, $page_id ) { 52 | if ( 'ptam' === $column_name ) { 53 | // If successful, returns the post type slug. 54 | $post_type = get_post_meta( $page_id, '_post_type_mapped', true ); 55 | if ( $post_type && ! empty( $post_type ) ) { 56 | $archive_link = get_post_type_archive_link( $post_type ); 57 | if ( $archive_link ) { 58 | echo sprintf( 59 | '%s', 60 | esc_url( $archive_link ), 61 | esc_html__( 'View Post Type Archive', 'post-type-archive-mapping' ) 62 | ); 63 | } 64 | return; 65 | } 66 | $term_id = get_post_meta( $page_id, '_term_mapped', true ); 67 | if ( $term_id && ! empty( $term_id ) ) { 68 | $archive_link = get_term_link( absint( $term_id ) ); 69 | if ( is_wp_error( $archive_link ) ) { 70 | return; 71 | } 72 | echo sprintf( 73 | '%s', 74 | esc_url( $archive_link ), 75 | esc_html__( 'View Term Archive', 'post-type-archive-mapping' ) 76 | ); 77 | return; 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | const gulp = require( 'gulp' ); 2 | const del = require( 'del' ); 3 | const run = require( 'gulp-run' ); 4 | const zip = require( 'gulp-zip' ); 5 | 6 | gulp.task( 'bundle', function() { 7 | return gulp.src( [ 8 | '**/*', 9 | '!bin/**/*', 10 | '!node_modules/**/*', 11 | '!vendor/**/*', 12 | '!composer.*', 13 | '!release/**/*', 14 | '!tests/**/*', 15 | '!phpcs.xml' 16 | ] ) 17 | .pipe( gulp.dest( 'release/post-type-archive-mapping' ) ); 18 | } ); 19 | 20 | gulp.task( 'remove:bundle', function() { 21 | return del( [ 22 | 'release/post-type-archive-mapping', 23 | 'post-type-archive-mapping.zip', 24 | ] ); 25 | } ); 26 | 27 | gulp.task( 'wporg:prepare', function() { 28 | return run( 'mkdir -p release' ).exec(); 29 | } ); 30 | 31 | gulp.task( 'release:copy-for-zip', function() { 32 | return gulp.src('release/post-type-archive-mapping/**') 33 | .pipe(gulp.dest('post-type-archive-mapping')); 34 | } ); 35 | 36 | gulp.task( 'release:zip', function() { 37 | return gulp.src('post-type-archive-mapping/**/*', { base: "." }) 38 | .pipe(zip('post-type-archive-mapping.zip')) 39 | .pipe(gulp.dest('.')); 40 | } ); 41 | 42 | gulp.task( 'cleanup', function() { 43 | return del( [ 44 | 'release', 45 | 'post-type-archive-mapping' 46 | ] ); 47 | } ); 48 | 49 | gulp.task( 'clean:bundle', function() { 50 | return del( [ 51 | 'release/post-type-archive-mapping/bin', 52 | 'release/post-type-archive-mapping/node_modules', 53 | 'release/post-type-archive-mapping/vendor', 54 | 'release/post-type-archive-mapping/tests', 55 | 'release/post-type-archive-mapping/trunk', 56 | 'release/post-type-archive-mapping/gulpfile.js', 57 | 'release/post-type-archive-mapping/Makefile', 58 | 'release/post-type-archive-mapping/package*.json', 59 | 'release/post-type-archive-mapping/phpunit.xml.dist', 60 | 'release/post-type-archive-mapping/README.md', 61 | 'release/post-type-archive-mapping/CHANGELOG.md', 62 | 'release/post-type-archive-mapping/webpack.config.js', 63 | 'release/post-type-archive-mapping/.editorconfig', 64 | 'release/post-type-archive-mapping/.eslistignore', 65 | 'release/post-type-archive-mapping/.eslistrcjson', 66 | 'release/post-type-archive-mapping/.git', 67 | 'release/post-type-archive-mapping/.gitignore', 68 | 'release/post-type-archive-mapping/src/block', 69 | 'package/prepare', 70 | ] ); 71 | } ); 72 | 73 | gulp.task( 'default', gulp.series( 74 | 'remove:bundle', 75 | 'bundle', 76 | 'wporg:prepare', 77 | 'clean:bundle', 78 | 'release:copy-for-zip', 79 | 'release:zip', 80 | 'cleanup' 81 | ) ); 82 | -------------------------------------------------------------------------------- /includes/class-yoast.php: -------------------------------------------------------------------------------- 1 | labels->name ) ? apply_filters( 'post_type_archive_title', $post_type_data->labels->name, $post_type ) : $title; 104 | return $title; 105 | } 106 | if ( 'term' === $archive_type ) { 107 | $term_id = absint( $archive_id ); 108 | $term = get_term_by( 'id', $term_id, get_query_var( 'term_tax' ) ); 109 | if ( is_wp_error( $term ) ) { 110 | return $title; 111 | } 112 | $title = apply_filters( 'single_term_title', $term->name ); 113 | return $title; 114 | } 115 | return $title; 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/scss/admin.scss: -------------------------------------------------------------------------------- 1 | $base_color: #58a0db; 2 | $admin_color_panel_background: #fff; 3 | $border_color_light: #ddd; 4 | $admin_logo_color: #b01b1b; 5 | $body_color: #000; 6 | $main_color: #274472; 7 | $color_disabled: #f1f1f1; 8 | $accent_color_alt: #627227; 9 | $accent_color: #722727; 10 | $accent_color_hover: #722727; 11 | $color_white: #ffffff; 12 | $color_black: #000000; 13 | $secondary_color: #e2e3e5; 14 | $secondary_text_color: #383d41; 15 | $secondary_border_color: #d6d8db; 16 | $success_color: #d4edda; 17 | $success_text_color: #155724; 18 | $success_border_color: #c3e6cb; 19 | $info_color: #d1ecf1; 20 | $info_border_color: #bee5eb; 21 | $info_text_color: #0c5460; 22 | $warning_color: #fff3cd; 23 | $warning_border_color: #ffeeba; 24 | $warning_text_color: #856404; 25 | $error_color: #f8d7da; 26 | $error_border_color: #f5c6cb; 27 | $error_text_color: #721c24; 28 | $danger_background_color: #721c24; 29 | $danger_text_color: #ffffff; 30 | $save_button_color: #22721c; 31 | $save_button_color_text: #fff; 32 | $primary_button_color: #1c3472; 33 | $primary_button_color_text: #fff; 34 | $secondary_button_color: #6c757d; 35 | $secondary_button_color_text: #fff; 36 | $edit_button_color: #f8f9fa; 37 | $edit_button_color_text: #000; 38 | $delete_button_color: #721c24; 39 | $delete_button_color_text: #fff; 40 | $danger_button_color: #721c24; 41 | $danger_button_color_text: #fff; 42 | 43 | 44 | .ptam-admin-reading-cpt { 45 | margin-bottom: 1.2em; 46 | h3 { 47 | margin-top: 0.2em; 48 | } 49 | } 50 | .ptam-admin-wrap { 51 | h1 { 52 | vertical-align: middle; 53 | } 54 | } 55 | .ptam-admin-logo { 56 | vertical-align: middle; 57 | img { 58 | max-width: 50px; 59 | } 60 | } 61 | 62 | /* Button Options */ 63 | .ptam-button { 64 | padding: 10px 20px; 65 | border-radius: 5px; 66 | background: $accent_color; 67 | color: #fff; 68 | cursor: pointer; 69 | border: 1px solid #e0e4e9; 70 | transition: background-color 0.5s ease; 71 | text-decoration: none; 72 | display: inline-block; 73 | vertical-align: middle; 74 | font-size: 14px; 75 | &:hover { 76 | color: #fff; 77 | background: lighten( $accent_color, 10% ); 78 | } 79 | &.ptam-button-info { 80 | background: $secondary_button_color; 81 | color: $secondary_button_color_text; 82 | &:hover { 83 | background: lighten( $secondary_button_color, 10% ); 84 | } 85 | } 86 | &.ptam-button-danger { 87 | background: $danger_button_color; 88 | color: $danger_button_color_text; 89 | &:hover { 90 | background: lighten( $danger_button_color, 10% ); 91 | } 92 | } 93 | &.ptam-button-edit { 94 | background: $edit_button_color; 95 | color: $edit_button_color_text; 96 | &:hover { 97 | background: lighten( $edit_button_color, 10% ); 98 | } 99 | } 100 | &.ptam-button-delete { 101 | background: $delete_button_color; 102 | color: $delete_button_color_text; 103 | &:hover { 104 | background: lighten( $delete_button_color, 10% ); 105 | } 106 | } 107 | &.ptam-button-lg { 108 | padding: 20px 30px; 109 | font-size: 2em; 110 | } 111 | &.ptam-button-save { 112 | background: $save_button_color; 113 | color: $save_button_color_text; 114 | &:hover { 115 | color: #fff; 116 | background: lighten( $save_button_color, 10% ); 117 | } 118 | } 119 | .ptam-icon-button { 120 | text-align: middle; 121 | display: inline-block; 122 | width: 16px; 123 | height: 16px; 124 | } 125 | svg { 126 | width: 16px; 127 | height: 16px; 128 | vertical-align: middle; 129 | } 130 | .ptam-icon-yellow { 131 | color: #f52a39; 132 | } 133 | } 134 | 135 | h3.ptam-panel-heading { 136 | color: $secondary_button_color; 137 | font-size: 1.8em; 138 | font-weight: 700; 139 | padding-bottom: 2px; 140 | margin: 0; 141 | padding-bottom: 0.7em; 142 | line-height: 1.3; 143 | } 144 | .ptam-admin-panel-area { 145 | position: relative; 146 | background-color: #FFF; 147 | border: 1px solid #DDD; 148 | box-shadow: 1px 1px 7px 2px rgba(221,221,221,0.6); 149 | padding: 20px; 150 | margin-top: 25px; 151 | } 152 | .ptam-panel-row { 153 | margin-bottom: 15px; 154 | &:last-of-type { 155 | margin-bottom: 0; 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /includes/class-enqueue.php: -------------------------------------------------------------------------------- 1 | true, 84 | 'publicly_queryable' => true, 85 | ), 86 | 'objects' 87 | ); 88 | $tax_array = array(); 89 | foreach ( $taxonomies as $index => $taxonomy ) { 90 | $tax_array[ $index ] = $taxonomy->label; 91 | } 92 | 93 | $post_type_array = array(); 94 | $post_types = get_post_types( 95 | array( 96 | 'public' => true, 97 | ), 98 | 'objects' 99 | ); 100 | foreach ( $post_types as $post_type => $type ) { 101 | if ( get_object_taxonomies( $post_type, 'names' ) ) { 102 | $post_type_array[ $post_type ] = $type->label; 103 | } 104 | } 105 | 106 | $wpml_languages = array(); 107 | if ( function_exists( 'icl_get_languages' ) ) { 108 | $languages = icl_get_languages(); 109 | foreach ( $languages as $language ) { 110 | $wpml_languages[] = array( 111 | 'value' => $language['code'], 112 | 'label' => $language['native_name'], 113 | ); 114 | } 115 | } 116 | 117 | // Pass in i18n variables. 118 | wp_localize_script( 119 | 'ptam-custom-posts-gutenberg', 120 | 'ptam_globals', 121 | array( 122 | 'img_url' => esc_url( \PostTypeArchiveMapping::get_plugin_url( 'img/loading.png' ) ), 123 | 'rest_url' => esc_url( rest_url() ), 124 | 'taxonomies' => $tax_array, 125 | 'fonts' => Functions::get_fonts(), 126 | 'image_sizes' => Functions::get_all_image_sizes(), 127 | 'post_types' => $post_type_array, 128 | 'custom_posts_block_preview' => esc_url( \PostTypeArchiveMapping::get_plugin_url( 'img/custom-post-types-block.jpg' ) ), 129 | 'term_grid_block_preview' => esc_url( \PostTypeArchiveMapping::get_plugin_url( 'img/term-grid-block.jpg' ) ), 130 | 'featured_posts_block_preview' => esc_url( \PostTypeArchiveMapping::get_plugin_url( 'img/featured-posts-block.jpg' ) ), 131 | 'wpml_installed' => defined( 'ICL_SITEPRESS_VERSION' ) ? true : false, 132 | 'wpml_languages' => $wpml_languages, 133 | 'rest_nonce' => wp_create_nonce( 'wp_rest' ), 134 | ) 135 | ); 136 | wp_set_script_translations( 'ptam-custom-posts-gutenberg', 'post-type-archive-mapping' ); 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/common.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Common styles 3 | * Loads on front end and back end 4 | */ 5 | 6 | @font-face { 7 | font-family: 'PTAM'; 8 | src: url('../fonts/ptam.eot'); /* IE9 Compat Modes */ 9 | src: url('../fonts/ptam.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ 10 | url('../fonts/ptam.woff2') format('woff2'), /* Super Modern Browsers */ 11 | url('../fonts/ptam.woff') format('woff'), /* Pretty Modern Browsers */ 12 | url('../fonts/ptam.ttf') format('truetype'), /* Safari, Android, iOS */ 13 | url('../fonts/ptam.svg#svgFontName') format('svg'); /* Legacy iOS */ 14 | } 15 | 16 | // Variables 17 | $black: #293038; 18 | $accent: #5a3fd6; 19 | $lightgray: #626e81; 20 | 21 | /* Font size styles */ 22 | @media only screen and (min-width: 600px) { 23 | div[class*="wp-block-atomic"].ptam-font-size-14 { 24 | &.ptam-block-testimonial p, 25 | &.ptam-block-notice p, 26 | &.ptam-block-profile p, 27 | &.ptam-block-accordion p, 28 | &.ptam-block-cta p { 29 | font-size: 14px; 30 | } 31 | } 32 | 33 | div[class*="wp-block-atomic"].ptam-font-size-15 { 34 | &.ptam-block-testimonial p, 35 | &.ptam-block-notice p, 36 | &.ptam-block-profile p, 37 | &.ptam-block-accordion p, 38 | &.ptam-block-cta p { 39 | font-size: 15px; 40 | } 41 | } 42 | 43 | div[class*="wp-block-atomic"].ptam-font-size-16 { 44 | &.ptam-block-testimonial p, 45 | &.ptam-block-notice p, 46 | &.ptam-block-profile p, 47 | &.ptam-block-accordion p, 48 | &.ptam-block-cta p { 49 | font-size: 16px; 50 | } 51 | } 52 | 53 | div[class*="wp-block-atomic"].ptam-font-size-17 { 54 | &.ptam-block-testimonial p, 55 | &.ptam-block-notice p, 56 | &.ptam-block-profile p, 57 | &.ptam-block-accordion p, 58 | &.ptam-block-cta p { 59 | font-size: 17px; 60 | } 61 | } 62 | 63 | div[class*="wp-block-atomic"].ptam-font-size-18 { 64 | &.ptam-block-testimonial p, 65 | &.ptam-block-notice p, 66 | &.ptam-block-profile p, 67 | &.ptam-block-accordion p, 68 | &.ptam-block-cta p { 69 | font-size: 18px; 70 | } 71 | } 72 | 73 | div[class*="wp-block-atomic"].ptam-font-size-19 { 74 | &.ptam-block-testimonial p, 75 | &.ptam-block-notice p, 76 | &.ptam-block-profile p, 77 | &.ptam-block-accordion p, 78 | &.ptam-block-cta p { 79 | font-size: 19px; 80 | } 81 | } 82 | 83 | div[class*="wp-block-atomic"].ptam-font-size-20 { 84 | &.ptam-block-testimonial p, 85 | &.ptam-block-notice p, 86 | &.ptam-block-profile p, 87 | &.ptam-block-accordion p, 88 | &.ptam-block-cta p { 89 | font-size: 20px; 90 | } 91 | } 92 | 93 | div[class*="wp-block-atomic"].ptam-font-size-21 { 94 | &.ptam-block-testimonial p, 95 | &.ptam-block-notice p, 96 | &.ptam-block-profile p, 97 | &.ptam-block-accordion p, 98 | &.ptam-block-cta p { 99 | font-size: 21px; 100 | } 101 | } 102 | 103 | div[class*="wp-block-atomic"].ptam-font-size-22 { 104 | &.ptam-block-testimonial p, 105 | &.ptam-block-notice p, 106 | &.ptam-block-profile p, 107 | &.ptam-block-accordion p, 108 | &.ptam-block-cta p { 109 | font-size: 22px; 110 | } 111 | } 112 | 113 | div[class*="wp-block-atomic"].ptam-font-size-23 { 114 | &.ptam-block-testimonial p, 115 | &.ptam-block-notice p, 116 | &.ptam-block-profile p, 117 | &.ptam-block-accordion p, 118 | &.ptam-block-cta p { 119 | font-size: 23px; 120 | } 121 | } 122 | 123 | div[class*="wp-block-atomic"].ptam-font-size-24 { 124 | &.ptam-block-testimonial p, 125 | &.ptam-block-notice p, 126 | &.ptam-block-profile p, 127 | &.ptam-block-accordion p, 128 | &.ptam-block-cta p { 129 | font-size: 24px; 130 | } 131 | } 132 | } 133 | 134 | .center { 135 | text-align: center; 136 | } 137 | 138 | .left { 139 | text-align: left; 140 | } 141 | 142 | .right { 143 | text-align: right; 144 | } 145 | 146 | @media only screen and (min-width: 600px) { 147 | .wp-block-columns .layout-column-1, 148 | .wp-block-columns .layout-column-2 { 149 | margin-right: 5%; 150 | } 151 | } 152 | 153 | .wp-block-image { 154 | margin-bottom: 1.2em; 155 | } 156 | 157 | .ptam-text-link { 158 | color: inherit; 159 | box-shadow: 0 -1px 0 inset; 160 | text-decoration: none; 161 | transition: .3s ease; 162 | 163 | &:hover { 164 | color: inherit; 165 | box-shadow: 0 -2px 0 inset; 166 | color: $accent; 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /includes/admin/class-options.php: -------------------------------------------------------------------------------- 1 | 'off', 98 | 'disable_archive_mapping' => 'off', 99 | 'disable_page_columns' => 'off', 100 | 'disable_image_sizes' => 'off', 101 | ); 102 | 103 | /** 104 | * Allow other plugins to add to the defaults. 105 | * 106 | * @since 5.1.0 107 | * 108 | * @param array $defaults An array of option defaults. 109 | */ 110 | $defaults = apply_filters( 'ptam_options_defaults', $defaults ); 111 | return $defaults; 112 | } 113 | 114 | /** 115 | * Sanitize options before saving. 116 | * 117 | * @param array $options Array of options to sanitize. 118 | * 119 | * @return bool true if valid, false if not. 120 | */ 121 | private static function sanitize_options( $options = array() ) { 122 | if ( ! is_array( $options ) ) { 123 | return false; 124 | } 125 | foreach ( $options as $option_name => $option_value ) { 126 | switch ( $option_name ) { 127 | default: 128 | if ( 'off' !== $option_value && 'on' !== $option_value ) { 129 | return false; 130 | } 131 | break; 132 | } 133 | } 134 | return true; 135 | } 136 | 137 | /** 138 | * Checks if blocks are disabled or not. 139 | * 140 | * @return bool true if disabled, false if not. 141 | */ 142 | public static function is_blocks_disabled() { 143 | $maybe_disabled = self::get_options( false, 'disable_blocks' ); 144 | if ( is_string( $maybe_disabled ) && 'on' === $maybe_disabled ) { 145 | return true; 146 | } 147 | return false; 148 | } 149 | 150 | /** 151 | * Checks if page columns are disabled or not. 152 | * 153 | * @return bool true if disabled, false if not. 154 | */ 155 | public static function is_page_columns_disabled() { 156 | $maybe_disabled = self::get_options( false, 'disable_page_columns' ); 157 | if ( is_string( $maybe_disabled ) && 'on' === $maybe_disabled ) { 158 | return true; 159 | } 160 | return false; 161 | } 162 | 163 | /** 164 | * Checks if archive mapping is disabled or not. 165 | * 166 | * @return bool true if disabled, false if not. 167 | */ 168 | public static function is_archive_mapping_disabled() { 169 | $maybe_disabled = self::get_options( false, 'disable_archive_mapping' ); 170 | if ( is_string( $maybe_disabled ) && 'on' === $maybe_disabled ) { 171 | return true; 172 | } 173 | return false; 174 | } 175 | 176 | /** 177 | * Checks if custom image sizes are disabled or not. 178 | * 179 | * @return bool true if disabled, false if not. 180 | */ 181 | public static function is_custom_image_sizes_disabled() { 182 | $maybe_disabled = self::get_options( false, 'disable_image_sizes' ); 183 | if ( is_string( $maybe_disabled ) && 'on' === $maybe_disabled ) { 184 | return true; 185 | } 186 | return false; 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /src/block/term-grid/block.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schemas.wp.org/trunk/block.json", 3 | "title": "Term Grid", 4 | "apiVersion": 1, 5 | "name": "ptam/term-grid", 6 | "category": "ptam-custom-query-blocks", 7 | "icon": "", 8 | "description": "Show off your terms (categories) in a beautiful and customizable grid.", 9 | "keywords": ["category", "term", "grid"], 10 | "supports": { 11 | "align": ["wide", "full", "center"], 12 | "anchor": true, 13 | "html": false 14 | }, 15 | "version": "5.1.4", 16 | "textdomain": "post-type-archive-mapping", 17 | "attributes": { 18 | "taxonomy": { 19 | "type": "string", 20 | "default": "category" 21 | }, 22 | "terms": { 23 | "type": "array", 24 | "default": [] 25 | }, 26 | "termsExclude": { 27 | "type": "array", 28 | "default": [] 29 | }, 30 | "order": { 31 | "type": "string", 32 | "default": "desc" 33 | }, 34 | "orderBy": { 35 | "type": "string", 36 | "default": "name" 37 | }, 38 | "align": { 39 | "type": "string", 40 | "default": "full" 41 | }, 42 | "columns": { 43 | "type": "integer", 44 | "default": 2 45 | }, 46 | "showTermTitle": { 47 | "type": "boolean", 48 | "default": true 49 | }, 50 | "showTermDescription": { 51 | "type": "boolean", 52 | "default": false 53 | }, 54 | "disableStyles": { 55 | "type": "boolean", 56 | "default": false 57 | }, 58 | "linkContainer": { 59 | "type": "boolean", 60 | "default": true 61 | }, 62 | "linkTermTitle": { 63 | "type": "boolean", 64 | "default": true 65 | }, 66 | "showButton": { 67 | "type": "boolean", 68 | "default": false 69 | }, 70 | "backgroundImageSource": { 71 | "type": "string", 72 | "default": "meta" 73 | }, 74 | "backgroundImageMeta": { 75 | "type": "string", 76 | "default": "" 77 | }, 78 | "backgroundImageFallback": { 79 | "type": "object", 80 | "default": "" 81 | }, 82 | "imageSize": { 83 | "type": "string", 84 | "default": "large" 85 | }, 86 | "containerId": { 87 | "type": "string", 88 | "default": "ptam-term-grid-wrapper" 89 | }, 90 | "backgroundType": { 91 | "type": "string", 92 | "default": "color" 93 | }, 94 | "backgroundColor": { 95 | "type": "string", 96 | "default": "#32373c" 97 | }, 98 | "backgroundColorHover": { 99 | "type": "string", 100 | "default": "#32373c" 101 | }, 102 | "backgroundGradient": { 103 | "type": "string", 104 | "default": "" 105 | }, 106 | "backgroundGradientHover": { 107 | "type": "string", 108 | "default": "" 109 | }, 110 | "overlayColor": { 111 | "type": "string", 112 | "default": "#000000" 113 | }, 114 | "overlayColorHover": { 115 | "type": "string", 116 | "default": "#000000" 117 | }, 118 | "overlayOpacity": { 119 | "type": "number", 120 | "default": 0.3 121 | }, 122 | "overlayOpacityHover": { 123 | "type": "number", 124 | "default": 0.5 125 | }, 126 | "termTitleColor": { 127 | "type": "string", 128 | "default": "#FFFFFF" 129 | }, 130 | "termTitleColorHover": { 131 | "type": "string", 132 | "default": "#FFFFFF" 133 | }, 134 | "termDescriptionColor": { 135 | "type": "string", 136 | "default": "#FFFFFF" 137 | }, 138 | "termDescriptionColorHover": { 139 | "type": "string", 140 | "default": "#FFFFFF" 141 | }, 142 | "itemBorder": { 143 | "type": "integer", 144 | "default": 0 145 | }, 146 | "itemBorderColor": { 147 | "type": "string", 148 | "default": "#000000" 149 | }, 150 | "itemBorderRadius": { 151 | "type": "integer", 152 | "default": 0 153 | }, 154 | "termTitleFont": { 155 | "type": "string", 156 | "default": "Arial" 157 | }, 158 | "termDescriptionFont": { 159 | "type": "string", 160 | "default": "Arial" 161 | }, 162 | "termButtonText": { 163 | "type": "string", 164 | "default": "Learn More" 165 | }, 166 | "termButtonFont": { 167 | "type": "string", 168 | "default": "Arial" 169 | }, 170 | "termButtonTextColor": { 171 | "type": "string", 172 | "default": "#FFFFFF" 173 | }, 174 | "termButtonTextHoverColor": { 175 | "type": "string", 176 | "default": "#FFFFFF" 177 | }, 178 | "termButtonBackgroundColor": { 179 | "type": "string", 180 | "default": "#32373c" 181 | }, 182 | "termButtonBackgroundHoverColor": { 183 | "type": "string", 184 | "default": "#000000" 185 | }, 186 | "termButtonBorder": { 187 | "type": "integer", 188 | "default": 0 189 | }, 190 | "termButtonBorderColor": { 191 | "type": "string", 192 | "default": "#000000" 193 | }, 194 | "termButtonBorderRadius": { 195 | "type": "integer", 196 | "default": 28 197 | }, 198 | "preview": { 199 | "type": "boolean", 200 | "default": false 201 | } 202 | }, 203 | "example": { 204 | "attributes": { 205 | "preview": true 206 | } 207 | }, 208 | "editorScript": "ptam-custom-posts-gutenberg", 209 | "editorStyle": "ptam-style-editor-css" 210 | } 211 | -------------------------------------------------------------------------------- /src/block/featured-posts/block.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schemas.wp.org/trunk/block.json", 3 | "title": "Featured Posts by Term", 4 | "apiVersion": 1, 5 | "name": "ptam/featured-posts", 6 | "category": "ptam-custom-query-blocks", 7 | "icon": "", 8 | "description": "Highlight a term (category) and show the items within it. Perfect for term archives.", 9 | "keywords": [ 10 | "featured", 11 | "featured post", 12 | "post", 13 | "posts", 14 | "category", 15 | "term" 16 | ], 17 | "supports": { 18 | "align": ["wide", "full", "center"], 19 | "anchor": true, 20 | "html": false 21 | }, 22 | "version": "5.1.4", 23 | "textdomain": "post-type-archive-mapping", 24 | "attributes": { 25 | "taxonomy": { 26 | "type": "string", 27 | "default": "category" 28 | }, 29 | "postType": { 30 | "type": "string", 31 | "default": "post" 32 | }, 33 | "postLayout": { 34 | "type": "string", 35 | "default": "excerpt" 36 | }, 37 | "displayPostContent": { 38 | "type": "boolean", 39 | "default": false 40 | }, 41 | "term": { 42 | "type": "string", 43 | "default": "0" 44 | }, 45 | "postsInclude": { 46 | "type": "array", 47 | "default": [] 48 | }, 49 | "postsExclude": { 50 | "type": "array", 51 | "default": [] 52 | }, 53 | "order": { 54 | "type": "string", 55 | "default": "DESC" 56 | }, 57 | "orderBy": { 58 | "type": "string", 59 | "default": "date" 60 | }, 61 | "align": { 62 | "type": "string", 63 | "default": "wide" 64 | }, 65 | "avatarSize": { 66 | "type": "integer", 67 | "default": 500 68 | }, 69 | "imageType": { 70 | "type": "string", 71 | "default": "regular" 72 | }, 73 | "imageTypeSize": { 74 | "type": "string", 75 | "default": "thumbnail" 76 | }, 77 | "imageCrop": { 78 | "type": "string", 79 | "default": "landscape" 80 | }, 81 | "fallbackImg": { 82 | "type": "object", 83 | "default": "" 84 | }, 85 | "postsToShow": { 86 | "type": "integer", 87 | "default": 2 88 | }, 89 | "termDisplayPaddingLeft": { 90 | "type": "integer", 91 | "default": 20 92 | }, 93 | "termDisplayPaddingRight": { 94 | "type": "integer", 95 | "default": 20 96 | }, 97 | "termDisplayPaddingTop": { 98 | "type": "integer", 99 | "default": 10 100 | }, 101 | "termDisplayPaddingBottom": { 102 | "type": "integer", 103 | "default": 10 104 | }, 105 | "termBackgroundColor": { 106 | "type": "string", 107 | "default": "#128c20" 108 | }, 109 | "termTextColor": { 110 | "type": "string", 111 | "default": "#FFFFFF" 112 | }, 113 | "termFont": { 114 | "type": "string", 115 | "default": "inherit" 116 | }, 117 | "termFontSize": { 118 | "type": "integer", 119 | "default": 20 120 | }, 121 | "termTitle": { 122 | "type": "string", 123 | "default": "" 124 | }, 125 | "titleFont": { 126 | "type": "string", 127 | "default": "inherit" 128 | }, 129 | "titleFontSize": { 130 | "type": "integer", 131 | "default": 24 132 | }, 133 | "titleColor": { 134 | "type": "string", 135 | "default": "#000000" 136 | }, 137 | "titleColorHover": { 138 | "type": "string", 139 | "default": "#128c20" 140 | }, 141 | "containerId": { 142 | "type": "string", 143 | "default": "ptam-featured-post-list" 144 | }, 145 | "disableStyles": { 146 | "type": "boolean", 147 | "default": false 148 | }, 149 | "showMeta": { 150 | "type": "boolean", 151 | "default": true 152 | }, 153 | "showMetaAuthor": { 154 | "type": "boolean", 155 | "default": true 156 | }, 157 | "showMetaDate": { 158 | "type": "boolean", 159 | "default": true 160 | }, 161 | "showMetaComments": { 162 | "type": "boolean", 163 | "default": false 164 | }, 165 | "showFeaturedImage": { 166 | "type": "boolean", 167 | "default": true 168 | }, 169 | "showReadMore": { 170 | "type": "boolean", 171 | "default": true 172 | }, 173 | "showExcerpt": { 174 | "type": "boolean", 175 | "default": true 176 | }, 177 | "excerptLength": { 178 | "type": "integer", 179 | "default": 55 180 | }, 181 | "excerptFont": { 182 | "type": "string", 183 | "default": "inherit" 184 | }, 185 | "excerptFontSize": { 186 | "type": "integer", 187 | "default": 18 188 | }, 189 | "excerptTextColor": { 190 | "type": "string", 191 | "default": "#000000" 192 | }, 193 | "readMoreButtonText": { 194 | "type": "string", 195 | "default": "Read More" 196 | }, 197 | "readMoreButtonFont": { 198 | "type": "string", 199 | "default": "inherit" 200 | }, 201 | "readMoreButtonTextColor": { 202 | "type": "string", 203 | "default": "#000000" 204 | }, 205 | "readMoreButtonTextHoverColor": { 206 | "type": "string", 207 | "default": "#000000" 208 | }, 209 | "readMoreButtonBackgroundColor": { 210 | "type": "string", 211 | "default": "#CCCCCC" 212 | }, 213 | "readMoreButtonBackgroundHoverColor": { 214 | "type": "string", 215 | "default": "#adadad" 216 | }, 217 | "readMoreButtonBorder": { 218 | "type": "integer", 219 | "default": 0 220 | }, 221 | "readMoreButtonBorderColor": { 222 | "type": "string", 223 | "default": "inherit" 224 | }, 225 | "readMoreButtonBorderRadius": { 226 | "type": "integer", 227 | "default": 10 228 | }, 229 | "preview": { 230 | "type": "boolean", 231 | "default": false 232 | }, 233 | "showPagination": { 234 | "type": "boolean", 235 | "default": false 236 | } 237 | }, 238 | "example": { 239 | "attributes": { 240 | "preview": true 241 | } 242 | }, 243 | "editorScript": "ptam-custom-posts-gutenberg", 244 | "editorStyle": "ptam-style-editor-css" 245 | } 246 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "globals": { 4 | "wp": true, 5 | "wpApiSettings": true, 6 | "window": true, 7 | "document": true 8 | }, 9 | "env": { 10 | "browser": true, 11 | "node": true, 12 | "es6": true, 13 | "jest/globals": true 14 | }, 15 | "parserOptions": { 16 | "ecmaVersion": 6, 17 | "sourceType": "module", 18 | "ecmaFeatures": { 19 | "jsx": true, 20 | "experimentalObjectRestSpread": true 21 | } 22 | }, 23 | "extends": ["plugin:@wordpress/eslint-plugin/recommended-with-formatting"], 24 | "plugins": ["react", "jsx-a11y", "jest"], 25 | "settings": { 26 | "react": { 27 | "pragma": "wp" 28 | } 29 | }, 30 | "rules": { 31 | "array-bracket-spacing": ["error", "always"], 32 | "brace-style": ["error", "1tbs"], 33 | "camelcase": ["error", { "properties": "never" }], 34 | "comma-dangle": ["error", "always-multiline"], 35 | "comma-spacing": "error", 36 | "comma-style": "error", 37 | "computed-property-spacing": ["error", "always"], 38 | "constructor-super": "error", 39 | "dot-notation": "error", 40 | "eol-last": "error", 41 | "eqeqeq": "error", 42 | "func-call-spacing": "error", 43 | "indent": ["error", "tab", { "SwitchCase": 1 }], 44 | "jsx-a11y/label-has-for": [ 45 | "error", 46 | { 47 | "required": "id" 48 | } 49 | ], 50 | "jsx-a11y/media-has-caption": "off", 51 | "jsx-a11y/no-noninteractive-tabindex": "off", 52 | "jsx-a11y/role-has-required-aria-props": "off", 53 | "jsx-quotes": "error", 54 | "key-spacing": "error", 55 | "keyword-spacing": "error", 56 | "lines-around-comment": "off", 57 | "no-alert": "error", 58 | "no-bitwise": "error", 59 | "no-caller": "error", 60 | "no-console": "error", 61 | "no-const-assign": "error", 62 | "no-debugger": "error", 63 | "no-dupe-args": "error", 64 | "no-dupe-class-members": "error", 65 | "no-dupe-keys": "error", 66 | "no-duplicate-case": "error", 67 | "no-duplicate-imports": "error", 68 | "no-else-return": "error", 69 | "no-eval": "error", 70 | "no-extra-semi": "error", 71 | "no-fallthrough": "error", 72 | "no-lonely-if": "error", 73 | "no-mixed-operators": "error", 74 | "no-mixed-spaces-and-tabs": "error", 75 | "no-multiple-empty-lines": ["error", { "max": 1 }], 76 | "no-multi-spaces": "error", 77 | "no-multi-str": "off", 78 | "no-negated-in-lhs": "error", 79 | "no-nested-ternary": "error", 80 | "no-redeclare": "error", 81 | "no-restricted-syntax": [ 82 | "error", 83 | { 84 | "selector": "ImportDeclaration[source.value=/^@wordpress\\u002F.+\\u002F/]", 85 | "message": "Path access on WordPress dependencies is not allowed." 86 | }, 87 | { 88 | "selector": "ImportDeclaration[source.value=/^blocks$/]", 89 | "message": "Use @wordpress/blocks as import path instead." 90 | }, 91 | { 92 | "selector": "ImportDeclaration[source.value=/^components$/]", 93 | "message": "Use @wordpress/components as import path instead." 94 | }, 95 | { 96 | "selector": "ImportDeclaration[source.value=/^date$/]", 97 | "message": "Use @wordpress/date as import path instead." 98 | }, 99 | { 100 | "selector": "ImportDeclaration[source.value=/^editor$/]", 101 | "message": "Use @wordpress/editor as import path instead." 102 | }, 103 | { 104 | "selector": "ImportDeclaration[source.value=/^element$/]", 105 | "message": "Use @wordpress/element as import path instead." 106 | }, 107 | { 108 | "selector": "ImportDeclaration[source.value=/^i18n$/]", 109 | "message": "Use @wordpress/i18n as import path instead." 110 | }, 111 | { 112 | "selector": "ImportDeclaration[source.value=/^data$/]", 113 | "message": "Use @wordpress/data as import path instead." 114 | }, 115 | { 116 | "selector": "ImportDeclaration[source.value=/^utils$/]", 117 | "message": "Use @wordpress/utils as import path instead." 118 | }, 119 | { 120 | "selector": "CallExpression[callee.name=/^__|_n|_x$/]:not([arguments.0.type=/^Literal|BinaryExpression$/])", 121 | "message": "Translate function arguments must be string literals." 122 | }, 123 | { 124 | "selector": "CallExpression[callee.name=/^_n|_x$/]:not([arguments.1.type=/^Literal|BinaryExpression$/])", 125 | "message": "Translate function arguments must be string literals." 126 | }, 127 | { 128 | "selector": "CallExpression[callee.name=_nx]:not([arguments.2.type=/^Literal|BinaryExpression$/])", 129 | "message": "Translate function arguments must be string literals." 130 | } 131 | ], 132 | "no-shadow": "error", 133 | "no-undef": "error", 134 | "no-undef-init": "error", 135 | "no-unreachable": "error", 136 | "no-unsafe-negation": "error", 137 | "no-unused-expressions": "error", 138 | "no-unused-vars": "error", 139 | "no-useless-computed-key": "error", 140 | "no-useless-constructor": "error", 141 | "no-useless-return": "error", 142 | "no-var": "error", 143 | "no-whitespace-before-property": "error", 144 | "object-curly-spacing": ["error", "always"], 145 | "padded-blocks": ["error", "never"], 146 | "prefer-const": "error", 147 | "quote-props": ["error", "as-needed"], 148 | "react/display-name": "off", 149 | "react/jsx-curly-spacing": [ 150 | "error", 151 | { 152 | "when": "always", 153 | "children": true 154 | } 155 | ], 156 | "react/jsx-equals-spacing": "error", 157 | "react/jsx-indent": ["error", "tab"], 158 | "react/jsx-indent-props": ["error", "tab"], 159 | "react/jsx-key": "error", 160 | "react/jsx-tag-spacing": "error", 161 | "react/no-children-prop": "off", 162 | "react/no-find-dom-node": "warn", 163 | "react/prop-types": "off", 164 | "semi": "error", 165 | "semi-spacing": "error", 166 | "space-before-blocks": ["error", "always"], 167 | "space-before-function-paren": ["error", "never"], 168 | "space-in-parens": ["error", "always"], 169 | "space-infix-ops": ["error", { "int32Hint": false }], 170 | "space-unary-ops": [ 171 | "error", 172 | { 173 | "overrides": { 174 | "!": true 175 | } 176 | } 177 | ], 178 | "template-curly-spacing": ["error", "always"], 179 | "valid-jsdoc": ["error", { "requireReturn": false }], 180 | "valid-typeof": "error", 181 | "yoda": "off" 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /src/block/custom-post-one/block.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schemas.wp.org/trunk/block.json", 3 | "title": "Custom Posts", 4 | "apiVersion": 1, 5 | "name": "ptam/custom-posts", 6 | "category": "ptam-custom-query-blocks", 7 | "icon": "", 8 | "description": "Show a grid or list layout of custom post type archives that you can narrow down by post type, taxonomy, and term.", 9 | "keywords": ["custom post", "post type"], 10 | "version": "5.1.4", 11 | "textdomain": "post-type-archive-mapping", 12 | "attributes": { 13 | "postType": { 14 | "type": "string", 15 | "default": "post" 16 | }, 17 | "imageLocation": { 18 | "type": "string", 19 | "default": "regular" 20 | }, 21 | "changeCapitilization": { 22 | "type": "boolean", 23 | "value": false 24 | }, 25 | "imageSize": { 26 | "type": "string", 27 | "default": "ptam-block-post-grid-landscape" 28 | }, 29 | "imageTypeSize": { 30 | "type": "string", 31 | "default": "thumbnail" 32 | }, 33 | "imageType": { 34 | "type": "string", 35 | "default": "regular" 36 | }, 37 | "avatarSize": { 38 | "type": "integer", 39 | "default": 500 40 | }, 41 | "taxonomy": { 42 | "type": "string", 43 | "default": "category" 44 | }, 45 | "displayTaxonomies": { 46 | "type": "boolean", 47 | "default": true 48 | }, 49 | "taxonomyLocation": { 50 | "type": "string", 51 | "default": "regular" 52 | }, 53 | "term": { 54 | "type": "string", 55 | "default": 0 56 | }, 57 | "terms": { 58 | "type": "string", 59 | "default": "all" 60 | }, 61 | "context": { 62 | "type": "string", 63 | "default": "view" 64 | }, 65 | "className": { 66 | "type": "string" 67 | }, 68 | "postsToShow": { 69 | "type": "number", 70 | "default": 6 71 | }, 72 | "pagination": { 73 | "type": "boolean", 74 | "default": false 75 | }, 76 | "displayTitle": { 77 | "type": "boolean", 78 | "default": true 79 | }, 80 | "displayTitleLink": { 81 | "type": "boolean", 82 | "default": true 83 | }, 84 | "displayCustomFields": { 85 | "type": "boolean", 86 | "default": false 87 | }, 88 | "displayPostDate": { 89 | "type": "boolean", 90 | "default": true 91 | }, 92 | "displayPostContent": { 93 | "type": "boolean", 94 | "default": false 95 | }, 96 | "displayPostExcerpt": { 97 | "type": "boolean", 98 | "default": true 99 | }, 100 | "displayPostAuthor": { 101 | "type": "boolean", 102 | "default": true 103 | }, 104 | "displayPostImage": { 105 | "type": "boolean", 106 | "default": true 107 | }, 108 | "displayPostLink": { 109 | "type": "boolean", 110 | "default": true 111 | }, 112 | "postLayout": { 113 | "type": "string", 114 | "default": "grid" 115 | }, 116 | "columns": { 117 | "type": "integer", 118 | "default": 2 119 | }, 120 | "align": { 121 | "type": "string", 122 | "default": "center" 123 | }, 124 | "width": { 125 | "type": "string", 126 | "default": "wide" 127 | }, 128 | "order": { 129 | "type": "string", 130 | "default": "desc" 131 | }, 132 | "orderBy": { 133 | "type": "string", 134 | "default": "date" 135 | }, 136 | "imageCrop": { 137 | "type": "string", 138 | "default": "landscape" 139 | }, 140 | "readMoreText": { 141 | "type": "string", 142 | "default": "Continue Reading" 143 | }, 144 | "trimWords": { 145 | "type": "integer", 146 | "default": 55 147 | }, 148 | "titleAlignment": { 149 | "type": "string", 150 | "default": "left" 151 | }, 152 | "customFieldAlignment": { 153 | "type": "string", 154 | "default": "left" 155 | }, 156 | "imageAlignment": { 157 | "type": "string", 158 | "default": "left" 159 | }, 160 | "metaAlignment": { 161 | "type": "string", 162 | "default": "left" 163 | }, 164 | "contentAlignment": { 165 | "type": "string", 166 | "default": "left" 167 | }, 168 | "padding": { 169 | "type": "integer", 170 | "default": 0 171 | }, 172 | "border": { 173 | "type": "integer", 174 | "default": 0 175 | }, 176 | "borderRounded": { 177 | "type": "number", 178 | "default": 0 179 | }, 180 | "borderColor": { 181 | "type": "string", 182 | "default": "#000000" 183 | }, 184 | "backgroundColor": { 185 | "type": "string", 186 | "default": "inherit" 187 | }, 188 | "titleColor": { 189 | "type": "string", 190 | "default": "inherit" 191 | }, 192 | "customFieldsColor": { 193 | "type": "string", 194 | "default": "inherit" 195 | }, 196 | "linkColor": { 197 | "type": "string", 198 | "default": "inherit" 199 | }, 200 | "contentColor": { 201 | "type": "string", 202 | "default": "inherit" 203 | }, 204 | "continueReadingColor": { 205 | "type": "string", 206 | "default": "inherit" 207 | }, 208 | "titleFont": { 209 | "type": "string", 210 | "default": "inherit" 211 | }, 212 | "customFieldsFont": { 213 | "type": "string", 214 | "default": "inherit" 215 | }, 216 | "metaFont": { 217 | "type": "string", 218 | "default": "inherit" 219 | }, 220 | "contentFont": { 221 | "type": "string", 222 | "default": "inherit" 223 | }, 224 | "continueReadingFont": { 225 | "type": "string", 226 | "default": "inherit" 227 | }, 228 | "customFields": { 229 | "type": "string", 230 | "default": "" 231 | }, 232 | "removeStyles": { 233 | "type": "boolean", 234 | "default": false 235 | }, 236 | "titleHeadingTag": { 237 | "type": "string", 238 | "default": "h2" 239 | }, 240 | "fallbackImg": { 241 | "type": "object", 242 | "default": "" 243 | }, 244 | "preview": { 245 | "type": "boolean", 246 | "default": false 247 | }, 248 | "wpmlLanguage": { 249 | "type": "string", 250 | "default": "en" 251 | } 252 | }, 253 | "example": { 254 | "attributes": { 255 | "preview": true 256 | } 257 | }, 258 | "editorScript": "ptam-custom-posts-gutenberg", 259 | "editorStyle": "ptam-style-editor-css" 260 | } 261 | -------------------------------------------------------------------------------- /languages/post-type-archive-mapping.pot: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2019 Ronald Huereca 2 | # This file is distributed under the same license as the Custom Post Types Block plugin. 3 | msgid "" 4 | msgstr "" 5 | "Project-Id-Version: Custom Post Types Block 3.0.7\n" 6 | "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/post-type-archive-mapping\n" 7 | "Last-Translator: FULL NAME \n" 8 | "Language-Team: LANGUAGE \n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "POT-Creation-Date: 2019-12-08T22:10:52+00:00\n" 13 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 14 | "X-Generator: WP-CLI 2.3.0\n" 15 | "X-Domain: post-type-archive-mapping\n" 16 | 17 | #. Plugin Name of the plugin 18 | msgid "Custom Post Types Block" 19 | msgstr "" 20 | 21 | #. Plugin URI of the plugin 22 | msgid "https://mediaron.com/portfolio/post-type-archive-mapping/" 23 | msgstr "" 24 | 25 | #. Description of the plugin 26 | msgid "Map your post type archives to a page and use our Gutenberg block to show posts" 27 | msgstr "" 28 | 29 | #. Author of the plugin 30 | msgid "Ronald Huereca" 31 | msgstr "" 32 | 33 | #. Author URI of the plugin 34 | msgid "https://mediaron.com" 35 | msgstr "" 36 | 37 | #: post-type-archive-mapping.php:212 38 | msgctxt "plugin settings heading" 39 | msgid "Post Type Archive Mapping" 40 | msgstr "" 41 | 42 | #: post-type-archive-mapping.php:216 43 | msgid "Post Type Archive Mapping" 44 | msgstr "" 45 | 46 | #: post-type-archive-mapping.php:254 47 | msgid "Default" 48 | msgstr "" 49 | 50 | #: src/select-posts.php:503 51 | msgid "Newer Items" 52 | msgstr "" 53 | 54 | #: src/select-posts.php:504 55 | msgid "Older Items" 56 | msgstr "" 57 | 58 | #: dist/blocks.build.js:1 59 | msgid "All" 60 | msgstr "" 61 | 62 | #: dist/blocks.build.js:1 63 | msgid "Select a Taxonomy" 64 | msgstr "" 65 | 66 | #: dist/blocks.build.js:1 67 | msgid "Regular placement" 68 | msgstr "" 69 | 70 | #: dist/blocks.build.js:1 71 | msgid "Image Below Title" 72 | msgstr "" 73 | 74 | #: dist/blocks.build.js:1 75 | msgid "Below title and post meta" 76 | msgstr "" 77 | 78 | #: dist/blocks.build.js:1 79 | msgid "Image on bottom" 80 | msgstr "" 81 | 82 | #: dist/blocks.build.js:1 83 | msgid "H1" 84 | msgstr "" 85 | 86 | #: dist/blocks.build.js:1 87 | msgid "H2" 88 | msgstr "" 89 | 90 | #: dist/blocks.build.js:1 91 | msgid "H3" 92 | msgstr "" 93 | 94 | #: dist/blocks.build.js:1 95 | msgid "H4" 96 | msgstr "" 97 | 98 | #: dist/blocks.build.js:1 99 | msgid "H5" 100 | msgstr "" 101 | 102 | #: dist/blocks.build.js:1 103 | msgid "H6" 104 | msgstr "" 105 | 106 | #: dist/blocks.build.js:1 107 | msgid "Gravatar" 108 | msgstr "" 109 | 110 | #: dist/blocks.build.js:1 111 | msgid "Featured Image" 112 | msgstr "" 113 | 114 | #: dist/blocks.build.js:1 115 | msgid "Below Content" 116 | msgstr "" 117 | 118 | #: dist/blocks.build.js:1 119 | msgid "Left" 120 | msgstr "" 121 | 122 | #: dist/blocks.build.js:1 123 | msgid "Center" 124 | msgstr "" 125 | 126 | #: dist/blocks.build.js:1 127 | msgid "Right" 128 | msgstr "" 129 | 130 | #: dist/blocks.build.js:1 131 | msgid "Custom Posts Settings" 132 | msgstr "" 133 | 134 | #: dist/blocks.build.js:1 135 | msgid "Post Type" 136 | msgstr "" 137 | 138 | #: dist/blocks.build.js:1 139 | msgid "Taxonomy" 140 | msgstr "" 141 | 142 | #: dist/blocks.build.js:1 143 | msgid "Terms" 144 | msgstr "" 145 | 146 | #: dist/blocks.build.js:1 147 | msgid "Columns" 148 | msgstr "" 149 | 150 | #: dist/blocks.build.js:1 151 | msgid "Title" 152 | msgstr "" 153 | 154 | #: dist/blocks.build.js:1 155 | msgid "Display Title" 156 | msgstr "" 157 | 158 | #: dist/blocks.build.js:1 159 | msgid "Title Heading Tag" 160 | msgstr "" 161 | 162 | #: dist/blocks.build.js:1 163 | msgid "Custom Fields" 164 | msgstr "" 165 | 166 | #: dist/blocks.build.js:1 167 | msgid "Display Custom Fields" 168 | msgstr "" 169 | 170 | #: dist/blocks.build.js:1 171 | msgid "Enter Custom Field Markup" 172 | msgstr "" 173 | 174 | #: dist/blocks.build.js:1 175 | msgid "HTML allowed. Place custom fields inbetween {}: {custom_field_1}" 176 | msgstr "" 177 | 178 | #: dist/blocks.build.js:1 179 | msgid "Display Featured Image" 180 | msgstr "" 181 | 182 | #: dist/blocks.build.js:1 183 | msgid "Image Type" 184 | msgstr "" 185 | 186 | #: dist/blocks.build.js:1 187 | msgid "Avatar Size" 188 | msgstr "" 189 | 190 | #: dist/blocks.build.js:1 191 | msgid "Fallback Featured Image" 192 | msgstr "" 193 | 194 | #: dist/blocks.build.js:1 195 | msgid "Reset Image" 196 | msgstr "" 197 | 198 | #: dist/blocks.build.js:1 199 | msgid "Featured Image Size" 200 | msgstr "" 201 | 202 | #: dist/blocks.build.js:1 203 | msgid "Image Location" 204 | msgstr "" 205 | 206 | #: dist/blocks.build.js:1 207 | msgid "Options" 208 | msgstr "" 209 | 210 | #: dist/blocks.build.js:1 211 | msgid "Display Taxonomies" 212 | msgstr "" 213 | 214 | #: dist/blocks.build.js:1 215 | msgid "Taxonomy Location" 216 | msgstr "" 217 | 218 | #: dist/blocks.build.js:1 219 | msgid "Display Post Author" 220 | msgstr "" 221 | 222 | #: dist/blocks.build.js:1 223 | msgid "Display Post Date" 224 | msgstr "" 225 | 226 | #: dist/blocks.build.js:1 227 | msgid "Display Post Excerpt" 228 | msgstr "" 229 | 230 | #: dist/blocks.build.js:1 231 | msgid "Maximum Word Length of Excerpt" 232 | msgstr "" 233 | 234 | #: dist/blocks.build.js:1 235 | msgid "Display Pagination" 236 | msgstr "" 237 | 238 | #: dist/blocks.build.js:1 239 | msgid "Change Capitilization" 240 | msgstr "" 241 | 242 | #: dist/blocks.build.js:1 243 | msgid "Display Continue Reading Link" 244 | msgstr "" 245 | 246 | #: dist/blocks.build.js:1 247 | msgid "Customize Read More Link" 248 | msgstr "" 249 | 250 | #: dist/blocks.build.js:1 251 | msgid "Remove Styles" 252 | msgstr "" 253 | 254 | #: dist/blocks.build.js:1 255 | msgid "Alignment" 256 | msgstr "" 257 | 258 | #: dist/blocks.build.js:1 259 | msgid "Title Alignment" 260 | msgstr "" 261 | 262 | #: dist/blocks.build.js:1 263 | msgid "Custom Fields Alignment" 264 | msgstr "" 265 | 266 | #: dist/blocks.build.js:1 267 | msgid "Image Alignment" 268 | msgstr "" 269 | 270 | #: dist/blocks.build.js:1 271 | msgid "Meta Alignment" 272 | msgstr "" 273 | 274 | #: dist/blocks.build.js:1 275 | msgid "Content Alignment" 276 | msgstr "" 277 | 278 | #: dist/blocks.build.js:1 279 | msgid "Borders and Padding" 280 | msgstr "" 281 | 282 | #: dist/blocks.build.js:1 283 | msgid "Padding" 284 | msgstr "" 285 | 286 | #: dist/blocks.build.js:1 287 | msgid "Border" 288 | msgstr "" 289 | 290 | #: dist/blocks.build.js:1 291 | msgid "Border Color" 292 | msgstr "" 293 | 294 | #: dist/blocks.build.js:1 295 | msgid "Border Rounded" 296 | msgstr "" 297 | 298 | #: dist/blocks.build.js:1 299 | msgid "Background and Colors" 300 | msgstr "" 301 | 302 | #: dist/blocks.build.js:1 303 | msgid "Background Color" 304 | msgstr "" 305 | 306 | #: dist/blocks.build.js:1 307 | msgid "Title Color" 308 | msgstr "" 309 | 310 | #: dist/blocks.build.js:1 311 | msgid "Custom Fields Color" 312 | msgstr "" 313 | 314 | #: dist/blocks.build.js:1 315 | msgid "Content Color" 316 | msgstr "" 317 | 318 | #: dist/blocks.build.js:1 319 | msgid "Link Color" 320 | msgstr "" 321 | 322 | #: dist/blocks.build.js:1 323 | msgid "Continue Reading Color" 324 | msgstr "" 325 | 326 | #: dist/blocks.build.js:1 327 | msgid "Fonts" 328 | msgstr "" 329 | 330 | #: dist/blocks.build.js:1 331 | msgid "Title Font" 332 | msgstr "" 333 | 334 | #: dist/blocks.build.js:1 335 | msgid "Custom Fields Font" 336 | msgstr "" 337 | 338 | #: dist/blocks.build.js:1 339 | msgid "Meta Font" 340 | msgstr "" 341 | 342 | #: dist/blocks.build.js:1 343 | msgid "Content Font" 344 | msgstr "" 345 | 346 | #: dist/blocks.build.js:1 347 | msgid "Continue Reading Font" 348 | msgstr "" 349 | 350 | #: dist/blocks.build.js:1 351 | msgid "Custom Posts" 352 | msgstr "" 353 | 354 | #: dist/blocks.build.js:1 355 | msgid "No posts found." 356 | msgstr "" 357 | 358 | #: dist/blocks.build.js:1 359 | msgid "Grid View" 360 | msgstr "" 361 | 362 | #: dist/blocks.build.js:1 363 | msgid "List View" 364 | msgstr "" 365 | 366 | #: dist/blocks.build.js:1 367 | msgid "(Untitled)" 368 | msgstr "" 369 | -------------------------------------------------------------------------------- /includes/admin/tabs/class-settings.php: -------------------------------------------------------------------------------- 1 | tab, array( $this, 'output_settings' ), 1, 3 ); 32 | add_action( 'wp_ajax_ptam_dismiss_notice', array( $this, 'ajax_dismiss_notice' ) ); 33 | } 34 | 35 | /** 36 | * Dismiss the notice. 37 | */ 38 | public function ajax_dismiss_notice() { 39 | // Check the nonce. 40 | check_ajax_referer( 'dlx-app-nag', 'nonce' ); 41 | 42 | // Get the current user ID. 43 | $user_id = get_current_user_id(); 44 | 45 | // Set user meta to dismiss the ratings nag. 46 | update_user_meta( $user_id, 'dlx_app_nag_dismissed', true ); 47 | 48 | // Return a success message. 49 | wp_send_json_success(); 50 | } 51 | 52 | /** 53 | * Add the settings tab and callback actions. 54 | * 55 | * @param array $tabs Array of tabs. 56 | * 57 | * @return array of tabs. 58 | */ 59 | public function add_tab( $tabs ) { 60 | $tabs[] = array( 61 | 'get' => $this->tab, 62 | 'action' => 'ptam_output_' . $this->tab, 63 | 'url' => Functions::get_settings_url( $this->tab ), 64 | 'label' => _x( 'Settings', 'Tab label as settings', 'post-type-archive-mapping' ), 65 | 'icon' => 'home-heart', 66 | ); 67 | return $tabs; 68 | } 69 | 70 | /** 71 | * Add the settings main tab and callback actions. 72 | * 73 | * @param array $tabs Array of tabs. 74 | * @param string $current_tab The current tab selected. 75 | * @param string $sub_tab The current sub-tab selected. 76 | * 77 | * @return array of tabs. 78 | */ 79 | public function add_sub_tab( $tabs, $current_tab, $sub_tab ) { 80 | if ( ( ! empty( $current_tab ) || ! empty( $sub_tab ) ) && $this->tab !== $current_tab ) { 81 | return $tabs; 82 | } 83 | return $tabs; 84 | } 85 | 86 | /** 87 | * Begin settings routing for the various outputs. 88 | * 89 | * @param string $tab Current tab. 90 | * @param string $sub_tab Current sub tab. 91 | */ 92 | public function output_settings( $tab, $sub_tab = '' ) { 93 | if ( $this->tab === $tab ) { 94 | if ( empty( $sub_tab ) || $this->tab === $sub_tab ) { 95 | wp_enqueue_script( 96 | 'ptam-app-dismiss', 97 | Functions::get_plugin_url( 'includes/admin/js/app-dismiss.js' ), 98 | array(), 99 | '1.0.0', 100 | true 101 | ); 102 | wp_localize_script( 103 | 'ptam-app-dismiss', 104 | 'ptam_app_dismiss', 105 | array( 106 | 'nonce' => wp_create_nonce( 'dlx-app-nag' ), 107 | ) 108 | ); 109 | if ( isset( $_POST['submit'] ) && isset( $_POST['options'] ) ) { 110 | check_admin_referer( 'save_ptam_' . $this->tab ); 111 | $options = wp_unslash( $_POST['options'] ); // phpcs:ignore 112 | Options::update_options( $options ); 113 | printf( '

    %s

    ', esc_html__( 'Your options have been saved.', 'post-type-archive-mapping' ) ); 114 | } 115 | // Get options and defaults. 116 | $options = Options::get_options( true ); 117 | 118 | // Get dismissal meta. 119 | $dismissed = get_user_meta( get_current_user_id(), 'dlx_app_nag_dismissed', true ); 120 | if ( ! $dismissed ) : 121 | ?> 122 |
    123 |

    124 | 127 |

    128 |

    129 | 130 | 131 | 132 |

    133 |
    134 | 137 |
    138 | tab ); ?> 139 | 140 | 141 | 142 | 143 | 148 | 149 | 150 | 151 | 156 | 157 | 158 | 159 | 164 | 165 | 166 | 167 | 172 | 173 | tab 184 | ); 185 | do_action( $action, $options ); 186 | ?> 187 | 188 |
    144 | 145 | /> 146 |

    147 |
    152 | 153 | /> 154 |

    155 |
    160 | 161 | /> 162 |

    163 |
    168 | 169 | /> 170 |

    171 |
    189 | tab 200 | ); 201 | do_action( $action, $options ); 202 | ?> 203 | 204 |
    205 | tab, array( $this, 'output_settings' ), 1, 3 ); 32 | } 33 | 34 | /** 35 | * Add the settings tab and callback actions. 36 | * 37 | * @param array $tabs Array of tabs. 38 | * 39 | * @return array of tabs. 40 | */ 41 | public function add_tab( $tabs ) { 42 | $tabs[] = array( 43 | 'get' => $this->tab, 44 | 'action' => 'ptam_output_' . $this->tab, 45 | 'url' => Functions::get_settings_url( $this->tab ), 46 | 'label' => _x( 'Support', 'Tab label as support', 'post-type-archive-mapping' ), 47 | 'icon' => 'home-heart', 48 | ); 49 | return $tabs; 50 | } 51 | 52 | /** 53 | * Add the settings main tab and callback actions. 54 | * 55 | * @param array $tabs Array of tabs. 56 | * @param string $current_tab The current tab selected. 57 | * @param string $sub_tab The current sub-tab selected. 58 | * 59 | * @return array of tabs. 60 | */ 61 | public function add_sub_tab( $tabs, $current_tab, $sub_tab ) { 62 | if ( ( ! empty( $current_tab ) || ! empty( $sub_tab ) ) && $this->tab !== $current_tab ) { 63 | return $tabs; 64 | } 65 | return $tabs; 66 | } 67 | 68 | /** 69 | * Begin settings routing for the various outputs. 70 | * 71 | * @param string $tab Current tab. 72 | * @param string $sub_tab Current sub tab. 73 | */ 74 | public function output_settings( $tab, $sub_tab = '' ) { 75 | if ( $this->tab === $tab ) { 76 | if ( empty( $sub_tab ) || $this->tab === $sub_tab ) { 77 | ?> 78 | 95 |
    96 |

    97 | 98 |

    99 |
    100 |

    101 | 102 |

    103 |
    104 |
    105 |    106 |
    107 |
    108 |
    109 |

    110 | 111 |

    112 |
    113 |

    114 | 115 |

    116 |
    117 |
    118 |    119 |
    120 |
    121 |
    122 |

    123 | 124 |

    125 |
    126 |

    127 | 128 |

    129 |
    130 |
    131 |    132 |
    133 |
    134 |
    135 |

    136 | 137 |

    138 |
    139 |

    140 | 141 |

    142 |
    143 |
    144 |    145 |
    146 |
    147 |
    148 |

    149 | 150 |

    151 |
    152 |

    153 | 154 |

    155 |
    156 |
    157 |    158 |
    159 |
    160 | $plugin_meta An array of the plugin's metadata. 35 | * @param string $plugin_file Path to the plugin file relative to the plugins directory. 36 | * @return array Updated array of the plugin's metadata. 37 | */ 38 | public function filter_plugin_row_meta( array $plugin_meta, $plugin_file ) { 39 | if ( 'post-type-archive-mapping/post-type-archive-mapping.php' !== $plugin_file ) { 40 | return $plugin_meta; 41 | } 42 | 43 | $plugin_meta[] = sprintf( 44 | '%2$s', 45 | 'https://dlxplugins.com/plugins/archive-pages-pro/', 46 | esc_html_x( 'Get Archive Pages Pro', 'verb', 'post-type-archive-mapping' ) 47 | ); 48 | 49 | return $plugin_meta; 50 | } 51 | 52 | /** 53 | * Adds a plugin settings link. 54 | * 55 | * Adds a plugin settings link. 56 | * 57 | * @param array $settings The settings array for the plugin. 58 | * 59 | * @return array Settings array. 60 | */ 61 | public function plugin_settings_link( $settings ) { 62 | $admin_settings_links = array(); 63 | 64 | $admin_settings_links[] = sprintf( 65 | '%s', 66 | esc_url( Functions::get_settings_url( 'settings' ) ), 67 | esc_html__( 'Settings', 'post-type-archive-mapping' ) 68 | ); 69 | $admin_settings_links[] = sprintf( 70 | '%s', 71 | esc_url( Functions::get_settings_url( 'support' ) ), 72 | esc_html__( 'Support', 'post-type-archive-mapping' ) 73 | ); 74 | if ( ! is_array( $settings ) ) { 75 | return $admin_settings_links; 76 | } else { 77 | return array_merge( $settings, $admin_settings_links ); 78 | } 79 | } 80 | 81 | /** 82 | * Registers and outputs placeholder for settings. 83 | * 84 | * @since 1.0.0 85 | */ 86 | public static function settings_page() { 87 | ?> 88 |
    89 | 94 |
    95 | 104 | '; 117 | $tabs_count = count( $tabs ); 118 | if ( $tabs && ! empty( $tabs ) && is_array( $tabs ) ) { 119 | $active_tab = Functions::get_admin_tab(); 120 | if ( null === $active_tab ) { 121 | $active_tab = 'settings'; 122 | } 123 | $is_tab_match = false; 124 | if ( 'settings' === $active_tab ) { 125 | $active_tab = 'settings'; 126 | } else { 127 | foreach ( $tabs as $tab ) { 128 | $tab_get = isset( $tab['get'] ) ? $tab['get'] : ''; 129 | if ( $active_tab === $tab_get ) { 130 | $is_tab_match = true; 131 | } 132 | } 133 | if ( ! $is_tab_match ) { 134 | $active_tab = 'settings'; 135 | } 136 | } 137 | $do_action = false; 138 | foreach ( $tabs as $tab ) { 139 | $classes = array( 'nav-tab' ); 140 | $tab_get = isset( $tab['get'] ) ? $tab['get'] : ''; 141 | if ( $active_tab === $tab_get ) { 142 | $classes[] = 'nav-tab-active'; 143 | $do_action = isset( $tab['action'] ) ? $tab['action'] : false; 144 | } elseif ( ! $is_tab_match && 'setup' === $tab_get ) { 145 | $classes[] = 'nav-tab-active'; 146 | $do_action = isset( $tab['action'] ) ? $tab['action'] : false; 147 | } 148 | $tab_url = isset( $tab['url'] ) ? $tab['url'] : ''; 149 | $tab_label = isset( $tab['label'] ) ? $tab['label'] : ''; 150 | $tab_html .= sprintf( 151 | '%s', 152 | esc_url( $tab_url ), 153 | esc_attr( implode( ' ', $classes ) ), 154 | esc_attr( $tab_get ), 155 | esc_html( $tab['label'] ) 156 | ); 157 | } 158 | $tab_html .= ''; 159 | if ( $tabs_count > 0 ) { 160 | echo wp_kses( $tab_html, Functions::get_kses_allowed_html() ); 161 | } 162 | 163 | $current_tab = Functions::get_admin_tab(); 164 | $current_sub_tab = Functions::get_admin_sub_tab(); 165 | 166 | /** 167 | * Filer the output of the sub-tab output. 168 | * 169 | * Potentially modify or add your own sub-tabs. 170 | * 171 | * @since 5.1.0 172 | * 173 | * @param array Associative array of tabs. 174 | * @param string Tab 175 | * @param string Sub Tab 176 | */ 177 | $sub_tabs = apply_filters( 'ptam_admin_sub_tabs', array(), $current_tab, $current_sub_tab ); 178 | 179 | // Check to see if no tabs are available for this view. 180 | if ( null === $current_tab && null === $current_sub_tab ) { 181 | $current_tab = 'settings'; 182 | } 183 | if ( $sub_tabs && ! empty( $sub_tabs ) && is_array( $sub_tabs ) ) { 184 | if ( null === $current_sub_tab ) { 185 | $current_sub_tab = ''; 186 | } 187 | $is_tab_match = false; 188 | $first_sub_tab = current( $sub_tabs ); 189 | $first_sub_tab_get = $first_sub_tab['get']; 190 | if ( $first_sub_tab_get === $current_sub_tab ) { 191 | $active_tab = $current_sub_tab; 192 | } else { 193 | $active_tab = $current_sub_tab; 194 | foreach ( $sub_tabs as $tab ) { 195 | $tab_get = isset( $tab['get'] ) ? $tab['get'] : ''; 196 | if ( $active_tab === $tab_get ) { 197 | $is_tab_match = true; 198 | } 199 | } 200 | if ( ! $is_tab_match ) { 201 | $active_tab = $first_sub_tab_get; 202 | } 203 | } 204 | $sub_tab_html_array = array(); 205 | $do_subtab_action = false; 206 | $maybe_sub_tab = ''; 207 | foreach ( $sub_tabs as $sub_tab ) { 208 | $classes = array( 'ptam-sub-tab' ); 209 | $tab_get = isset( $sub_tab['get'] ) ? $sub_tab['get'] : ''; 210 | if ( $active_tab === $tab_get ) { 211 | $classes[] = 'ptam-sub-tab-active'; 212 | $do_subtab_action = true; 213 | $current_sub_tab = $tab_get; 214 | } elseif ( ! $is_tab_match && $first_sub_tab_get === $tab_get ) { 215 | $classes[] = 'ptam-sub-tab-active'; 216 | $do_subtab_action = true; 217 | $current_sub_tab = $first_sub_tab_get; 218 | } 219 | $tab_url = isset( $sub_tab['url'] ) ? $sub_tab['url'] : ''; 220 | $tab_label = isset( $sub_tab['label'] ) ? $sub_tab['label'] : ''; 221 | if ( $current_sub_tab === $tab_get ) { 222 | $sub_tab_html_array[] = sprintf( '%s', esc_attr( implode( ' ', $classes ) ), esc_attr( $tab_get ), esc_html( $sub_tab['label'] ) ); 223 | } else { 224 | $sub_tab_html_array[] = sprintf( '%s', esc_url( $tab_url ), esc_attr( implode( ' ', $classes ) ), esc_attr( $tab_get ), esc_html( $sub_tab['label'] ) ); 225 | } 226 | } 227 | if ( ! empty( $sub_tab_html_array ) ) { 228 | echo ''; 229 | } 230 | if ( $do_subtab_action ) { 231 | /** 232 | * Perform a sub tab action. 233 | * 234 | * Perform a sub tab action. Useful for loading scripts or inline styles as necessary. 235 | * 236 | * @since 5.1.0 237 | * 238 | * mpp_admin_sub_tab_{current_tab}_{current_sub_tab} 239 | * @param string Sub Tab 240 | */ 241 | do_action( 242 | sprintf( // phpcs:ignore 243 | 'ptam_admin_sub_tab_%s_%s', 244 | sanitize_title( $current_tab ), 245 | sanitize_title( $current_sub_tab ) 246 | ) 247 | ); 248 | } 249 | } 250 | if ( $do_action ) { 251 | 252 | /** 253 | * Perform a tab action. 254 | * 255 | * Perform a tab action. 256 | * 257 | * @since 5.1.0 258 | * 259 | * @param string $action Can be any action. 260 | * @param string Tab 261 | * @param string Sub Tab 262 | */ 263 | do_action( $do_action, $current_tab, $current_sub_tab ); 264 | } 265 | } 266 | ?> 267 | 275 |
    276 |

    277 | 278 | 279 |

    280 |

    281 | 289 |
    290 | 2 | 3 | 4 | Generated by IcoMoon 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/fonts/ptam.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by IcoMoon 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/block/style.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Post grid styles 3 | * Loads on front end and back end 4 | */ 5 | @import '../common'; 6 | 7 | .entry-content { 8 | .ptam-block-post-grid-title { 9 | margin-top: 0; 10 | margin-bottom: 15px; 11 | font-size: 28px; 12 | line-height: 1.2; 13 | clear: none; 14 | &:before { 15 | display: none; 16 | } 17 | &:after { 18 | display: none; 19 | } 20 | 21 | a { 22 | color: #000; 23 | box-shadow: none; 24 | transition: .3s ease; 25 | } 26 | } 27 | } 28 | .ptam-block-post-grid { 29 | margin: 0 0 1.2em 0; 30 | position: relative; 31 | 32 | .is-grid { 33 | display: grid; 34 | grid-template-columns: 1fr 1fr; 35 | grid-template-rows: 1fr; 36 | grid-gap: 0 2em; 37 | column-gap: 2em; 38 | line-height: 1.1; 39 | 40 | article { 41 | margin-bottom: 2.5em; 42 | } 43 | } 44 | 45 | .is-grid.columns-1 { 46 | grid-template-columns: 1fr; 47 | } 48 | 49 | .is-grid.columns-2 { 50 | grid-template-columns: 1fr 1fr; 51 | @media only screen and (max-width: 600px) { 52 | grid-template-columns: 1fr; 53 | } 54 | } 55 | 56 | .is-grid.columns-3 { 57 | grid-template-columns: 1fr 1fr 1fr; 58 | @media only screen and (max-width: 600px) { 59 | grid-template-columns: 1fr 1fr; 60 | } 61 | } 62 | 63 | .is-grid.columns-4 { 64 | grid-template-columns: 1fr 1fr 1fr 1fr; 65 | @media only screen and (max-width: 800px) { 66 | grid-template-columns: 1fr 1fr 1fr; 67 | } 68 | } 69 | 70 | .is-grid.columns-5 { 71 | grid-template-columns: 1fr 1fr 1fr 1fr 1fr; 72 | @media only screen and (max-width: 1000px) { 73 | grid-template-columns: 1fr 1fr 1fr 1fr; 74 | } 75 | @media only screen and (max-width: 800px) { 76 | grid-template-columns: 1fr 1fr 1fr; 77 | } 78 | } 79 | 80 | .is-grid.columns-6 { 81 | grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr; 82 | @media only screen and (max-width: 1000px) { 83 | grid-template-columns: 1fr 1fr 1fr 1fr; 84 | } 85 | @media only screen and (max-width: 800px) { 86 | grid-template-columns: 1fr 1fr 1fr; 87 | } 88 | } 89 | 90 | div[class*="columns"].is-grid { 91 | @media only screen and (max-width: 600px) { 92 | grid-template-columns: 1fr; 93 | } 94 | } 95 | 96 | .ptam-post-grid-items .has_thumb .ptam-block-post-grid-image { 97 | 98 | } 99 | 100 | .ptam-block-post-grid-image { 101 | margin: 10px 0; 102 | img { 103 | display: inline-block; 104 | } 105 | } 106 | .is-list .ptam-block-post-grid-image { 107 | margin-top: 0; 108 | } 109 | 110 | .ptam-block-post-grid-text { 111 | text-align: left; 112 | } 113 | 114 | .ptam-block-post-grid-image .avatar { 115 | height: auto; 116 | width: inherit; 117 | border-radius: 0; 118 | } 119 | 120 | .ptam-block-post-grid-title { 121 | margin-top: 0; 122 | margin-bottom: 15px; 123 | font-size: 28px; 124 | line-height: 1.2; 125 | clear: none; 126 | &:before { 127 | display: none; 128 | } 129 | &:after { 130 | display: none; 131 | } 132 | 133 | a { 134 | color: #000; 135 | box-shadow: none; 136 | transition: .3s ease; 137 | } 138 | } 139 | 140 | .ptam-block-post-grid-byline { 141 | text-transform: uppercase; 142 | font-size: 13px; 143 | letter-spacing: 1px; 144 | color: $lightgray; 145 | margin-bottom: 15px; 146 | } 147 | 148 | .ptam-text-lower-case { 149 | text-transform: none; 150 | } 151 | 152 | .ptam-block-post-grid-author, 153 | .ptam-block-post-grid-date { 154 | display: inline-block; 155 | 156 | &:not(:last-child):after { 157 | content: "\B7"; 158 | vertical-align: middle; 159 | margin: 0 5px; 160 | line-height: 1; 161 | } 162 | } 163 | 164 | .ptam-block-post-grid-author a { 165 | box-shadow: unset; 166 | 167 | &:hover { 168 | color: inherit; 169 | text-decoration: none; 170 | box-shadow: unset; 171 | } 172 | } 173 | 174 | .ptam-block-post-grid-text p { 175 | margin: 0 0 15px 0; 176 | line-height: 1.5; 177 | font-size: 18px; 178 | 179 | @media only screen and (max-width: 600px) { 180 | font-size: 16px; 181 | } 182 | 183 | &:last-of-type { 184 | margin-bottom: 0; 185 | } 186 | } 187 | 188 | .ptam-block-post-grid-link { 189 | display: inline-block; 190 | box-shadow: none; 191 | transition: .3s ease; 192 | font-weight: bold; 193 | color: #000; 194 | 195 | &:hover { 196 | box-shadow: 0 -2px 0 inset; 197 | } 198 | } 199 | 200 | .ptam-block-post-grid-excerpt div + p { 201 | margin-top: 15px; 202 | } 203 | 204 | .is-list { 205 | article { 206 | display: grid; 207 | grid-template-columns: 30% 1fr; 208 | grid-template-rows: 1fr; 209 | grid-gap: 0 2em; 210 | &:not(:last-child) { 211 | margin-bottom: 5%; 212 | padding-bottom: 5%; 213 | } 214 | 215 | @media only screen and (min-width: 600px) { 216 | &:not(:last-child) { 217 | border-bottom: solid 1px #eee; 218 | } 219 | } 220 | 221 | @media only screen and (max-width: 600px) { 222 | grid-template-columns: 1fr; 223 | } 224 | } 225 | &.is-custom article { 226 | display: block; 227 | grid-template-columns: 100% 1fr; 228 | grid-template-rows: 1fr; 229 | grid-gap: 0 2em; 230 | } 231 | 232 | .ptam-block-post-grid-image { 233 | margin-bottom: 0; 234 | 235 | @media only screen and (max-width: 600px) { 236 | margin-bottom: 5%; 237 | } 238 | } 239 | h1.ptam-block-post-grid-title { 240 | @media only screen and (min-width: 600px) { 241 | font-size: 38px; 242 | } 243 | margin-top: 10px 0; 244 | } 245 | h2.ptam-block-post-grid-title { 246 | @media only screen and (min-width: 600px) { 247 | font-size: 34px; 248 | } 249 | margin-top: 10px 0; 250 | } 251 | h3.ptam-block-post-grid-title { 252 | @media only screen and (min-width: 600px) { 253 | font-size: 34px; 254 | } 255 | margin-top: 10px 0; 256 | } 257 | h4.ptam-block-post-grid-title { 258 | @media only screen and (min-width: 600px) { 259 | font-size: 28px; 260 | } 261 | margin-top: 10px 0; 262 | } 263 | h5.ptam-block-post-grid-title { 264 | @media only screen and (min-width: 600px) { 265 | font-size: 22px; 266 | } 267 | margin-top: 10px 0; 268 | } 269 | h6.ptam-block-post-grid-title { 270 | @media only screen and (min-width: 600px) { 271 | font-size: 18px; 272 | } 273 | margin-top: 10px 0; 274 | } 275 | 276 | .no-thumb .ptam-block-post-grid-text { 277 | grid-column: span 1; 278 | } 279 | } 280 | } 281 | button.ptam-media-alt-upload.components-button { 282 | margin-bottom: 20px; 283 | } 284 | button.ptam-media-alt-reset.components-button { 285 | margin: 15px 0; 286 | } 287 | /* Search Styles */ 288 | .ptam-term-select, 289 | .ptam-term-exclude { 290 | .woocommerce-search-list__selected-header { 291 | button { 292 | display: block; 293 | margin: 1em 0; 294 | } 295 | } 296 | .woocommerce-search-list__selected { 297 | margin-bottom: 15px; 298 | } 299 | .woocommerce-tag.has-remove { 300 | display: flex; 301 | align-items: center; 302 | justify-content: space-between; 303 | background: #FFF; 304 | padding: 10px 20px; 305 | border: 1px solid #EEE; 306 | color: #000; 307 | 308 | .woocommerce-tag__remove { 309 | display: block; 310 | align-self: flex-end; 311 | } 312 | } 313 | } 314 | 315 | /* Term Grid */ 316 | .ptam-term-grid-loading { 317 | display: flex; 318 | flex-wrap: wrap; 319 | justify-content: center; 320 | align-items: center; 321 | text-align: center; 322 | width: 100%; 323 | h1 { 324 | width: 100%; 325 | text-align: center; 326 | } 327 | } 328 | .ptam-term-grid { 329 | /* Grid Fallback */ 330 | position: relative; 331 | display: flex; 332 | flex-wrap: wrap; 333 | 334 | display: grid; 335 | grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); 336 | grid-auto-rows: minmax(150px, auto); 337 | grid-gap: 1em; 338 | justify-items: center; 339 | 340 | &.columns-1 { 341 | grid-template-columns: 1fr; 342 | } 343 | 344 | &.columns-2 { 345 | grid-template-columns: 1fr 1fr; 346 | @media only screen and (max-width: 500px) { 347 | grid-template-columns: 1fr; 348 | } 349 | } 350 | 351 | &.columns-3 { 352 | grid-template-columns: 1fr 1fr 1fr; 353 | @media only screen and (max-width: 600px) { 354 | grid-template-columns: 1fr 1fr; 355 | } 356 | @media only screen and (max-width: 500px) { 357 | grid-template-columns: 1fr; 358 | } 359 | } 360 | 361 | &.columns-4 { 362 | grid-template-columns: 1fr 1fr 1fr 1fr; 363 | @media only screen and (max-width: 800px) { 364 | grid-template-columns: 1fr 1fr 1fr; 365 | } 366 | @media only screen and (max-width: 600px) { 367 | grid-template-columns: 1fr 1fr; 368 | } 369 | @media only screen and (max-width: 500px) { 370 | grid-template-columns: 1fr; 371 | } 372 | } 373 | .ptam-term-grid-anchor-full { 374 | position: absolute; 375 | z-index: 3; 376 | display: block; 377 | width: 100%; 378 | height: 100%; 379 | } 380 | 381 | .ptam-term-grid-item { 382 | position: relative; 383 | display: flex; 384 | flex-wrap: wrap; 385 | align-items: center; 386 | justify-content: center; 387 | min-height: 300px; 388 | width: 100%; 389 | background: #24292d; 390 | color: #FFF; 391 | background-size: cover; 392 | background-repeat: no-repeat; 393 | background-position: center center; 394 | text-align: center; 395 | padding: 20px; 396 | overflow: hidden; 397 | transition: background-color 0.5s ease; 398 | word-break: break-all; 399 | box-sizing: border-box; 400 | 401 | /* Flex Fallback */ 402 | margin-left: 5px; 403 | margin-right: 5px; 404 | flex: 1 1 300px; 405 | 406 | .ptam-term-grid-item-content { 407 | position: relative; 408 | z-index: 2; 409 | } 410 | .ptam-term-grid-button { 411 | display: inline-block; 412 | background-color: #32373c; 413 | color: #FFF; 414 | border: none; 415 | border-radius: 28px; 416 | font-weight: 500; 417 | box-shadow: none; 418 | cursor: pointer; 419 | display: inline-block; 420 | font-size: 18px; 421 | margin: 0; 422 | margin-top: 1em; 423 | padding: 12px 24px; 424 | text-align: center; 425 | text-decoration: none; 426 | overflow-wrap: break-word; 427 | transition: background-color 0.5s ease; 428 | } 429 | h2 { 430 | color: #FFFFFF; 431 | font-size: 2.2em; 432 | } 433 | .ptam-term-grid-item-description { 434 | font-size: 1.4em; 435 | line-height: 1.5em; 436 | } 437 | } 438 | } 439 | 440 | /* Featured Post Styles */ 441 | .ptam-fp-wrapper { 442 | .ptam-fp-term { 443 | margin-bottom: 20px; 444 | span { 445 | display: inline-block; 446 | } 447 | } 448 | .ptam-featured-post-item { 449 | padding-bottom: 1.3em; 450 | border-bottom: 1px solid #DDD; 451 | &:last-child { 452 | border-bottom: 0; 453 | } 454 | } 455 | .ptam-featured-post-meta { 456 | .entry-title { 457 | font-weight: 700; 458 | line-height: 1.4em; 459 | margin: 1em 0; 460 | a { 461 | color: #000000; 462 | text-decoration: none; 463 | &:hover { 464 | color: #000000; 465 | text-decoration: none; 466 | } 467 | } 468 | } 469 | .entry-meta { 470 | display: flex; 471 | flex-wrap: wrap; 472 | justify-content: space-between; 473 | margin-bottom: 1em; 474 | font-size: 12px; 475 | .author-name { 476 | a { 477 | font-weight: 700; 478 | color: #6c6c6c; 479 | text-decoration: none; 480 | &:hover { 481 | color: #333; 482 | text-decoration: none; 483 | } 484 | &:before { 485 | font-family: 'PTAM'; 486 | content: '\e71e'; 487 | display: inline-block; 488 | margin-right: 2px; 489 | } 490 | } 491 | } 492 | .post-date { 493 | color: #6c6c6c; 494 | &:before { 495 | font-family: 'PTAM'; 496 | content: '\e789'; 497 | display: inline-block; 498 | margin-right: 2px; 499 | } 500 | } 501 | .post-comments { 502 | color: #000; 503 | &:before { 504 | font-family: 'PTAM'; 505 | content: '\e7d6'; 506 | display: inline-block; 507 | margin-right: 2px; 508 | } 509 | } 510 | } 511 | } 512 | .ptam-featured-post-content { 513 | line-height: 1.2em; 514 | margin: 1em 0; 515 | } 516 | .ptam-featured-post-button { 517 | a { 518 | display: inline-block; 519 | padding: 10px 20px; 520 | text-decoration: none; 521 | :hover { 522 | text-decoration: none; 523 | } 524 | } 525 | } 526 | /* Uncomment to have a zoom effect on hover. 527 | .ptam-featured-post-image { 528 | overflow: hidden; 529 | img { 530 | transition: transform .8s; 531 | &:hover { 532 | transform: scale( 1.1 ); 533 | } 534 | } 535 | }*/ 536 | } 537 | 538 | .ptam-pagination, 539 | body.has-blocks .fl-post-content .ptam-pagination { 540 | > ul { 541 | list-style-type: none; 542 | margin: 0; 543 | padding: 0; 544 | } 545 | li { 546 | display: inline-block; 547 | 548 | & > span, 549 | & > a { 550 | display: inline-block; 551 | padding: 5px 10px; 552 | margin: 0 4px 0 0; 553 | border: 1px solid #eee; 554 | line-height: 1; 555 | text-decoration: none; 556 | border-radius: 2px; 557 | font-weight: 600; 558 | } 559 | & > span:hover, 560 | & > a:hover { 561 | background: #f9f9f9; 562 | } 563 | & > span.current { 564 | background: #f9f9f9; 565 | } 566 | } 567 | } 568 | .ptam-apply { 569 | margin-top: 15px; 570 | margin-bottom: 20px; 571 | } 572 | .ptam-term-select .woocommerce-search-list__selected, 573 | .ptam-term-exclude .woocommerce-search-list__selected { 574 | display: none; 575 | } 576 | .ptam-term-select .components-base-control__field, 577 | .ptam-term-exclude .components-base-control__field { 578 | display: none; 579 | } 580 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | === Custom Query Blocks === 2 | Contributors: ronalfy, chrislogan, paaljoachim 3 | Tags: map pages, archives, post type block, 404 page, category grid 4 | Requires at least: 5.5 5 | Requires PHP: 5.6 6 | Tested up to: 6.9 7 | Stable tag: 5.4.0 8 | License: GPLv2 or later 9 | License URI: http://www.gnu.org/licenses/gpl-2.0.html 10 | Donate link: https://github.com/MediaRon/post-type-archive-mapping 11 | 12 | Map your archives to pages. Map 404 and term archives as well. 13 | 14 | == Description == 15 | 16 | A WordPress plugin for displaying posts and terms (e.g., categories) using a Gutenberg block. Works well with posts, pages, custom post types, taxonomies, and terms. 17 | 18 | Bonus: archive mapping. 19 | 20 | > **Archive Pages Pro is here**: Map post types, terms, authors, and more to pages. Learn more about Archive Pages Pro 21 | 22 |
      23 |
    • Map your post type archives to a page for customization of the post type archive page.
    • 24 |
    • Map your category archives to a page for customization of the term archive page.
    • 25 |
    • Map your 404 template to a page and easily customize your 404 page.
    • 26 |
    27 | 28 | View Documentation and Overview 29 | 30 | The plugin currently has three blocks: 31 | 32 | * Custom Post Types Block 33 | * Term (Category) Grid Block 34 | * Featured Posts by Category Block 35 | 36 | === Post Type Archive Mapping === 37 | 38 | This plugin allows you to map your custom post type archive pages. Just create a page and go to Settings->Reading to set the page for your archive. 39 | 40 | Ensure your post types have has_archive set to true. 41 | 42 |
      43 |
    • Select a Public page to use as your post type archive page.
    • 44 |
    • View the archive and you will see the page content instead of the archive content.
    • 45 |
    • Use page templates on your pages for flexibility.
    • 46 |
    • Custom Gutenberg block for showing your posts.
    • 47 |
    48 | 49 | === Term Archive Mapping === 50 | 51 | This plugin also allows you to map your term archives to a page. Just create a page and go edit your term to set the archive page. 52 | 53 |
      54 |
    • Create a public page to use as your term archive.
    • 55 |
    • Visit the edit term page and select the page.
    • 56 |
    • View the term and you will see your selected page.
    • 57 |
    • Use Gutenberg on your public page to customize the archive.
    • 58 |
    59 | 60 | === 404 Page Mapping === 61 | 62 | This plugin allows you to map a page to your 404 template, so you can customize a 404 page as needed. 63 | 64 | === Development is on GitHub === 65 | 66 | Development is on GitHub 67 | 68 | === Archive Pages Pro === 69 | 70 | Archive Pages Pro has all the mapping feature of this plugin and more. You can map post types, terms, authors, and more to pages. Learn more about Archive Pages Pro 71 | 72 | == Installation == 73 | 74 | 1. Just unzip and upload the "post-type-archive-mapping" folder to your '/wp-content/plugins/' directory 75 | 2. Activate the plugin through the 'Plugins' menu in WordPress 76 | 77 | Post Type Archive Mapping 78 | 79 | 1. Create a custom post type that has an archive 80 | 2. Create a page with a custom template. Use the Gutenberg block to show off posts in that Custom Post Type. 81 | 3. Go to Settings->Reading and assign the page to the custom post type archive 82 | 4. Go to the post type archive and observe the page content is now the archive 83 | 84 | Term Archive Mapping 85 | 86 | 1. Create a public page to use as your term archive. 87 | 2. Visit the edit term page and select the page. 88 | 3. View the term and you will see your selected page. 89 | 4. Use Gutenberg on your public page to customize the archive. 90 | 91 | 404 Template Mapping 92 | 93 | 1. Visit Settings->Reading and map your 404 template to a page. 94 | 2. Customize the new 404 page. 95 | 3. Navigate to a broken URL to preview the 404 page. 96 | 97 | == Frequently Asked Questions == 98 | 99 | = I don't see the post types. What's wrong? = 100 | 101 | Make sure your post type has has_archive set to true and show_in_rest set to true. 102 | 103 | = Can you do posts instead of pages? = 104 | 105 | This plugin will only allow mapping to pages. 106 | 107 | = Does this plugin work with term (e.g., category) archives? = 108 | 109 | Yes. Edit a term and you can map it to any page. 110 | 111 | = I need help. Can you help me? = 112 | 113 | Yes, just post in the support forums here and I'll do my best to address your issue. 114 | 115 | == Screenshots == 116 | 117 | 1. Setting up the custom post types block. 118 | 2. Styling the block. 119 | 3. New Term Grid Block. 120 | 4. Settings->Reading option. 121 | 5. Term archive option. 122 | 123 | == Changelog == 124 | 125 | = 5.4.0 = 126 | * Released 2025-11-15 127 | * Resolving XSS vulnerability with title tag as reported via Patchstack. Ensuring compatibility with WP 6.9. 128 | 129 | = 5.3.1 = 130 | * Released 2024-08-27 131 | * Fixing some deprecation notices in blocks. 132 | * Adding information about new plugin Archive Pages Pro. 133 | * Misc. copy updates. 134 | 135 | = 5.3.0 = 136 | * Released 2024-07-10 137 | * Hardening REST APIs based on security report from the WordPress security team. 138 | * This is a security release and we recommend updating as soon as possible. 139 | 140 | = 5.2.0 = 141 | * Released 2024-03-17 142 | * Fixing a bug in the Term Grid block where the SearchListControl in Woo Components was throwing an error, so the component was reworked. 143 | 144 | = 5.1.6 = 145 | * Released 2023-03-17 146 | * Fixing a bug where the term grid didn't show on the frontend. 147 | 148 | = 5.1.5 = 149 | * Released 2022-10-02 150 | * Fixing a bug where a term would not save in the custom post types block. 151 | 152 | = 5.1.4 = 153 | * Released 2022-10-01 154 | * Updated build scripts. 155 | * Fixing schema errors when it comes to registering attributes. 156 | 157 | = 5.1.2 = 158 | * Released 2021-07-28 159 | * Fixing block categories for WP 5.8. 160 | 161 | = 5.1.0 = 162 | * Released 2021-03-25 163 | * Seeking volunteer devs if you want to learn blocks and help lower the build size. 164 | * Feature: Can disable post type mapping via the settings page. 165 | * Feature: Can disable the blocks via the settings page. 166 | * Feature: Can disable the columns on the pages screen. 167 | * Feature: Can disable the created image sizes. 168 | * Feature: New admin options to enable/disable settings. 169 | * Bug fix: Selecting individual terms in the term block would not reflect on the front-end. 170 | * Misc: Removing block icon from the Add Blocks screen. 171 | * Misc: Updating block icons and color scheme. 172 | * Bug fix: Tweaking word-break in the terms block. 173 | 174 | = 5.0.6 = 175 | * Released 2021-03-09 176 | * Fixing term saving causing archives to fail. 177 | 178 | = 5.0.5 = 179 | * Released 2021-02-12 180 | * Mapping to pages now shows a hierachy to more easily select pages. 181 | * New branding. Hopefully less spammy. 182 | * Making readme more descriptive of what the plugin does. 183 | 184 | = 5.0.1 = 185 | * Released 2021-02-12 186 | * Fixed the Term block with the block erroring out when modifying the query parameters. 187 | * Testing with WordPress 5.7. 188 | 189 | = 5.0.0 = 190 | * Released 2020-09-07 191 | * Added ability to map 404 to a page. 192 | * Fixed Gutenberg bugs in the Custom Post Types block and Featured Posts block. 193 | 194 | = 4.5.5 = 195 | * Released 2020-08-23 196 | * Minimium supported version is now WordPress 5.5 197 | * Fixed pagination for WP 5.5. 198 | * Fixed REST API errors for WP 5.5. 199 | * Miscellaneous block fixes and updates. 200 | 201 | = 4.5.3 = 202 | * Released 2020-05-17 203 | * Added Polylang support when mapping posts. Added WPML support for the main Custom Post Types block. 204 | 205 | = 4.5.2 = 206 | * Released 2020-05-01 207 | * Removing the term redirect as some pages would get "stuck." 208 | 209 | = 4.5.1 = 210 | * Released 2020-04-29 211 | * Added pagination to the Featured Posts by Category Block. 212 | 213 | = 4.5.0 = 214 | * Released 2020-04-20 215 | * Added featured posts by category block. 216 | * Added block previews. 217 | * New plugin name: Custom Query Blocks 218 | 219 | = 4.0.5 - 220 | * Released 2020-04-16 221 | * Added compatibility for Yoast SEO. 222 | 223 | = 4.0.1 = 224 | * Released 2020-04-12 225 | * New block: Term (Category) Grid Block. 226 | * HOT FIX: Term Grid wasn't loading. 227 | 228 | = 3.3.5 = 229 | * Released 2020-04-07 230 | * Updated plugin architecture. 231 | * Show mapped pages and its own column. 232 | * Mapped term pages now redirect to the correct term. 233 | * Added new contributor: Paal Joachim. 234 | 235 | = 3.3.1 = 236 | * Released 2020-04-01 237 | * Fixing PHP notice saying invalid argument for foreach statement. 238 | 239 | = 3.3.0 = 240 | 241 | * Released 2020-03-11 242 | * New full post mode for showing off the full post. 243 | * Option to remove the link from the title. 244 | 245 | = 3.2.2 = 246 | * Released 2020-02-10 247 | * Plugin was having conflicts with other admin screens when saving terms, resulting in a 403 error. 248 | 249 | = 3.2.1 = 250 | * Released 2020-02-03 251 | * Added support for translations. 252 | * Revised loading screen to make it easier on translators. 253 | 254 | = 3.2.0 = 255 | * Released 2020-02-03 256 | * Added ability to map term archives to pages. 257 | 258 | = 3.1.1 = 259 | * Released 2020-02-01 260 | * Added several order and orderby parameters. 261 | 262 | = 3.1.0 = 263 | * Released 2020-01-26 264 | * Removing custom field placeholder if a custom field isn't present. 265 | * Removing continue reading link and post link if custom post type isn't publicly queryable. 266 | * Wrapping excerpt in paragraph tag. 267 | * Add class to readmore paragraph tag for styling. 268 | * Hiding styles options if override styles is present. 269 | * Changing verbiage of remove styles to Override styles. 270 | * Added support for Adobe fonts through https://wordpress.org/plugins/custom-typekit-fonts/ 271 | 272 | = 3.0.9 = 273 | 274 | * Released 2019-12-08 275 | * Added the ability to set a fallback image for the featured image. 276 | 277 | = 3.0.7 = 278 | 279 | * Released 2019-12-05 280 | * Fixing pagination when a page with the Gutenberg block is set as the front page. 281 | 282 | = 3.0.6 = 283 | 284 | * Released 2019-12-05 285 | * Moving featured image to its own panel in Gutenberg settings. 286 | * Moving title to its own panel in Gutenberg settings. 287 | * Cleaning up editor styles for headings. 288 | * Adding ability to change the heading HTML tag. 289 | 290 | = 3.0.5 = 291 | * Released 2019-12-05 292 | * Adding ability to remove styles so that you can style your own layout. 293 | 294 | = 3.0.0 = 295 | * Released 2019-12-03 296 | * Adding custom field support. 297 | * Updating REST API for faster loading. 298 | 299 | = 2.2.2 = 300 | * Released 2019-12-02 301 | * Added ability to remove title from displaying. 302 | * Added new branded loading animation. 303 | 304 | = 2.2.1 = 305 | * Released 2019-10-29 306 | * Testing up to WordPress 5.3. 307 | * Fixing JS error when jQuery is not defined as a $ variable. 308 | 309 | = 2.2.0 = 310 | * Released 2019-08-23 311 | * Bug fix when in grid mode and image is placed below the title. 312 | * Bug fix: skipping taxonomies when there are none. 313 | * Bug fix: fixing capitalization error. 314 | * Enhancement: You can now select fonts for your content areas. 315 | 316 | = 2.1.2 = 317 | * Released 2019-06-11 318 | * Fixing pagination 319 | 320 | = 2.1.1 = 321 | * Released 2019-05-26 322 | * Some users were seeing featured images twice in the back-end. 323 | 324 | = 2.1.0 = 325 | * Released 2019-05-25 326 | * Fixed Gravatar sizing not saving. 327 | * Changing the way excerpts are shown in Gutenberg. 328 | * Added the ability to change taxonomy location. 329 | * Content can now be centered in the Grid view. 330 | * Added border, padding, and background style options in Gutenberg block. 331 | * Added color options for text in Gutenberg block. 332 | 333 | = 2.0.7 = 334 | * Released 2019-05-24 335 | * Added the ability to trim the excerpt length. 336 | * Reduce the file size of the Gutenberg block script using a new build technique. 337 | 338 | = 2.0.5 = 339 | * Released 2019-04-21 340 | * Conditional term filtering 341 | 342 | = 2.0.4 = 343 | * Released 2019-04-18 344 | * Adding support for six columns 345 | * Fixing undefined index error 346 | 347 | = 2.0.3 = 348 | * Released 2019-03-29 349 | * Fixed term not being saved when displaying posts 350 | 351 | = 2.0.1 = 352 | * Released 2019-01-17 353 | * Fixed pagination when using a page with just the block 354 | 355 | = 2.0.1 = 356 | * Released 2019-01-17 357 | * Fixing bug where arguments weren't an array when switching reading types in Settings->Reading. 358 | 359 | = 2.0.0 = 360 | * Released 2019-01-06 361 | * Numerous enhancements to the Gutenberg block including showing taxonomies, setting the image type (Avatar vs Regular), setting where the featured image is displayed, selecting the image size, and much more. 362 | 363 | = 1.0.1 = 364 | * Released 2018-11-07 365 | * WordPress 5.0 compatibility 366 | 367 | = 1.0.0 = 368 | * Released 2018-09-24 369 | * Initial release. 370 | 371 | == Upgrade Notice == 372 | 373 | = 5.4.0 = 374 | Resolving XSS vulnerability with title tag as reported via Patchstack. Ensuring compatibility with WP 6.9. -------------------------------------------------------------------------------- /dist/blockstyles.css: -------------------------------------------------------------------------------- 1 | @font-face{font-family:"PTAM";src:url("../fonts/ptam.eot");src:url("../fonts/ptam.eot?#iefix") format("embedded-opentype"),url("../fonts/ptam.woff2") format("woff2"),url("../fonts/ptam.woff") format("woff"),url("../fonts/ptam.ttf") format("truetype"),url("../fonts/ptam.svg#svgFontName") format("svg")}@media only screen and (min-width: 600px){div[class*=wp-block-atomic].ptam-font-size-14.ptam-block-testimonial p,div[class*=wp-block-atomic].ptam-font-size-14.ptam-block-notice p,div[class*=wp-block-atomic].ptam-font-size-14.ptam-block-profile p,div[class*=wp-block-atomic].ptam-font-size-14.ptam-block-accordion p,div[class*=wp-block-atomic].ptam-font-size-14.ptam-block-cta p{font-size:14px}div[class*=wp-block-atomic].ptam-font-size-15.ptam-block-testimonial p,div[class*=wp-block-atomic].ptam-font-size-15.ptam-block-notice p,div[class*=wp-block-atomic].ptam-font-size-15.ptam-block-profile p,div[class*=wp-block-atomic].ptam-font-size-15.ptam-block-accordion p,div[class*=wp-block-atomic].ptam-font-size-15.ptam-block-cta p{font-size:15px}div[class*=wp-block-atomic].ptam-font-size-16.ptam-block-testimonial p,div[class*=wp-block-atomic].ptam-font-size-16.ptam-block-notice p,div[class*=wp-block-atomic].ptam-font-size-16.ptam-block-profile p,div[class*=wp-block-atomic].ptam-font-size-16.ptam-block-accordion p,div[class*=wp-block-atomic].ptam-font-size-16.ptam-block-cta p{font-size:16px}div[class*=wp-block-atomic].ptam-font-size-17.ptam-block-testimonial p,div[class*=wp-block-atomic].ptam-font-size-17.ptam-block-notice p,div[class*=wp-block-atomic].ptam-font-size-17.ptam-block-profile p,div[class*=wp-block-atomic].ptam-font-size-17.ptam-block-accordion p,div[class*=wp-block-atomic].ptam-font-size-17.ptam-block-cta p{font-size:17px}div[class*=wp-block-atomic].ptam-font-size-18.ptam-block-testimonial p,div[class*=wp-block-atomic].ptam-font-size-18.ptam-block-notice p,div[class*=wp-block-atomic].ptam-font-size-18.ptam-block-profile p,div[class*=wp-block-atomic].ptam-font-size-18.ptam-block-accordion p,div[class*=wp-block-atomic].ptam-font-size-18.ptam-block-cta p{font-size:18px}div[class*=wp-block-atomic].ptam-font-size-19.ptam-block-testimonial p,div[class*=wp-block-atomic].ptam-font-size-19.ptam-block-notice p,div[class*=wp-block-atomic].ptam-font-size-19.ptam-block-profile p,div[class*=wp-block-atomic].ptam-font-size-19.ptam-block-accordion p,div[class*=wp-block-atomic].ptam-font-size-19.ptam-block-cta p{font-size:19px}div[class*=wp-block-atomic].ptam-font-size-20.ptam-block-testimonial p,div[class*=wp-block-atomic].ptam-font-size-20.ptam-block-notice p,div[class*=wp-block-atomic].ptam-font-size-20.ptam-block-profile p,div[class*=wp-block-atomic].ptam-font-size-20.ptam-block-accordion p,div[class*=wp-block-atomic].ptam-font-size-20.ptam-block-cta p{font-size:20px}div[class*=wp-block-atomic].ptam-font-size-21.ptam-block-testimonial p,div[class*=wp-block-atomic].ptam-font-size-21.ptam-block-notice p,div[class*=wp-block-atomic].ptam-font-size-21.ptam-block-profile p,div[class*=wp-block-atomic].ptam-font-size-21.ptam-block-accordion p,div[class*=wp-block-atomic].ptam-font-size-21.ptam-block-cta p{font-size:21px}div[class*=wp-block-atomic].ptam-font-size-22.ptam-block-testimonial p,div[class*=wp-block-atomic].ptam-font-size-22.ptam-block-notice p,div[class*=wp-block-atomic].ptam-font-size-22.ptam-block-profile p,div[class*=wp-block-atomic].ptam-font-size-22.ptam-block-accordion p,div[class*=wp-block-atomic].ptam-font-size-22.ptam-block-cta p{font-size:22px}div[class*=wp-block-atomic].ptam-font-size-23.ptam-block-testimonial p,div[class*=wp-block-atomic].ptam-font-size-23.ptam-block-notice p,div[class*=wp-block-atomic].ptam-font-size-23.ptam-block-profile p,div[class*=wp-block-atomic].ptam-font-size-23.ptam-block-accordion p,div[class*=wp-block-atomic].ptam-font-size-23.ptam-block-cta p{font-size:23px}div[class*=wp-block-atomic].ptam-font-size-24.ptam-block-testimonial p,div[class*=wp-block-atomic].ptam-font-size-24.ptam-block-notice p,div[class*=wp-block-atomic].ptam-font-size-24.ptam-block-profile p,div[class*=wp-block-atomic].ptam-font-size-24.ptam-block-accordion p,div[class*=wp-block-atomic].ptam-font-size-24.ptam-block-cta p{font-size:24px}}.center{text-align:center}.left{text-align:left}.right{text-align:right}@media only screen and (min-width: 600px){.wp-block-columns .layout-column-1,.wp-block-columns .layout-column-2{margin-right:5%}}.wp-block-image{margin-bottom:1.2em}.ptam-text-link{color:inherit;box-shadow:0 -1px 0 inset;text-decoration:none;transition:.3s ease}.ptam-text-link:hover{color:inherit;box-shadow:0 -2px 0 inset;color:#5a3fd6}.entry-content .ptam-block-post-grid-title{margin-top:0;margin-bottom:15px;font-size:28px;line-height:1.2;clear:none}.entry-content .ptam-block-post-grid-title:before{display:none}.entry-content .ptam-block-post-grid-title:after{display:none}.entry-content .ptam-block-post-grid-title a{color:#000;box-shadow:none;transition:.3s ease}.ptam-block-post-grid{margin:0 0 1.2em 0;position:relative}.ptam-block-post-grid .is-grid{display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr;grid-gap:0 2em;column-gap:2em;line-height:1.1}.ptam-block-post-grid .is-grid article{margin-bottom:2.5em}.ptam-block-post-grid .is-grid.columns-1{grid-template-columns:1fr}.ptam-block-post-grid .is-grid.columns-2{grid-template-columns:1fr 1fr}@media only screen and (max-width: 600px){.ptam-block-post-grid .is-grid.columns-2{grid-template-columns:1fr}}.ptam-block-post-grid .is-grid.columns-3{grid-template-columns:1fr 1fr 1fr}@media only screen and (max-width: 600px){.ptam-block-post-grid .is-grid.columns-3{grid-template-columns:1fr 1fr}}.ptam-block-post-grid .is-grid.columns-4{grid-template-columns:1fr 1fr 1fr 1fr}@media only screen and (max-width: 800px){.ptam-block-post-grid .is-grid.columns-4{grid-template-columns:1fr 1fr 1fr}}.ptam-block-post-grid .is-grid.columns-5{grid-template-columns:1fr 1fr 1fr 1fr 1fr}@media only screen and (max-width: 1000px){.ptam-block-post-grid .is-grid.columns-5{grid-template-columns:1fr 1fr 1fr 1fr}}@media only screen and (max-width: 800px){.ptam-block-post-grid .is-grid.columns-5{grid-template-columns:1fr 1fr 1fr}}.ptam-block-post-grid .is-grid.columns-6{grid-template-columns:1fr 1fr 1fr 1fr 1fr 1fr}@media only screen and (max-width: 1000px){.ptam-block-post-grid .is-grid.columns-6{grid-template-columns:1fr 1fr 1fr 1fr}}@media only screen and (max-width: 800px){.ptam-block-post-grid .is-grid.columns-6{grid-template-columns:1fr 1fr 1fr}}@media only screen and (max-width: 600px){.ptam-block-post-grid div[class*=columns].is-grid{grid-template-columns:1fr}}.ptam-block-post-grid .ptam-block-post-grid-image{margin:10px 0}.ptam-block-post-grid .ptam-block-post-grid-image img{display:inline-block}.ptam-block-post-grid .is-list .ptam-block-post-grid-image{margin-top:0}.ptam-block-post-grid .ptam-block-post-grid-text{text-align:left}.ptam-block-post-grid .ptam-block-post-grid-image .avatar{height:auto;width:inherit;border-radius:0}.ptam-block-post-grid .ptam-block-post-grid-title{margin-top:0;margin-bottom:15px;font-size:28px;line-height:1.2;clear:none}.ptam-block-post-grid .ptam-block-post-grid-title:before{display:none}.ptam-block-post-grid .ptam-block-post-grid-title:after{display:none}.ptam-block-post-grid .ptam-block-post-grid-title a{color:#000;box-shadow:none;transition:.3s ease}.ptam-block-post-grid .ptam-block-post-grid-byline{text-transform:uppercase;font-size:13px;letter-spacing:1px;color:#626e81;margin-bottom:15px}.ptam-block-post-grid .ptam-text-lower-case{text-transform:none}.ptam-block-post-grid .ptam-block-post-grid-author,.ptam-block-post-grid .ptam-block-post-grid-date{display:inline-block}.ptam-block-post-grid .ptam-block-post-grid-author:not(:last-child):after,.ptam-block-post-grid .ptam-block-post-grid-date:not(:last-child):after{content:"·";vertical-align:middle;margin:0 5px;line-height:1}.ptam-block-post-grid .ptam-block-post-grid-author a{box-shadow:unset}.ptam-block-post-grid .ptam-block-post-grid-author a:hover{color:inherit;text-decoration:none;box-shadow:unset}.ptam-block-post-grid .ptam-block-post-grid-text p{margin:0 0 15px 0;line-height:1.5;font-size:18px}@media only screen and (max-width: 600px){.ptam-block-post-grid .ptam-block-post-grid-text p{font-size:16px}}.ptam-block-post-grid .ptam-block-post-grid-text p:last-of-type{margin-bottom:0}.ptam-block-post-grid .ptam-block-post-grid-link{display:inline-block;box-shadow:none;transition:.3s ease;font-weight:bold;color:#000}.ptam-block-post-grid .ptam-block-post-grid-link:hover{box-shadow:0 -2px 0 inset}.ptam-block-post-grid .ptam-block-post-grid-excerpt div+p{margin-top:15px}.ptam-block-post-grid .is-list article{display:grid;grid-template-columns:30% 1fr;grid-template-rows:1fr;grid-gap:0 2em}.ptam-block-post-grid .is-list article:not(:last-child){margin-bottom:5%;padding-bottom:5%}@media only screen and (min-width: 600px){.ptam-block-post-grid .is-list article:not(:last-child){border-bottom:solid 1px #eee}}@media only screen and (max-width: 600px){.ptam-block-post-grid .is-list article{grid-template-columns:1fr}}.ptam-block-post-grid .is-list.is-custom article{display:block;grid-template-columns:100% 1fr;grid-template-rows:1fr;grid-gap:0 2em}.ptam-block-post-grid .is-list .ptam-block-post-grid-image{margin-bottom:0}@media only screen and (max-width: 600px){.ptam-block-post-grid .is-list .ptam-block-post-grid-image{margin-bottom:5%}}.ptam-block-post-grid .is-list h1.ptam-block-post-grid-title{margin-top:10px 0}@media only screen and (min-width: 600px){.ptam-block-post-grid .is-list h1.ptam-block-post-grid-title{font-size:38px}}.ptam-block-post-grid .is-list h2.ptam-block-post-grid-title{margin-top:10px 0}@media only screen and (min-width: 600px){.ptam-block-post-grid .is-list h2.ptam-block-post-grid-title{font-size:34px}}.ptam-block-post-grid .is-list h3.ptam-block-post-grid-title{margin-top:10px 0}@media only screen and (min-width: 600px){.ptam-block-post-grid .is-list h3.ptam-block-post-grid-title{font-size:34px}}.ptam-block-post-grid .is-list h4.ptam-block-post-grid-title{margin-top:10px 0}@media only screen and (min-width: 600px){.ptam-block-post-grid .is-list h4.ptam-block-post-grid-title{font-size:28px}}.ptam-block-post-grid .is-list h5.ptam-block-post-grid-title{margin-top:10px 0}@media only screen and (min-width: 600px){.ptam-block-post-grid .is-list h5.ptam-block-post-grid-title{font-size:22px}}.ptam-block-post-grid .is-list h6.ptam-block-post-grid-title{margin-top:10px 0}@media only screen and (min-width: 600px){.ptam-block-post-grid .is-list h6.ptam-block-post-grid-title{font-size:18px}}.ptam-block-post-grid .is-list .no-thumb .ptam-block-post-grid-text{grid-column:span 1}button.ptam-media-alt-upload.components-button{margin-bottom:20px}button.ptam-media-alt-reset.components-button{margin:15px 0}.ptam-term-select .woocommerce-search-list__selected-header button,.ptam-term-exclude .woocommerce-search-list__selected-header button{display:block;margin:1em 0}.ptam-term-select .woocommerce-search-list__selected,.ptam-term-exclude .woocommerce-search-list__selected{margin-bottom:15px}.ptam-term-select .woocommerce-tag.has-remove,.ptam-term-exclude .woocommerce-tag.has-remove{display:flex;align-items:center;justify-content:space-between;background:#fff;padding:10px 20px;border:1px solid #eee;color:#000}.ptam-term-select .woocommerce-tag.has-remove .woocommerce-tag__remove,.ptam-term-exclude .woocommerce-tag.has-remove .woocommerce-tag__remove{display:block;align-self:flex-end}.ptam-term-grid-loading{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;text-align:center;width:100%}.ptam-term-grid-loading h1{width:100%;text-align:center}.ptam-term-grid{position:relative;display:flex;flex-wrap:wrap;display:grid;grid-template-columns:repeat(auto-fill, minmax(200px, 1fr));grid-auto-rows:minmax(150px, auto);grid-gap:1em;justify-items:center}.ptam-term-grid.columns-1{grid-template-columns:1fr}.ptam-term-grid.columns-2{grid-template-columns:1fr 1fr}@media only screen and (max-width: 500px){.ptam-term-grid.columns-2{grid-template-columns:1fr}}.ptam-term-grid.columns-3{grid-template-columns:1fr 1fr 1fr}@media only screen and (max-width: 600px){.ptam-term-grid.columns-3{grid-template-columns:1fr 1fr}}@media only screen and (max-width: 500px){.ptam-term-grid.columns-3{grid-template-columns:1fr}}.ptam-term-grid.columns-4{grid-template-columns:1fr 1fr 1fr 1fr}@media only screen and (max-width: 800px){.ptam-term-grid.columns-4{grid-template-columns:1fr 1fr 1fr}}@media only screen and (max-width: 600px){.ptam-term-grid.columns-4{grid-template-columns:1fr 1fr}}@media only screen and (max-width: 500px){.ptam-term-grid.columns-4{grid-template-columns:1fr}}.ptam-term-grid .ptam-term-grid-anchor-full{position:absolute;z-index:3;display:block;width:100%;height:100%}.ptam-term-grid .ptam-term-grid-item{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:center;min-height:300px;width:100%;background:#24292d;color:#fff;background-size:cover;background-repeat:no-repeat;background-position:center center;text-align:center;padding:20px;overflow:hidden;transition:background-color .5s ease;word-break:break-all;box-sizing:border-box;margin-left:5px;margin-right:5px;flex:1 1 300px}.ptam-term-grid .ptam-term-grid-item .ptam-term-grid-item-content{position:relative;z-index:2}.ptam-term-grid .ptam-term-grid-item .ptam-term-grid-button{display:inline-block;background-color:#32373c;color:#fff;border:none;border-radius:28px;font-weight:500;box-shadow:none;cursor:pointer;display:inline-block;font-size:18px;margin:0;margin-top:1em;padding:12px 24px;text-align:center;text-decoration:none;overflow-wrap:break-word;transition:background-color .5s ease}.ptam-term-grid .ptam-term-grid-item h2{color:#fff;font-size:2.2em}.ptam-term-grid .ptam-term-grid-item .ptam-term-grid-item-description{font-size:1.4em;line-height:1.5em}.ptam-fp-wrapper .ptam-fp-term{margin-bottom:20px}.ptam-fp-wrapper .ptam-fp-term span{display:inline-block}.ptam-fp-wrapper .ptam-featured-post-item{padding-bottom:1.3em;border-bottom:1px solid #ddd}.ptam-fp-wrapper .ptam-featured-post-item:last-child{border-bottom:0}.ptam-fp-wrapper .ptam-featured-post-meta .entry-title{font-weight:700;line-height:1.4em;margin:1em 0}.ptam-fp-wrapper .ptam-featured-post-meta .entry-title a{color:#000;text-decoration:none}.ptam-fp-wrapper .ptam-featured-post-meta .entry-title a:hover{color:#000;text-decoration:none}.ptam-fp-wrapper .ptam-featured-post-meta .entry-meta{display:flex;flex-wrap:wrap;justify-content:space-between;margin-bottom:1em;font-size:12px}.ptam-fp-wrapper .ptam-featured-post-meta .entry-meta .author-name a{font-weight:700;color:#6c6c6c;text-decoration:none}.ptam-fp-wrapper .ptam-featured-post-meta .entry-meta .author-name a:hover{color:#333;text-decoration:none}.ptam-fp-wrapper .ptam-featured-post-meta .entry-meta .author-name a:before{font-family:"PTAM";content:"";display:inline-block;margin-right:2px}.ptam-fp-wrapper .ptam-featured-post-meta .entry-meta .post-date{color:#6c6c6c}.ptam-fp-wrapper .ptam-featured-post-meta .entry-meta .post-date:before{font-family:"PTAM";content:"";display:inline-block;margin-right:2px}.ptam-fp-wrapper .ptam-featured-post-meta .entry-meta .post-comments{color:#000}.ptam-fp-wrapper .ptam-featured-post-meta .entry-meta .post-comments:before{font-family:"PTAM";content:"";display:inline-block;margin-right:2px}.ptam-fp-wrapper .ptam-featured-post-content{line-height:1.2em;margin:1em 0}.ptam-fp-wrapper .ptam-featured-post-button a{display:inline-block;padding:10px 20px;text-decoration:none}.ptam-fp-wrapper .ptam-featured-post-button a :hover{text-decoration:none}.ptam-pagination>ul,body.has-blocks .fl-post-content .ptam-pagination>ul{list-style-type:none;margin:0;padding:0}.ptam-pagination li,body.has-blocks .fl-post-content .ptam-pagination li{display:inline-block}.ptam-pagination li>span,.ptam-pagination li>a,body.has-blocks .fl-post-content .ptam-pagination li>span,body.has-blocks .fl-post-content .ptam-pagination li>a{display:inline-block;padding:5px 10px;margin:0 4px 0 0;border:1px solid #eee;line-height:1;text-decoration:none;border-radius:2px;font-weight:600}.ptam-pagination li>span:hover,.ptam-pagination li>a:hover,body.has-blocks .fl-post-content .ptam-pagination li>span:hover,body.has-blocks .fl-post-content .ptam-pagination li>a:hover{background:#f9f9f9}.ptam-pagination li>span.current,body.has-blocks .fl-post-content .ptam-pagination li>span.current{background:#f9f9f9}.ptam-apply{margin-top:15px;margin-bottom:20px}.ptam-term-select .woocommerce-search-list__selected,.ptam-term-exclude .woocommerce-search-list__selected{display:none}.ptam-term-select .components-base-control__field,.ptam-term-exclude .components-base-control__field{display:none} 2 | -------------------------------------------------------------------------------- /includes/class-functions.php: -------------------------------------------------------------------------------- 1 | 1 ) { 110 | $opacity = 1.0; 111 | } 112 | $output = 'rgba(' . implode( ',', $rgb ) . ',' . $opacity . ')'; 113 | } else { 114 | $output = 'rgb(' . implode( ',', $rgb ) . ')'; 115 | } 116 | 117 | // Return rgb(a) color string. 118 | return $output; 119 | } 120 | 121 | /** 122 | * Return an image URL. 123 | * 124 | * @param int $attachment_id The attachment ID. 125 | * @param string $size The image size to retrieve. 126 | * 127 | * @return string Image URL or empty string if not found. 128 | */ 129 | public static function get_image( $attachment_id = 0, $size = 'large' ) { 130 | $maybe_image = wp_get_attachment_image_src( $attachment_id, $size ); 131 | if ( ! $maybe_image ) { 132 | return ''; 133 | } 134 | if ( isset( $maybe_image[0] ) ) { 135 | return esc_url( $maybe_image[0] ); 136 | } 137 | return ''; 138 | } 139 | 140 | /** 141 | * Get an image from term meta. 142 | * 143 | * @param string $size The image size. 144 | * @param string $meta_field The meta field to query. 145 | * @param string $type The type of meta to retrieve (meta, acf, pods). 146 | * @param string $taxonomy The taxonomy slug to retrieve images for. 147 | * @param int $term_id The term to retrieve data for. 148 | * 149 | * @return string Image URL or blank if not found. 150 | */ 151 | public static function get_term_image( $size = 'large', $meta_field = '', $type = 'meta', $taxonomy = 'category', $term_id = 0 ) { 152 | if ( 'none' === $type ) { 153 | return ''; 154 | } 155 | if ( 'acf' === $type && function_exists( 'get_field' ) ) { 156 | $acf_term_id = $taxonomy . '_' . $term_id; 157 | $acf_term_value = get_field( $meta_field, $acf_term_id ); 158 | if ( ! $acf_term_value ) { 159 | return ''; 160 | } 161 | if ( is_numeric( $acf_term_value ) ) { 162 | $image = self::get_image( $acf_term_value, $size ); 163 | return $image; 164 | } elseif ( is_array( $acf_term_value ) && isset( $acf_term_value['url'] ) ) { 165 | return esc_url( $acf_term_value['url'] ); 166 | } elseif ( is_string( $acf_term_value ) ) { 167 | return esc_url( $acf_term_value ); 168 | } else { 169 | return ''; 170 | } 171 | } 172 | if ( 'meta' === $type ) { 173 | $term_value = get_term_meta( $term_id, $meta_field, true ); 174 | if ( is_numeric( $term_value ) ) { 175 | $image = self::get_image( $term_value, $size ); 176 | return $image; 177 | } elseif ( is_array( $term_value ) && isset( $term_value['url'] ) ) { 178 | return esc_url( $term_value['url'] ); 179 | } elseif ( is_string( $term_value ) ) { 180 | return esc_url( $term_value ); 181 | } else { 182 | return ''; 183 | } 184 | } 185 | if ( 'pods' === $type ) { 186 | $term_value = get_term_meta( $term_id, $meta_field, true ); 187 | if ( is_numeric( $term_value ) ) { 188 | $image = self::get_image( $term_value, $size ); 189 | return $image; 190 | } elseif ( is_array( $term_value ) && isset( $term_value['ID'] ) ) { 191 | return self::get_image( $term_value['ID'], $size ); 192 | } elseif ( is_string( $term_value ) ) { 193 | return esc_url( $term_value ); 194 | } else { 195 | return ''; 196 | } 197 | } 198 | return ''; 199 | } 200 | 201 | /** 202 | * Get web safe fonts 203 | * 204 | * @return array $fonts Fonts to Use 205 | */ 206 | public static function get_fonts() { 207 | /** 208 | * Filter the fonts that are available. 209 | * 210 | * @since 3.5.0 211 | * 212 | * @param array associative array of key/value pairs of fonts. 213 | */ 214 | $fonts = apply_filters( 215 | 'ptam_fonts', 216 | array( 217 | 'inherit' => 'Default', 218 | 'arial' => 'Arial', 219 | 'helvetica' => 'Helvetica', 220 | 'times new roman' => 'Times New Roman', 221 | 'times' => 'Times', 222 | 'courier new' => 'Courier New', 223 | 'courier' => 'Courier', 224 | 'verdana' => 'Verdana', 225 | 'georgia' => 'Georgia', 226 | 'palatino' => 'Palatino', 227 | 'garamond' => 'Garamond', 228 | 'bookman' => 'Bookman', 229 | 'trebuchet ms' => 'Trebuchet MS', 230 | 'arial black' => 'Arial Black', 231 | 'impact' => 'Impact', 232 | ) 233 | ); 234 | $pro_fonts = array(); 235 | // Add Typekit Fonts. 236 | if ( defined( 'CUSTOM_TYPEKIT_FONTS_FILE' ) ) { 237 | $adobe_fonts = get_option( 'custom-typekit-fonts', array() ); 238 | if ( isset( $adobe_fonts['custom-typekit-font-details'] ) ) { 239 | foreach ( $adobe_fonts['custom-typekit-font-details'] as $font_name => $font_details ) { 240 | $pro_fonts[ $font_details['slug'] ] = $font_details['family']; 241 | } 242 | } 243 | } 244 | $fonts = array_merge( $fonts, $pro_fonts ); 245 | return $fonts; 246 | } 247 | 248 | /** 249 | * Return the URL to the admin screen 250 | * 251 | * @param string $tab Tab path to load. 252 | * @param string $sub_tab Subtab path to load. 253 | * 254 | * @return string URL to admin screen. Output is not escaped. 255 | */ 256 | public static function get_settings_url( $tab = '', $sub_tab = '' ) { 257 | $options_url = admin_url( 'options-general.php?page=custom-query-blocks' ); 258 | if ( ! empty( $tab ) ) { 259 | $options_url = add_query_arg( array( 'tab' => sanitize_title( $tab ) ), $options_url ); 260 | if ( ! empty( $sub_tab ) ) { 261 | $options_url = add_query_arg( array( 'subtab' => sanitize_title( $sub_tab ) ), $options_url ); 262 | } 263 | } 264 | return $options_url; 265 | } 266 | 267 | /** 268 | * Get the current admin tab. 269 | * 270 | * @return null|string Current admin tab. 271 | */ 272 | public static function get_admin_tab() { 273 | $tab = filter_input( INPUT_GET, 'tab', FILTER_DEFAULT ); 274 | if ( $tab && is_string( $tab ) ) { 275 | return sanitize_text_field( sanitize_title( $tab ) ); 276 | } 277 | return null; 278 | } 279 | 280 | /** 281 | * Get the current admin sub-tab. 282 | * 283 | * @return null|string Current admin sub-tab. 284 | */ 285 | public static function get_admin_sub_tab() { 286 | $tab = filter_input( INPUT_GET, 'tab', FILTER_DEFAULT ); 287 | if ( $tab && is_string( $tab ) ) { 288 | $subtab = filter_input( INPUT_GET, 'subtab', FILTER_DEFAULT ); 289 | if ( $subtab && is_string( $subtab ) ) { 290 | return sanitize_text_field( sanitize_title( $subtab ) ); 291 | } 292 | } 293 | return null; 294 | } 295 | 296 | /** 297 | * Return the plugin slug. 298 | * 299 | * @return string plugin slug. 300 | */ 301 | public static function get_plugin_slug() { 302 | return dirname( plugin_basename( PTAM_FILE ) ); 303 | } 304 | 305 | /** 306 | * Return the plugin path. 307 | * 308 | * @return string plugin path. 309 | */ 310 | public static function get_plugin_path() { 311 | return plugin_basename( PTAM_FILE ); 312 | } 313 | 314 | /** 315 | * Return the basefile for the plugin. 316 | * 317 | * @return string base file for the plugin. 318 | */ 319 | public static function get_plugin_file() { 320 | return plugin_basename( PTAM_FILE ); 321 | } 322 | 323 | /** 324 | * Return the version for the plugin. 325 | * 326 | * @return float version for the plugin. 327 | */ 328 | public static function get_plugin_version() { 329 | return PTAM_VERSION; 330 | } 331 | 332 | /** 333 | * Get the Plugin Logo. 334 | */ 335 | public static function get_plugin_logo() { 336 | /** 337 | * Filer the output of the plugin logo. 338 | * 339 | * Potentially change branding of the plugin. 340 | * 341 | * @since 5.1.0 342 | * 343 | * @param string URL to the plugin logo. 344 | */ 345 | return apply_filters( 'ptam_plugin_logo_full', self::get_plugin_url( '/img/logo.png' ) ); 346 | } 347 | 348 | /** 349 | * Get the plugin author name. 350 | */ 351 | public static function get_plugin_author() { 352 | /** 353 | * Filer the output of the plugin Author. 354 | * 355 | * Potentially change branding of the plugin. 356 | * 357 | * @since 5.1.0 358 | * 359 | * @param string Plugin Author name. 360 | */ 361 | $plugin_author = apply_filters( 'ptam_plugin_author', 'MediaRon LLC' ); 362 | return $plugin_author; 363 | } 364 | 365 | /** 366 | * Return the Plugin author URI. 367 | */ 368 | public static function get_plugin_author_uri() { 369 | /** 370 | * Filer the output of the plugin Author URI. 371 | * 372 | * Potentially change branding of the plugin. 373 | * 374 | * @since 5.1.0 375 | * 376 | * @param string Plugin Author URI. 377 | */ 378 | $plugin_author = apply_filters( 'ptam_plugin_author_uri', 'https://mediaron.com' ); 379 | return $plugin_author; 380 | } 381 | 382 | /** 383 | * Get the Plugin Icon. 384 | */ 385 | public static function get_plugin_icon() { 386 | /** 387 | * Filer the output of the plugin icon. 388 | * 389 | * Potentially change branding of the plugin. 390 | * 391 | * @since 5.1.0 392 | * 393 | * @param string URL to the plugin icon. 394 | */ 395 | return apply_filters( 'ptam_plugin_icon', self::get_plugin_url( '/img/logo.png' ) ); 396 | } 397 | 398 | /** 399 | * Return the plugin name for the plugin. 400 | * 401 | * @return string Plugin name. 402 | */ 403 | public static function get_plugin_name() { 404 | /** 405 | * Filer the output of the plugin name. 406 | * 407 | * Potentially change branding of the plugin. 408 | * 409 | * @since 5.1.0 410 | * 411 | * @param string Plugin name. 412 | */ 413 | return apply_filters( 'ptam_plugin_name', __( 'Custom Query Blocks', 'post-type-archive-mapping' ) ); 414 | } 415 | 416 | /** 417 | * Return the plugin description for the plugin. 418 | * 419 | * @return string plugin description. 420 | */ 421 | public static function get_plugin_description() { 422 | /** 423 | * Filer the output of the plugin name. 424 | * 425 | * Potentially change branding of the plugin. 426 | * 427 | * @since 5.1.0 428 | * 429 | * @param string Plugin description. 430 | */ 431 | return apply_filters( 'ptam_plugin_description', __( 'Map your post type and term archives to a page and use our Gutenberg blocks to show posts or terms.', 'post-type-archive-mapping' ) ); 432 | } 433 | 434 | /** 435 | * Retrieve the plugin URI. 436 | */ 437 | public static function get_plugin_uri() { 438 | /** 439 | * Filer the output of the plugin URI. 440 | * 441 | * Potentially change branding of the plugin. 442 | * 443 | * @since 5.1.0 444 | * 445 | * @param string Plugin URI. 446 | */ 447 | return apply_filters( 'ptam_plugin_uri', 'https://mediaron.com/custom-query-blocks/' ); 448 | } 449 | 450 | /** 451 | * Retrieve the plugin Menu Name. 452 | */ 453 | public static function get_plugin_menu_name() { 454 | /** 455 | * Filer the output of the plugin menu name. 456 | * 457 | * Potentially change branding of the plugin. 458 | * 459 | * @since 5.1.0 460 | * 461 | * @param string Plugin Menu Name. 462 | */ 463 | return apply_filters( 'ptam_plugin_menu_name', __( 'Custom Query Blocks', 'post-type-archive-mapping' ) ); 464 | } 465 | 466 | /** 467 | * Retrieve the plugin title. 468 | */ 469 | public static function get_plugin_title() { 470 | /** 471 | * Filer the output of the plugin title. 472 | * 473 | * Potentially change branding of the plugin. 474 | * 475 | * @since 5.1.0 476 | * 477 | * @param string Plugin Menu Name. 478 | */ 479 | return apply_filters( 'ptam_plugin_menu_title', self::get_plugin_name() ); 480 | } 481 | 482 | /** 483 | * Returns appropriate html for KSES. 484 | * 485 | * @param bool $svg Whether to add SVG data to KSES. 486 | */ 487 | public static function get_kses_allowed_html( $svg = true ) { 488 | $allowed_tags = wp_kses_allowed_html(); 489 | 490 | $allowed_tags['nav'] = array( 491 | 'class' => array(), 492 | ); 493 | $allowed_tags['a']['class'] = array(); 494 | 495 | if ( ! $svg ) { 496 | return $allowed_tags; 497 | } 498 | $allowed_tags['svg'] = array( 499 | 'xmlns' => array(), 500 | 'fill' => array(), 501 | 'viewbox' => array(), 502 | 'role' => array(), 503 | 'aria-hidden' => array(), 504 | 'focusable' => array(), 505 | 'class' => array(), 506 | ); 507 | 508 | $allowed_tags['path'] = array( 509 | 'd' => array(), 510 | 'fill' => array(), 511 | 'opacity' => array(), 512 | ); 513 | 514 | $allowed_tags['g'] = array(); 515 | 516 | $allowed_tags['use'] = array( 517 | 'xlink:href' => array(), 518 | ); 519 | 520 | $allowed_tags['symbol'] = array( 521 | 'aria-hidden' => array(), 522 | 'viewBox' => array(), 523 | 'id' => array(), 524 | 'xmls' => array(), 525 | ); 526 | 527 | return $allowed_tags; 528 | } 529 | 530 | /** 531 | * Get the plugin directory for a path. 532 | * 533 | * @param string $path The path to the file. 534 | * 535 | * @return string The new path. 536 | */ 537 | public static function get_plugin_dir( $path = '' ) { 538 | $dir = rtrim( plugin_dir_path( PTAM_FILE ), '/' ); 539 | if ( ! empty( $path ) && is_string( $path ) ) { 540 | $dir .= '/' . ltrim( $path, '/' ); 541 | } 542 | return $dir; 543 | } 544 | 545 | /** 546 | * Return a plugin URL path. 547 | * 548 | * @param string $path Path to the file. 549 | * 550 | * @return string URL to to the file. 551 | */ 552 | public static function get_plugin_url( $path = '' ) { 553 | $dir = rtrim( plugin_dir_url( PTAM_FILE ), '/' ); 554 | if ( ! empty( $path ) && is_string( $path ) ) { 555 | $dir .= '/' . ltrim( $path, '/' ); 556 | } 557 | return $dir; 558 | } 559 | 560 | /** 561 | * Gets the highest priority for a filter. 562 | * 563 | * @param int $subtract The amount to subtract from the high priority. 564 | * 565 | * @return int priority. 566 | */ 567 | public static function get_highest_priority( $subtract = 0 ) { 568 | $highest_priority = PHP_INT_MAX; 569 | $subtract = absint( $subtract ); 570 | if ( 0 === $subtract ) { 571 | --$highest_priority; 572 | } else { 573 | $highest_priority = absint( $highest_priority - $subtract ); 574 | } 575 | return $highest_priority; 576 | } 577 | } 578 | -------------------------------------------------------------------------------- /post-type-archive-mapping.php: -------------------------------------------------------------------------------- 1 | enqueue = new PTAM\Includes\Enqueue(); 84 | $this->enqueue->run(); 85 | 86 | // Run if blocks are enabled. 87 | if ( false === Options::is_blocks_disabled() ) { 88 | // Register REST for the plugin. 89 | $this->rest = new PTAM\Includes\Rest\Rest(); 90 | $this->rest->run(); 91 | 92 | // Register Custom Post Type Block. 93 | $this->cpt_block_one = new PTAM\Includes\Blocks\Custom_Post_Types\Custom_Post_Types(); 94 | $this->cpt_block_one->run(); 95 | 96 | // Register Term Grid Block. 97 | $this->term_grid = new PTAM\Includes\Blocks\Term_Grid\Terms(); 98 | $this->term_grid->run(); 99 | 100 | // Register Featured Post Block. 101 | $this->featured_posts = new PTAM\Includes\Blocks\Featured_Posts\Posts(); 102 | $this->featured_posts->run(); 103 | 104 | // Gutenberg Helper which sets the block categories. 105 | $this->gutenberg = new PTAM\Includes\Admin\Gutenberg(); 106 | $this->gutenberg->run(); 107 | } 108 | 109 | /** 110 | * Filter to disable archive mapping. 111 | * This is useful if you want to use the blocks but not the archive mapping. 112 | * 113 | * @since 5.1.8 114 | */ 115 | $ptam_disabled = apply_filters( 'ptam_archive_mapping_disabled', false ); 116 | 117 | // Run if page columns are enabled. 118 | if ( false === Options::is_page_columns_disabled() && false === Options::is_archive_mapping_disabled() && ! $ptam_disabled ) { 119 | // Page columns. 120 | $this->page_columns = new PTAM\Includes\Admin\Page_Columns(); 121 | $this->page_columns->run(); 122 | } 123 | 124 | if ( ! $ptam_disabled ) { 125 | // Yoast Compatibility. 126 | $this->yoast = new PTAM\Includes\Yoast(); 127 | $this->yoast->run(); 128 | } 129 | 130 | // Admin settings. 131 | $this->admin_settings = new PTAM\Includes\Admin\Admin_Settings(); 132 | } //end constructor 133 | 134 | /** 135 | * Main plugin initialization 136 | * 137 | * Initialize admin menus, options,and scripts 138 | * 139 | * @since 1.0.0 140 | * @access public 141 | * 142 | * @see __construct 143 | */ 144 | public function init() { 145 | 146 | /** 147 | * Filter to disable archive mapping. 148 | * This is useful if you want to use the blocks but not the archive mapping. 149 | * 150 | * @since 5.1.8 151 | */ 152 | $ptam_disabled = apply_filters( 'ptam_archive_mapping_disabled', false ); 153 | 154 | // Check if archive mapping is disabled. 155 | if ( false === Options::is_archive_mapping_disabled() && ! $ptam_disabled ) { 156 | // Archive mapping settings. 157 | add_action( 'admin_init', array( $this, 'init_admin_settings' ) ); 158 | add_action( 'pre_get_posts', array( $this, 'maybe_override_archive' ) ); 159 | 160 | // Output admin notices once when saving archive mapping. 161 | add_action( 'admin_notices', array( $this, 'admin_notices' ) ); 162 | 163 | // 404 page detection. 164 | add_filter( 'template_include', array( $this, 'maybe_force_404_template' ), 1 ); 165 | } 166 | } //end init 167 | 168 | /** 169 | * This is a catch-all. Any 404 error not caught will be directed here. 170 | * If a 404 error is caught, will load the page template instead. 171 | * 172 | * @param string $template The regular template. 173 | * 174 | * @return string $template The updated template. 175 | */ 176 | public function maybe_force_404_template( $template ) { 177 | if ( is_404() ) { 178 | $page_id_404 = absint( get_option( 'post-type-archive-mapping-404', 0 ) ); 179 | if ( $page_id_404 > 0 ) { 180 | $args = array( 181 | 'post_type' => 'page', 182 | 'page_id' => $page_id_404, 183 | 'post_status' => 'publish', 184 | 'posts_per_page' => 1, 185 | ); 186 | /* I wise woman once told me to never use query_posts. Like NEVER. I had no choice here. */ 187 | query_posts( // phpcs:ignore 188 | $args 189 | ); 190 | return get_page_template(); 191 | } 192 | } 193 | return $template; 194 | } 195 | 196 | /** 197 | * Add admin notices when things go wrong. 198 | * 199 | * @since 3.3.5 200 | */ 201 | public function admin_notices() { 202 | // Check for any term errors. 203 | if ( get_option( 'ptam_error_message', '' ) ) { 204 | printf( 205 | '

    %s

    ', 206 | esc_html( get_option( 'ptam_error_message', '' ) ) 207 | ); 208 | delete_option( 'ptam_error_message' ); 209 | } 210 | } 211 | 212 | /** 213 | * Override an archive page based on passed query arguments. 214 | * 215 | * @param WP_Query $query The query to check. 216 | */ 217 | public function maybe_override_archive( $query ) { 218 | if ( is_admin() ) { 219 | return $query; 220 | } 221 | // Maybe Redirect. 222 | if ( is_page() ) { 223 | $object_id = get_queried_object_id(); 224 | $post_meta = get_post_meta( $object_id, '_post_type_mapped', true ); 225 | if ( $post_meta ) { 226 | if ( $post_meta && ! get_query_var( 'redirected' ) ) { 227 | wp_safe_redirect( get_post_type_archive_link( $post_meta ) ); 228 | exit; 229 | } 230 | } else { 231 | if ( get_query_var( 'paged' ) ) { 232 | $query->set( 'paged', get_query_var( 'paged' ) ); 233 | } 234 | return; 235 | } 236 | } 237 | 238 | // trigger this once after running the main query. 239 | if ( true === $this->paged_reset ) { 240 | $query->set( 'paged', $this->paged ); 241 | set_query_var( 'paged', $this->paged ); 242 | 243 | $this->paged_reset = false; 244 | } 245 | 246 | $post_types = get_option( 'post-type-archive-mapping', array() ); 247 | if ( empty( $post_types ) && is_admin() && ! is_tax() ) { 248 | return; 249 | } 250 | 251 | // trigger this the first time to get the current page. 252 | if ( is_null( $this->paged ) ) { 253 | $this->paged = get_query_var( 'paged' ); 254 | } 255 | if ( is_array( $post_types ) && ! empty( $post_types ) ) { 256 | foreach ( $post_types as $post_type => $post_id ) { 257 | if ( is_post_type_archive( $post_type ) && 'default' !== $post_id && $query->is_main_query() ) { 258 | $post_id = absint( $post_id ); 259 | $post_id = apply_filters( 'wpml_object_id', $post_id, 'page', true ); 260 | $query->set( 'post_type', 'page' ); 261 | $query->set( 'page_id', $post_id ); 262 | $query->set( 'redirected', true ); 263 | $query->set( 'original_archive_type', 'page' ); 264 | $query->set( 'original_archive_id', $post_type ); 265 | $query->set( 'term_tax', '' ); 266 | $query->set( 'paged', $this->paged ); 267 | $query->is_archive = false; 268 | $query->is_single = true; 269 | $query->is_singular = true; 270 | $query->is_post_type_archive = false; 271 | $this->paged_reset = true; 272 | } 273 | } 274 | } 275 | if ( is_tax() || $query->is_category || $query->is_tag ) { 276 | $post_id = get_term_meta( get_queried_object_id(), '_term_archive_mapping', true ); 277 | $term = get_queried_object(); 278 | if ( $post_id && 'default' !== $post_id ) { 279 | $post_id = absint( $post_id ); 280 | $query->set( 'post_type', 'page' ); 281 | $query->set( 'page_id', $post_id ); 282 | $query->set( 'redirected', true ); 283 | $query->set( 'paged', $this->paged ); 284 | $query->set( 'original_archive_type', 'term' ); 285 | $query->set( 'original_archive_id', absint( $term->term_id ) ); 286 | $query->set( 'term_tax', sanitize_text_field( $term->taxonomy ) ); 287 | $query->is_page = true; 288 | $query->is_archive = false; 289 | $query->is_category = false; 290 | $query->is_tag = false; 291 | $query->is_tax = false; 292 | $query->is_single = true; 293 | $query->is_singular = true; 294 | $query->is_post_type_archive = false; 295 | $query->queried_object_id = $post_id; 296 | 297 | $query->queried_object = get_post( $post_id, OBJECT ); 298 | $this->paged_reset = true; 299 | } 300 | } 301 | } 302 | 303 | /** 304 | * Get an absolute path for a plugin asset. 305 | * 306 | * @param string $path The relative path to the asset. 307 | */ 308 | public static function get_plugin_dir( $path = '' ) { 309 | $dir = rtrim( plugin_dir_path( __FILE__ ), '/' ); 310 | if ( ! empty( $path ) && is_string( $path ) ) { 311 | $dir .= '/' . ltrim( $path, '/' ); 312 | } 313 | return $dir; 314 | } 315 | 316 | /** 317 | * Get an absolute path for a plugin asset. 318 | * 319 | * @param string $path The relative path to the asset. 320 | */ 321 | public static function get_plugin_url( $path = '' ) { 322 | $dir = rtrim( plugin_dir_url( __FILE__ ), '/' ); 323 | if ( ! empty( $path ) && is_string( $path ) ) { 324 | $dir .= '/' . ltrim( $path, '/' ); 325 | } 326 | return $dir; 327 | } 328 | 329 | /** 330 | * Save post meta if selected on the reading screen. 331 | * 332 | * @param array $args Post Type arguments. 333 | */ 334 | public function post_type_save( $args ) { 335 | if ( ! is_array( $args ) ) { 336 | return $args; 337 | } 338 | global $wpdb; 339 | $query = "delete from {$wpdb->postmeta} where meta_key = '_post_type_mapped'"; 340 | $wpdb->query( $query ); // phpcs:ignore 341 | foreach ( $args as $post_type => $page_id ) { 342 | $maybe_mapped = get_post_meta( $page_id, '_term_mapped', true ); 343 | if ( $maybe_mapped ) { 344 | update_option( 345 | 'ptam_error_message', 346 | sprintf( 347 | /* Translators: %s is the page title */ 348 | __( 'The page %s to map to a post type archive is already mapped to a term.', 'post-type-archive-mapping' ), 349 | esc_html( get_the_title( $page_id ) ) 350 | ) 351 | ); 352 | unset( $args[ $post_type ] ); 353 | } else { 354 | update_post_meta( $page_id, '_post_type_mapped', $post_type ); 355 | } 356 | } 357 | return $args; 358 | } 359 | 360 | /** 361 | * Initialize options 362 | * 363 | * Initialize page settings, fields, and sections and their callbacks 364 | * 365 | * @since 1.0.0 366 | * @access public 367 | * 368 | * @see init 369 | */ 370 | public function init_admin_settings() { 371 | 372 | // Get taxonomies. 373 | $taxonomies = get_taxonomies( 374 | array( 375 | 'public' => true, 376 | ), 377 | 'objects' 378 | ); 379 | foreach ( $taxonomies as $taxonomy ) { 380 | add_action( "{$taxonomy->name}_edit_form", array( $this, 'map_term_interface' ) ); 381 | } 382 | add_action( 'edit_term', array( $this, 'save_mapped_term' ) ); 383 | 384 | // Register post type mapping settings. 385 | register_setting( 386 | 'reading', 387 | 'post-type-archive-mapping', 388 | array( 389 | 'sanitize_callback' => array( $this, 'post_type_save' ), 390 | ) 391 | ); 392 | register_setting( 393 | 'reading', 394 | 'post-type-archive-mapping-404', 395 | array( 396 | 'sanitize_callback' => 'absint', 397 | ) 398 | ); 399 | 400 | add_settings_section( 'post-type-archive-mapping', _x( 'Page/Item Mapping', 'plugin settings heading', 'post-type-archive-mapping' ), array( $this, 'settings_section' ), 'reading' ); 401 | 402 | add_settings_field( 403 | 'post-type-archive-mapping', 404 | __( 'Post Type Archive Mapping', 'post-type-archive-mapping' ), 405 | array( $this, 'add_settings_post_types' ), 406 | 'reading', 407 | 'post-type-archive-mapping' 408 | ); 409 | 410 | add_settings_field( 411 | 'post-type-archive-mapping-404', 412 | __( '404 Page', 'post-type-archive-mapping' ), 413 | array( $this, 'add_settings_404_page' ), 414 | 'reading', 415 | 'post-type-archive-mapping' 416 | ); 417 | 418 | } 419 | 420 | /** 421 | * Add post type options to Settings->Reading screen. 422 | * 423 | * @param array $args Post Type arguments. 424 | */ 425 | public function add_settings_post_types( $args ) { 426 | $output = get_option( 'post-type-archive-mapping', array() ); 427 | $post_types = get_post_types( 428 | array( 429 | 'public' => true, 430 | 'has_archive' => true, 431 | ) 432 | ); 433 | if ( empty( $post_types ) ) { 434 | ?> 435 |

    436 | $post_type ) { 440 | $selection = 'default'; 441 | if ( isset( $output[ $post_type ] ) ) { 442 | $selection = $output[ $post_type ]; 443 | } 444 | $post_type_label = $post_type; 445 | $post_type_data = get_post_type_object( $post_type ); 446 | if ( isset( $post_type_data->label ) && ! empty( $post_type_data->label ) ) { 447 | $post_type_label = $post_type_data->label; 448 | } 449 | ?> 450 |
    451 |

    452 | esc_attr( $selection ), 456 | 'name' => esc_html( "post-type-archive-mapping[{$post_type}]" ), 457 | 'value_field' => 'ID', 458 | 'option_none_value' => 'default', 459 | 'show_option_none' => esc_html__( 'Default', 'post-type-archive-mapping' ), 460 | ) 461 | ); 462 | ?> 463 |
    464 | 467 | Reading screen. 472 | * 473 | * @param array $args No idea what these are. 474 | */ 475 | public function add_settings_404_page( $args ) { 476 | $page_id_404 = get_option( 'post-type-archive-mapping-404', 0 ); 477 | if ( ! $page_id_404 ) { 478 | $page_id_404 = -1; 479 | } 480 | ?> 481 |
    482 |

    483 | intval( $page_id_404 ), 487 | 'name' => 'post-type-archive-mapping-404', 488 | 'value_field' => 'ID', 489 | 'option_none_value' => 'default', 490 | 'show_option_none' => esc_html__( 'Default', 'post-type-archive-mapping' ), 491 | ) 492 | ); 493 | ?> 494 |
    495 | term_id, '_term_archive_mapping', true ); 506 | if ( ! $post_id ) { 507 | $post_id = -1; 508 | } 509 | ?> 510 |

    511 | intval( $post_id ), 515 | 'name' => 'term_post_type', 516 | 'value_field' => 'ID', 517 | 'option_none_value' => 'default', 518 | 'show_option_none' => esc_html__( 'Default', 'post-type-archive-mapping' ), 519 | ) 520 | ); 521 | ?> 522 |

    523 |