PluginProbe
CryptX / trunk
CryptX vtrunk
4.2.0 4.1.1 trunk 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.9 2.0 2.1 2.2 2.3 2.3.1 2.3.2 2.3.3 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 All 92 releases
cryptx / src / components / HelpTab.js

HelpTab.js in CryptX trunk, at src/components/HelpTab.js

309 lines 9.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Reference material: the shortcode, the template functions, the JavaScript
3 * helpers and what changed in each release.
4 *
5 * The per-option explanations deliberately live next to the options rather
6 * than here -- this tab is for the things that have no control to sit beside.
7 */
8
9 import { useEffect, useState } from '@wordpress/element';
10 import apiFetch from '@wordpress/api-fetch';
11 import { __, _n, sprintf } from '@wordpress/i18n';
12 import {
13 Card,
14 CardBody,
15 CardHeader,
16 ExternalLink,
17 } from '@wordpress/components';
18
19 function Snippet( { children } ) {
20 return (
21 <pre className="cryptx-help__snippet">
22 <code>{ children }</code>
23 </pre>
24 );
25 }
26
27 /**
28 * One release: its version and what changed in it.
29 *
30 * @param {Object} props Component props.
31 * @param {Object} props.release The release, as the endpoint delivers it.
32 * @param {boolean} props.isCurrent Whether this is the installed version.
33 * @return {Element} The rendered release.
34 */
35 function Release( { release, isCurrent } ) {
36 return (
37 <section className="cryptx-help__release">
38 <h3>
39 { release.version }
40 { isCurrent && (
41 <span className="cryptx-help__badge">
42 { __( 'installed', 'cryptx' ) }
43 </span>
44 ) }
45 </h3>
46 <ul>
47 { release.items.map( ( item, index ) => (
48 <li
49 key={ index }
50 // The entries come from readme.txt and were run through
51 // wp_kses on the server; they carry links to the support
52 // forum.
53
54 dangerouslySetInnerHTML={ { __html: item } }
55 />
56 ) ) }
57 </ul>
58 </section>
59 );
60 }
61
62 function Changelog() {
63 const [ data, setData ] = useState( null );
64
65 useEffect( () => {
66 apiFetch( { path: '/cryptx/v1/changelog' } )
67 .then( ( response ) => setData( response ) )
68 .catch( () => setData( { releases: [], current: '' } ) );
69 }, [] );
70
71 if ( data === null ) {
72 return <p>{ __( 'Loading…', 'cryptx' ) }</p>;
73 }
74
75 const { releases, current } = data;
76
77 if ( ! releases || releases.length === 0 ) {
78 return <p>{ __( 'No changelog available.', 'cryptx' ) }</p>;
79 }
80
81 const [ newest, ...older ] = releases;
82
83 return (
84 <div className="cryptx-help__changelog">
85 <Release
86 release={ newest }
87 isCurrent={ newest.version === current }
88 />
89
90 { /* Twelve releases printed in full ran to some two thousand pixels
91 and buried the shortcode documentation above them. The one
92 people came for is the newest; the rest are one click away
93 rather than gone. */ }
94 { older.length > 0 && (
95 <details className="cryptx-help__older">
96 <summary>
97 { sprintf(
98 /* translators: %d: number of older releases */
99 _n(
100 'Show %d earlier release',
101 'Show %d earlier releases',
102 older.length,
103 'cryptx'
104 ),
105 older.length
106 ) }
107 </summary>
108 { older.map( ( release ) => (
109 <Release
110 key={ release.version }
111 release={ release }
112 isCurrent={ release.version === current }
113 />
114 ) ) }
115 </details>
116 ) }
117 </div>
118 );
119 }
120
121 export default function HelpTab() {
122 return (
123 <div
124 className="cryptx-tab-panel"
125 role="tabpanel"
126 id="cryptx-panel-help"
127 aria-labelledby="cryptx-tab-help"
128 >
129 <Card className="cryptx-section">
130 <CardHeader>
131 <h2 className="cryptx-section__title">
132 { __( 'Protect a single address', 'cryptx' ) }
133 </h2>
134 </CardHeader>
135 <CardBody>
136 <p>
137 { __(
138 'In the editor, look for the "Protected email address" block — it does the same thing with fields instead of syntax, and it is the easier way in. The shortcode below is for everywhere a block cannot go: a widget, a custom field, a theme template.',
139 'cryptx'
140 ) }
141 </p>
142 <p>
143 { __(
144 'Both outrank the two ways of switching CryptX off: they work in posts you excluded, and inside them no address is exempt, however the list under Exceptions reads. That makes them the way to protect one address in otherwise untouched content.',
145 'cryptx'
146 ) }
147 </p>
148 <Snippet>{ '[cryptx]info@example.com[/cryptx]' }</Snippet>
149 <p>
150 { __(
151 'Almost any setting from this screen can be overridden for a single shortcode by using its option name, written in lower case. The list of addresses to leave alone is the exception, and deliberately so: a shortcode says "protect this one", so nothing inside it is ever exempt.',
152 'cryptx'
153 ) }
154 </p>
155 <Snippet>
156 {
157 '[cryptx opt_linktext="1" alt_linktext="Contact us"]info@example.com[/cryptx]'
158 }
159 </Snippet>
160 <p>
161 { __(
162 'On top of the settings, four attributes describe the mail itself. They end up inside the encrypted link, so they stay hidden from spam bots just like the address:',
163 'cryptx'
164 ) }
165 </p>
166 <Snippet>
167 {
168 '[cryptx subject="Price enquiry" cc="sales@example.com"]info@example.com[/cryptx]'
169 }
170 </Snippet>
171 <p>
172 { __(
173 'Available are subject, body, cc and bcc — the headers RFC 6068 allows in a mailto link. Anything else is dropped. A link you wrote yourself with its own "?subject=" keeps it; the attribute only fills in where nothing is set.',
174 'cryptx'
175 ) }
176 </p>
177 <p className="cryptx-help__note">
178 { __(
179 'The shortcode needs an address between its tags. Written self-closing, as [cryptx subject="…" /], there is nothing to protect and nothing is output — the attributes go nowhere.',
180 'cryptx'
181 ) }
182 </p>
183 <p className="cryptx-help__note">
184 { __(
185 'Until 4.1.0 the attribute "subject" was accepted and then silently discarded, and an address written as "info@example.com?subject=…" lost its subject on the way as well. Both work now. The attribute "linktext", also listed by older versions of this page, never existed — use alt_linktext.',
186 'cryptx'
187 ) }
188 </p>
189 </CardBody>
190 </Card>
191
192 <Card className="cryptx-section">
193 <CardHeader>
194 <h2 className="cryptx-section__title">
195 { __( 'In a theme', 'cryptx' ) }
196 </h2>
197 </CardHeader>
198 <CardBody>
199 <Snippet>
200 {
201 "<?php echo cryptx_encrypt( 'info@example.com' ); ?>"
202 }
203 </Snippet>
204 <p>
205 { __(
206 'Takes an optional array of settings as its second argument, using the same option names as the shortcode.',
207 'cryptx'
208 ) }
209 </p>
210 <p className="cryptx-help__note">
211 { __(
212 'The older function encryptx() still exists but is deprecated and will be removed in a future major release.',
213 'cryptx'
214 ) }
215 </p>
216 </CardBody>
217 </Card>
218
219 <Card className="cryptx-section">
220 <CardHeader>
221 <h2 className="cryptx-section__title">
222 { __( 'In your own JavaScript', 'cryptx' ) }
223 </h2>
224 </CardHeader>
225 <CardBody>
226 <p>
227 { __(
228 'For addresses that are added to the page after it loaded, and therefore never passed through the server side filters.',
229 'cryptx'
230 ) }
231 </p>
232 <Snippet>
233 { `const link = document.createElement( 'a' );
234 link.href = generateDeCryptXHandler( 'info@example.com' );
235 link.textContent = 'Contact us';` }
236 </Snippet>
237 </CardBody>
238 </Card>
239
240 <Card className="cryptx-section">
241 <CardHeader>
242 <h2 className="cryptx-section__title">
243 { __( 'On the command line', 'cryptx' ) }
244 </h2>
245 </CardHeader>
246 <CardBody>
247 <p>
248 { __(
249 'With WP-CLI installed. The first two read and write the settings, through the same validation this screen uses.',
250 'cryptx'
251 ) }
252 </p>
253 <Snippet>
254 { `wp cryptx settings
255 wp cryptx settings opt_linktext
256 wp cryptx settings disable_rss 0` }
257 </Snippet>
258 <p>
259 { __(
260 'The third is the one worth knowing about: it runs the body and the title of every published post through the filters that render it, and reports the ones that still carry a readable address. That is the question you have after changing a setting, and the preview above cannot answer it — it only ever renders a single sample.',
261 'cryptx'
262 ) }
263 </p>
264 <Snippet>{ 'wp cryptx scan' }</Snippet>
265 <p className="cryptx-help__note">
266 { __(
267 'A verdict of "encoded" means the address is in the page as HTML entities. That is invisible to a naive scanner and plain to anything that decodes them, which is most things — it is not the same as "hidden".',
268 'cryptx'
269 ) }
270 </p>
271 <p className="cryptx-help__note">
272 { __(
273 'An address in a post title is always reported, because CryptX cannot protect one: the title reaches the document head through WordPress itself, along a path no plugin filter touches. Take it out of the title. And what the scan does not cover: widgets, comments, feeds, and whatever a theme prints on its own.',
274 'cryptx'
275 ) }
276 </p>
277 <p>
278 { __(
279 'On a multisite network both take --url, so one shell loop covers every site:',
280 'cryptx'
281 ) }
282 </p>
283 <Snippet>
284 {
285 'wp site list --field=url | xargs -I{} wp cryptx scan --url={}'
286 }
287 </Snippet>
288 </CardBody>
289 </Card>
290
291 <Card className="cryptx-section">
292 <CardHeader>
293 <h2 className="cryptx-section__title">
294 { __( 'What changed', 'cryptx' ) }
295 </h2>
296 </CardHeader>
297 <CardBody>
298 <Changelog />
299 <p>
300 <ExternalLink href="https://wordpress.org/plugins/cryptx/#developers">
301 { __( 'Full history on wordpress.org', 'cryptx' ) }
302 </ExternalLink>
303 </p>
304 </CardBody>
305 </Card>
306 </div>
307 );
308 }
309