documentation page. */ private const TAB_DOCS = [ 'appearance' => 'appearance', 'menu-builder' => 'menu-builder', 'toolbar' => 'toolbar', 'dashboard' => 'dashboard', 'content' => 'content-and-tables', 'cleanup' => 'admin-cleanup', 'frontend' => 'front-end', 'security' => 'security', 'login' => 'login', 'maintenance' => 'maintenance', 'analytics' => 'analytics', 'whitelabel' => 'white-label', 'site' => 'site-identity', 'tools' => 'tools', ]; private Settings $settings; public function __construct( Settings $settings ) { $this->settings = $settings; } /** * Off in a white-labelled admin: clients shouldn't land on a product page. */ public function visible() : bool { $visible = true; return $visible; } /** * A documentation page ('' for the index). */ public static function docsUrl( string $page = '' ) : string { $url = self::DOCS_URL . (( $page !== '' ? trailingslashit( $page ) : '' )); /** * Filters a documentation link on the settings screen. * * @param string $url The link. * @param string $page The page slug ('' for the index). */ return (string) apply_filters( 'featherdash/docs_url', $url, $page ); } /** * "Docs" link at the top of a settings tab. */ public function tabLink( string $tab ) : void { if ( !$this->visible() || !isset( self::TAB_DOCS[$tab] ) ) { return; } printf( '

%s %s

', esc_url( self::docsUrl( self::TAB_DOCS[$tab] ) ), esc_html__( 'Docs', 'featherdash' ), esc_html__( '(opens in a new tab)', 'featherdash' ) ); } /** * @param array> $sections Schema::sections(). */ public function render( array $sections, callable $proCard ) : void { if ( !$this->visible() ) { return; } ?>
renderIntro(); ?> renderDocs( $sections ); ?> renderNews(); ?>

DigitalBrew
> $sections */ private function renderDocs( array $sections ) : void { $tabs = []; foreach ( $sections as $key => $section ) { $tabs[(string) $key] = [(string) ($section['icon'] ?? ''), (string) $section['label']]; if ( $key === 'appearance' ) { $tabs['menu-builder'] = ['dashicons-menu-alt', __( 'Menu builder', 'featherdash' )]; } } $tabs['tools'] = ['dashicons-admin-tools', __( 'Tools', 'featherdash' )]; $guides = [ ['dashicons-flag', __( 'Getting started', 'featherdash' ), 'getting-started'], ['dashicons-editor-help', __( 'FAQ', 'featherdash' ), 'faq'], ['dashicons-admin-plugins', __( 'Plugin compatibility', 'featherdash' ), 'compatibility'], ['dashicons-editor-code', __( 'Developers: hooks and constants', 'featherdash' ), 'developers'] ]; ?>

} */ private static function latestChanges( int $limit ) : array { $file = FEATHERDASH_DIR . 'CHANGELOG.md'; if ( !is_readable( $file ) ) { return ['', []]; } $version = ''; $items = []; foreach ( (array) file( $file, FILE_IGNORE_NEW_LINES ) as $line ) { $line = (string) $line; if ( preg_match( '/^## \\[([^\\]]+)\\]/', $line, $match ) ) { if ( $version !== '' ) { break; } $version = $match[1]; continue; } if ( $version === '' || !str_starts_with( $line, '- ' ) ) { continue; } $text = substr( $line, 2 ); $title = ''; // "**Name** (where): description" → a bold name and the description. if ( preg_match( '/^\\*\\*(.+?)\\*\\*(?:\\s*\\([^)]*\\))?[:.]?\\s*(.*)$/', $text, $match ) ) { $title = self::plain( $match[1] ); $text = $match[2]; } $items[] = [$title, wp_trim_words( self::plain( $text ), 24 )]; if ( count( $items ) >= $limit ) { break; } } return [$version, $items]; } /** * Markdown inline formatting to plain text. */ private static function plain( string $text ) : string { $text = (string) preg_replace( '/\\[([^\\]]+)\\]\\([^)]*\\)/', '$1', $text ); return trim( str_replace( ['**', '`', '*'], '', $text ) ); } }