PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.8.2
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.8.2
4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.5.2 All 199 releases
betterdocs / includes / Editors / BlockEditor / Blocks / CodeSnippet.php

CodeSnippet.php in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 4.8.2, at includes/Editors/BlockEditor/Blocks/CodeSnippet.php

188 lines 6.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace WPDeveloper\BetterDocs\Editors\BlockEditor\Blocks;
3
4 if ( ! defined( 'ABSPATH' ) ) {
5 exit;
6 }
7
8
9 use WPDeveloper\BetterDocs\Editors\BlockEditor\Block;
10
11 class CodeSnippet extends Block {
12
13 protected $frontend_scripts = [ 'betterdocs-code-snippet' ];
14 protected $frontend_styles = [ 'betterdocs-code-snippet' ];
15
16 /**
17 * Unique name of the block
18 * @return string
19 */
20 public function get_name() {
21 return 'code-snippet';
22 }
23
24 /**
25 * Block default attributes
26 * @return array
27 */
28 public function get_default_attributes() {
29 return [
30 'blockId' => '',
31 'blockMeta' => (object) [],
32 'resOption' => 'Desktop',
33 'codeContent' => '',
34 'language' => 'javascript',
35 'codeVariants' => [],
36 'showLanguageLabel' => true,
37 'showCopyButton' => true,
38 'showHeader' => true,
39 'showLineNumbers' => false,
40 'theme' => 'light',
41 'fileName' => 'filename.js',
42 'showFileIcon' => true,
43 'fileIcon' => '',
44 'showTrafficLights' => true
45 ];
46 }
47
48 /**
49 * Register scripts and styles
50 */
51 public function register_scripts() {
52 $this->assets_manager->register( 'betterdocs-code-snippet', 'public/css/code-snippet.css' );
53 $this->assets_manager->register( 'betterdocs-code-snippet', 'public/js/code-snippet.js', [ 'wp-element' ] );
54
55 // Self-hosted Highlight.js (vendored under assets/static/vendor/highlightjs/,
56 // same convention as assets/vendor/scalar/). The frontend + editor read
57 // these URLs off the localized config instead of hitting cdnjs.
58 $this->assets_manager->localize(
59 'betterdocs-code-snippet',
60 'BetterDocsCodeSnippetConfig',
61 [
62 'hljsUrl' => $this->assets_manager->asset_url( 'vendor/highlightjs/highlight.min.js' ),
63 'cssLight' => $this->assets_manager->asset_url( 'vendor/highlightjs/github.min.css' ),
64 'cssDark' => $this->assets_manager->asset_url( 'vendor/highlightjs/github-dark.min.css' )
65 ]
66 );
67
68 // Enqueue CodeMirror for Gutenberg editor
69 if ( is_admin() ) {
70 add_action( 'enqueue_block_editor_assets', [ $this, 'enqueue_editor_assets' ], 5 );
71 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_editor_assets' ], 5 );
72 }
73 }
74
75 /**
76 * Enqueue CodeMirror assets for the block editor
77 */
78 public function enqueue_editor_assets() {
79 // Only enqueue on block editor pages
80 $screen = get_current_screen();
81 if ( ! $screen || ( $screen->base !== 'post' && $screen->base !== 'site-editor' ) ) {
82 return;
83 }
84
85 // Enqueue WordPress CodeMirror with basic settings
86 if ( function_exists( 'wp_enqueue_code_editor' ) ) {
87 wp_enqueue_code_editor( [
88 'type' => 'text/html'
89 ] );
90 }
91
92 // Enqueue frontend assets for syntax highlighting in editor preview
93 wp_enqueue_style( 'betterdocs-code-snippet' );
94 wp_enqueue_script( 'betterdocs-code-snippet' );
95 }
96
97 /**
98 * Check if we're in editor mode
99 * @return bool
100 */
101 public function is_editor_mode() {
102 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- REST request context check.
103 $context = isset( $_REQUEST['context'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['context'] ) ) : '';
104 return defined( 'REST_REQUEST' ) && REST_REQUEST && 'edit' === $context;
105 }
106
107 /**
108 * Render the block
109 * @param array $attributes
110 * @param string $content
111 */
112 public function render( $attributes, $content ) {
113 // Use the template with view_params
114 $this->views( 'templates/parts/code-snippet' );
115 }
116
117 /**
118 * View parameters for the template
119 * @return array
120 */
121 public function view_params() {
122 $attributes = &$this->attributes;
123
124 return [
125 'code_content' => $attributes['codeContent'],
126 'language' => $attributes['language'],
127 // Combined [primary + codeVariants] list the template renders as a
128 // language dropdown when it holds more than one entry.
129 'code_variants' => $this->build_variants( $attributes ),
130 'show_language_label' => $attributes['showLanguageLabel'],
131 'show_copy_button' => $attributes['showCopyButton'],
132 'show_header' => isset( $attributes['showHeader'] ) ? $attributes['showHeader'] : true,
133 'show_line_numbers' => $attributes['showLineNumbers'],
134 'theme' => $attributes['theme'],
135 'block_id' => $attributes['blockId'],
136 'widget_type' => 'blocks',
137 'is_editor_mode' => $this->is_editor_mode(),
138 // File Preview Header
139 'file_name' => isset( $attributes['fileName'] ) ? $attributes['fileName'] : 'filename.js',
140 'show_traffic_lights' => isset( $attributes['showTrafficLights'] ) ? $attributes['showTrafficLights'] : true,
141 'show_file_icon' => isset( $attributes['showFileIcon'] ) ? $attributes['showFileIcon'] : true,
142 'file_icon' => isset( $attributes['fileIcon'] ) ? $attributes['fileIcon'] : '',
143 ];
144 }
145
146 /**
147 * Build the ordered language list: the primary language/code first, then
148 * each non-empty entry from `codeVariants`. One entry → single-language
149 * (renders exactly as before); more → language dropdown.
150 *
151 * @param array $attributes
152 * @return array<int, array{language: string, code: string, file_name: string}>
153 */
154 protected function build_variants( $attributes ) {
155 $variants = [];
156
157 $primary_code = isset( $attributes['codeContent'] ) ? (string) $attributes['codeContent'] : '';
158 if ( '' !== $primary_code ) {
159 $variants[] = [
160 'language' => isset( $attributes['language'] ) ? (string) $attributes['language'] : 'javascript',
161 'code' => $primary_code,
162 'file_name' => isset( $attributes['fileName'] ) ? (string) $attributes['fileName'] : ''
163 ];
164 }
165
166 if ( ! empty( $attributes['codeVariants'] ) && is_array( $attributes['codeVariants'] ) ) {
167 foreach ( $attributes['codeVariants'] as $variant ) {
168 if ( ! is_array( $variant ) ) {
169 continue;
170 }
171
172 $code = isset( $variant['codeContent'] ) ? (string) $variant['codeContent'] : '';
173 if ( '' === $code ) {
174 continue;
175 }
176
177 $variants[] = [
178 'language' => isset( $variant['language'] ) ? (string) $variant['language'] : 'javascript',
179 'code' => $code,
180 'file_name' => isset( $variant['fileName'] ) ? (string) $variant['fileName'] : ''
181 ];
182 }
183 }
184
185 return $variants;
186 }
187 }
188