WordPress.org

Make WordPress Core


Ignore:
Timestamp:
10/28/2016 02:56:16 AM (4 years ago)
Author:
westonruter
Message:

Customize: Introduce starter content and site freshness state.

A theme can opt-in for tailored starter content to apply to the customizer when previewing the theme on a fresh install, when fresh_site is at its initial 1 value. Starter content is staged in the customizer and does not go live unless the changes are published. Initial starter content is added to Twenty Seventeen.

  • The fresh_site flag is cleared when a published post or page is saved, when widgets are modified, or when the customizer state is saved.
  • Starter content is registered via starter-content theme support, where the argument is an array containing widgets, posts, nav_menus, options, and theme_mods. Posts/pages in starter content are created with the auto-draft status, re-using the page/post stubs feature added to nav menus and the static front page controls.
  • A get_theme_starter_content filter allows for plugins to extend a theme's starter content.
  • Starter content in themes can/should re-use existing starter content items in core by using named placeholders.
  • Import theme starter content into customized state when fresh site.
  • Prevent original_title differences from causing refreshes if title is present.
  • Ensure nav menu item url is set according to object when previewing.
  • Make sure initial saved state is false if there are dirty settings without an existing changeset.
  • Ensure dirty settings are cleaned upon changeset publishing.

Props helen, westonruter, ocean90.
Fixes #38114, #38533.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/theme.php

    r38985 r38991  
    17571757
    17581758/**
     1759 * Expand a theme's starter content configuration using core-provided data.
     1760 *
     1761 * @since 4.7.0
     1762 *
     1763 * @return array Array of starter content.
     1764 */
     1765function get_theme_starter_content() {
     1766    $theme_support = get_theme_support( 'starter-content' );
     1767    if ( ! empty( $theme_support ) ) {
     1768        $config = $theme_support[0];
     1769    } else {
     1770        $config = array();
     1771    }
     1772
     1773    $core_content = array (
     1774        'widgets' => array(
     1775            'text_business_info' => array ( 'text', array (
     1776                'title' => __( 'Find Us' ),
     1777                'text' => join( '', array (
     1778                    '<p><strong>' . __( 'Address' ) . '</strong><br />',
     1779                    __( '123 Main Street' ) . '<br />' . __( 'New York, NY 10001' ) . '</p>',
     1780                    '<p><strong>' . __( 'Hours' ) . '</strong><br />',
     1781                    __( 'Monday&mdash;Friday: 9:00AM&ndash;5:00PM' ) . '<br />' . __( 'Saturday &amp; Sunday: 11:00AM&ndash;3:00PM' ) . '</p>'
     1782                ) ),
     1783            ) ),
     1784            'search' => array ( 'search', array (
     1785                'title' => __( 'Site Search' ),
     1786            ) ),
     1787            'text_credits' => array ( 'text', array (
     1788                'title' => __( 'Site Credits' ),
     1789                'text' => sprintf( __( 'This site was created on %s' ), get_date_from_gmt( current_time( 'mysql', 1 ), 'c' ) ),
     1790            ) ),
     1791        ),
     1792        'nav_menus' => array (
     1793            'page_home' => array(
     1794                'type' => 'post_type',
     1795                'object' => 'page',
     1796                'object_id' => '{{home}}',
     1797            ),
     1798            'page_about' => array(
     1799                'type' => 'post_type',
     1800                'object' => 'page',
     1801                'object_id' => '{{about-us}}',
     1802            ),
     1803            'page_blog' => array(
     1804                'type' => 'post_type',
     1805                'object' => 'page',
     1806                'object_id' => '{{blog}}',
     1807            ),
     1808            'page_contact' => array(
     1809                'type' => 'post_type',
     1810                'object' => 'page',
     1811                'object_id' => '{{contact-us}}',
     1812            ),
     1813
     1814            'link_yelp' => array(
     1815                'title' => __( 'Yelp' ),
     1816                'url' => 'https://www.yelp.com',
     1817            ),
     1818            'link_facebook' => array(
     1819                'title' => __( 'Facebook' ),
     1820                'url' => 'https://www.facebook.com/wordpress',
     1821            ),
     1822            'link_twitter' => array(
     1823                'title' => __( 'Twitter' ),
     1824                'url' => 'https://twitter.com/wordpress',
     1825            ),
     1826            'link_instagram' => array(
     1827                'title' => __( 'Instagram' ),
     1828                'url' => 'https://www.instagram.com/explore/tags/wordcamp/',
     1829            ),
     1830            'link_email' => array(
     1831                'title' => __( 'Email' ),
     1832                'url' => 'mailto:wordpress@example.com',
     1833            ),
     1834        ),
     1835        'posts' => array(
     1836            'home' => array(
     1837                'post_type' => 'page',
     1838                'post_title' => __( 'Homepage' ),
     1839                'post_content' => __( 'Welcome home.' ),
     1840            ),
     1841            'about-us' => array(
     1842                'post_type' => 'page',
     1843                'post_title' => __( 'About Us' ),
     1844                'post_content' => __( 'More than you ever wanted to know.' ),
     1845            ),
     1846            'contact-us' => array(
     1847                'post_type' => 'page',
     1848                'post_title' => __( 'Contact Us' ),
     1849                'post_content' => __( 'Call us at 999-999-9999.' ),
     1850            ),
     1851            'blog' => array(
     1852                'post_type' => 'page',
     1853                'post_title' => __( 'Blog' ),
     1854            ),
     1855
     1856            'homepage-section' => array(
     1857                'post_type' => 'page',
     1858                'post_title' => __( 'A homepage section' ),
     1859                'post_content' => __( 'This is an example of a homepage section, which are managed in theme options.' ),
     1860            ),
     1861        ),
     1862    );
     1863
     1864    $content = array();
     1865
     1866    foreach ( $config as $type => $args ) {
     1867        switch( $type ) {
     1868            // Use options and theme_mods as-is
     1869            case 'options' :
     1870            case 'theme_mods' :
     1871                $content[ $type ] = $config[ $type ];
     1872                break;
     1873
     1874            // Widgets are an extra level down due to groupings
     1875            case 'widgets' :
     1876                foreach ( $config[ $type ] as $group => $items ) {
     1877                    foreach ( $items as $id ) {
     1878                        if ( ! empty( $core_content[ $type ] ) && ! empty( $core_content[ $type ][ $id ] ) ) {
     1879                            $content[ $type ][ $group ][ $id ] = $core_content[ $type ][ $id ];
     1880                        }
     1881                    }
     1882                }
     1883                break;
     1884
     1885            // And nav menus are yet another level down
     1886            case 'nav_menus' :
     1887                foreach ( $config[ $type ] as $group => $args2 ) {
     1888                    // Menu groups need a name
     1889                    if ( empty( $args['name'] ) ) {
     1890                        $args2['name'] = $group;
     1891                    }
     1892
     1893                    $content[ $type ][ $group ]['name'] = $args2['name'];
     1894
     1895                    // Do we need to check if this is empty?
     1896                    foreach ( $args2['items'] as $id ) {
     1897                        if ( ! empty( $core_content[ $type ] ) && ! empty( $core_content[ $type ][ $id ] ) ) {
     1898                            $content[ $type ][ $group ]['items'][ $id ] = $core_content[ $type ][ $id ];
     1899                        }
     1900                    }
     1901                }
     1902                break;
     1903
     1904
     1905            // Everything else should map at the next level
     1906            default :
     1907                foreach( $config[ $type ] as $id ) {
     1908                    if ( ! empty( $core_content[ $type ] ) && ! empty( $core_content[ $type ][ $id ] ) ) {
     1909                        $content[ $type ][ $id ] = $core_content[ $type ][ $id ];
     1910                    }
     1911                }
     1912                break;
     1913        }
     1914    }
     1915
     1916    /**
     1917     * Filters the expanded array of starter content.
     1918     *
     1919     * @since 4.7.0
     1920     *
     1921     * @param array $content Array of starter content.
     1922     * @param array $config  Array of theme-specific starter content configuration.
     1923     */
     1924    return apply_filters( 'get_theme_starter_content', $content, $config );
     1925}
     1926
     1927/**
    17591928 * Registers theme support for a given feature.
    17601929 *
     
    17681937 * @since 4.1.0 The `title-tag` feature was added
    17691938 * @since 4.5.0 The `customize-selective-refresh-widgets` feature was added
     1939 * @since 4.7.0 The `starter-content` feature was added
    17701940 *
    17711941 * @global array $_wp_theme_features
     
    17731943 * @param string $feature  The feature being added. Likely core values include 'post-formats',
    17741944 *                         'post-thumbnails', 'html5', 'custom-logo', 'custom-header-uploads',
    1775  *                         'custom-header', 'custom-background', 'title-tag', etc.
     1945 *                         'custom-header', 'custom-background', 'title-tag', 'starter-content', etc.
    17761946 * @param mixed  $args,... Optional extra arguments to pass along with certain features.
    17771947 * @return void|bool False on failure, void otherwise.
     
    22052375     * The dynamic portion of the hook name, `$feature`, refers to the specific theme
    22062376     * feature. Possible values include 'post-formats', 'post-thumbnails', 'custom-background',
    2207      * 'custom-header', 'menus', 'automatic-feed-links', 'html5', and `customize-selective-refresh-widgets`.
     2377     * 'custom-header', 'menus', 'automatic-feed-links', 'html5',
     2378     * 'starter-content', and 'customize-selective-refresh-widgets'.
    22082379     *
    22092380     * @since 3.4.0
Note: See TracChangeset for help on using the changeset viewer.