Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 2e3353d

Browse files
authoredJan 23, 2025
Merge pull request #213 from codesnippetspro/19-add-snippet-name-to-shortcode
4 features to review in this PR
2 parents 21b09ee + 2ad4e43 commit 2e3353d

File tree

7 files changed

+53
-19
lines changed

7 files changed

+53
-19
lines changed
 

‎src/css/edit.scss

+6
Original file line numberDiff line numberDiff line change
@@ -152,3 +152,9 @@ p.snippet-scope, .snippet-scope p {
152152
.wrap .notice {
153153
scroll-margin: 0.75em;
154154
}
155+
156+
#edit-snippet-form-container .cs-sticky-notice {
157+
position: sticky;
158+
top: 40px;
159+
z-index: 100;
160+
}

‎src/css/manage.scss

-8
Original file line numberDiff line numberDiff line change
@@ -72,20 +72,12 @@ $inactive-color: #ccc;
7272
border-radius: 50%;
7373
}
7474

75-
&:hover::before {
76-
transform: translateX(40%);
77-
}
78-
7975
.snippets .active-snippet & {
8076
background-color: $active-color;
8177

8278
&::before {
8379
transform: translateX(100%);
8480
}
85-
86-
&:hover::before {
87-
transform: translateX(60%);
88-
}
8981
}
9082

9183
.snippets .erroneous-snippet &::before {

‎src/js/components/SnippetForm/fields/ScopeInput.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { buildShortcodeTag } from '../../../utils/shortcodes'
77
import { getSnippetType } from '../../../utils/snippets'
88
import { CopyToClipboardButton } from '../../common/CopyToClipboardButton'
99
import { useSnippetForm } from '../../../hooks/useSnippetForm'
10+
import { truncateWords } from '../../../utils/text'
1011
import type { ShortcodeAtts } from '../../../utils/shortcodes'
1112
import type { SnippetScope } from '../../../types/Snippet'
1213
import type { Dispatch, SetStateAction} from 'react'
@@ -117,6 +118,7 @@ const ShortcodeInfo: React.FC = () => {
117118
<>
118119
<ShortcodeTag atts={{
119120
id: snippet.id,
121+
name: truncateWords(snippet.name),
120122
network: snippet.network ?? isNetworkAdmin(),
121123
...options
122124
}} />

‎src/js/components/SnippetForm/page/Notices.tsx

+12-8
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,31 @@ import classnames from 'classnames'
22
import React, { useEffect } from 'react'
33
import { __, sprintf } from '@wordpress/i18n'
44
import { useSnippetForm } from '../../../hooks/useSnippetForm'
5-
import type { MouseEventHandler, ReactNode} from 'react'
5+
import type { ReactNode } from 'react'
66

77
interface DismissibleNoticeProps {
88
classNames?: classnames.Argument
9-
onRemove: MouseEventHandler<HTMLButtonElement>
9+
onRemove: VoidFunction
1010
children?: ReactNode
11+
autoHide?: boolean
1112
}
1213

13-
const DismissibleNotice: React.FC<DismissibleNoticeProps> = ({ classNames, onRemove, children }) => {
14+
const DismissibleNotice: React.FC<DismissibleNoticeProps> = ({ classNames, onRemove, children, autoHide = true }) => {
1415
useEffect(() => {
15-
if (window.CODE_SNIPPETS_EDIT?.scrollToNotices) {
16-
window.scrollTo({ top: 0, behavior: 'smooth' })
16+
if (autoHide) {
17+
const timer = setTimeout(onRemove, 5000)
18+
return () => clearTimeout(timer)
1719
}
18-
}, [])
20+
return undefined
21+
}, [autoHide, onRemove])
1922

2023
return (
21-
<div id="message" className={classnames('notice fade is-dismissible', classNames)}>
24+
<div id="message" className={classnames('cs-sticky-notice notice fade is-dismissible', classNames)}>
2225
<>{children}</>
2326

2427
<button type="button" className="notice-dismiss" onClick={event => {
2528
event.preventDefault()
26-
onRemove(event)
29+
onRemove()
2730
}}>
2831
<span className="screen-reader-text">{__('Dismiss notice.', 'code-snippets')}</span>
2932
</button>
@@ -45,6 +48,7 @@ export const Notices: React.FC = () => {
4548
<DismissibleNotice
4649
classNames="error"
4750
onRemove={() => setSnippet(previous => ({ ...previous, code_error: null }))}
51+
autoHide={false}
4852
>
4953
<p>
5054
<strong>{sprintf(

‎src/js/types/Shortcodes.ts

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export interface SourceShortcodeAtts {
55

66
export interface ContentShortcodeAtts {
77
id: string
8+
name: string
89
php: boolean
910
format: boolean
1011
shortcodes: boolean

‎src/js/utils/text.ts

+7
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,10 @@ export const trimLeadingChar = (text: string, character: string): string =>
66

77
export const trimTrailingChar = (text: string, character: string): string =>
88
character === text.charAt(text.length - 1) ? text.slice(0, -1) : text
9+
10+
export const truncateWords = (text: string, wordCount: number = 3): string => {
11+
const words = text.trim().split(/\s+/);
12+
return words.length > wordCount
13+
? `${words.slice(0, wordCount).join(' ')}...`
14+
: text;
15+
};

‎src/php/front-end/class-front-end.php

+25-3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ class Front_End {
2828
*/
2929
const PRISM_HANDLE = 'code-snippets-prism';
3030

31+
/**
32+
* Maximum depth for shortcode recursion.
33+
*/
34+
const MAX_SHORTCODE_DEPTH = 5;
35+
3136
/**
3237
* Class constructor
3338
*/
@@ -235,7 +240,7 @@ protected function convert_boolean_attribute_flags( array $atts, array $boolean_
235240
*
236241
* @return string Evaluated shortcode content.
237242
*/
238-
protected function evaluate_shortcode_content( Snippet $snippet, array $atts ): string {
243+
protected function evaluate_shortcode_content( Snippet $snippet, array $atts ): string {
239244
if ( empty( $atts['php'] ) ) {
240245
return $snippet->code;
241246
}
@@ -325,8 +330,25 @@ public function render_content_shortcode( array $atts ): string {
325330
// Remove this shortcode from the list to prevent recursion.
326331
remove_shortcode( self::CONTENT_SHORTCODE );
327332

328-
// Evaluate shortcodes.
329-
$content = do_shortcode( $atts['format'] ? shortcode_unautop( $content ) : $content );
333+
// Recursion depth is limited to prevent infinite loops.
334+
static $depth = 0;
335+
$max_depth = self::MAX_SHORTCODE_DEPTH;
336+
337+
// Find the shortcode in the content and replace it with the evaluated content.
338+
$content = preg_replace_callback(
339+
'/\[' . self::CONTENT_SHORTCODE . '([^\]]*)\]/',
340+
function ($matches) use (&$depth, $max_depth) {
341+
if ($depth >= $max_depth) {
342+
return '<!-- Max shortcode depth reached -->';
343+
}
344+
$depth++;
345+
$atts = shortcode_parse_atts($matches[1]);
346+
$result = $this->render_content_shortcode($atts);
347+
$depth--;
348+
return $result;
349+
},
350+
$content
351+
);
330352

331353
// Add this shortcode back to the list.
332354
add_shortcode( self::CONTENT_SHORTCODE, [ $this, 'render_content_shortcode' ] );

0 commit comments

Comments
 (0)