PluginProbe ʕ •ᴥ•ʔ
Timeline Blocks for Gutenberg / trunk
Timeline Blocks for Gutenberg vtrunk
timeline-blocks / src / blocks / edit.js
timeline-blocks / src / blocks Last commit date
components 7 years ago styles 6 years ago edit.js 6 years ago index.js 7 years ago index.php 2 months ago tb_generatecss.js 7 years ago tb_styling.js 7 years ago
edit.js
831 lines
1 /**
2 * External dependencies
3 */
4
5 import get from 'lodash/get';
6 import isUndefined from 'lodash/isUndefined';
7 import pickBy from 'lodash/pickBy';
8 import moment from 'moment';
9 import classnames from 'classnames';
10 import { stringify } from 'querystringify';
11 import tb_styling from './tb_styling';
12
13 // Import all of our Text Options requirements.
14 import TypographyControl from "./components/typography";
15
16 const {
17 Component,
18 Fragment
19 } = wp.element;
20
21 const {
22 __,
23 sprintf
24 } = wp.i18n;
25
26 const {
27 decodeEntities
28 } = wp.htmlEntities;
29
30 const {
31 apiFetch
32 } = wp;
33
34 const {
35 registerStore,
36 withSelect,
37 } = wp.data;
38
39 const {
40 PanelBody,
41 Placeholder,
42 QueryControls,
43 RangeControl,
44 SelectControl,
45 Spinner,
46 TextControl,
47 ToggleControl,
48 Toolbar,
49 withAPIData,
50 } = wp.components;
51
52 const {
53 InspectorControls,
54 BlockAlignmentToolbar,
55 BlockControls,
56 ColorPalette,
57 } = wp.editor;
58
59 const MAX_POSTS_COLUMNS = 4;
60
61 class LatestPostsBlock extends Component {
62 constructor() {
63 super(...arguments);
64 this.toggleDisplayPostDate = this.toggleDisplayPostDate.bind(this);
65 this.toggleDisplayPostExcerpt = this.toggleDisplayPostExcerpt.bind(this);
66 this.toggleDisplayPostAuthor = this.toggleDisplayPostAuthor.bind(this);
67 this.toggleDisplayPostTag = this.toggleDisplayPostTag.bind(this);
68 this.toggleDisplayPostCategory = this.toggleDisplayPostCategory.bind(this);
69 this.toggleDisplayPostImage = this.toggleDisplayPostImage.bind(this);
70 this.toggleDisplayPostLink = this.toggleDisplayPostLink.bind(this);
71 this.toggleDisplayPostComments = this.toggleDisplayPostComments.bind(this);
72 this.toggleDisplayPostSocialshare = this.toggleDisplayPostSocialshare.bind(this);
73 }
74
75 toggleDisplayPostDate() {
76 const {
77 displayPostDate
78 } = this.props.attributes;
79 const {
80 setAttributes
81 } = this.props;
82 setAttributes({
83 displayPostDate: !displayPostDate
84 });
85 }
86
87 toggleDisplayPostExcerpt() {
88 const {
89 displayPostExcerpt
90 } = this.props.attributes;
91 const {
92 setAttributes
93 } = this.props;
94 setAttributes({
95 displayPostExcerpt: !displayPostExcerpt
96 });
97 }
98
99 customizeWordsExcerpt() {
100 const {
101 wordsExcerpt
102 } = this.props.attributes;
103 const {
104 setAttributes
105 } = this.props;
106 setAttributes({
107 wordsExcerpt: !wordsExcerpt
108 });
109 }
110
111 toggleDisplayPostAuthor() {
112 const {
113 displayPostAuthor
114 } = this.props.attributes;
115 const {
116 setAttributes
117 } = this.props;
118 setAttributes({
119 displayPostAuthor: !displayPostAuthor
120 });
121 }
122
123 toggleDisplayPostTag() {
124 const {
125 displayPostTag
126 } = this.props.attributes;
127 const {
128 setAttributes
129 } = this.props;
130 setAttributes({
131 displayPostTag: !displayPostTag
132 });
133 }
134
135 toggleDisplayPostCategory() {
136 const {
137 displayPostCategory
138 } = this.props.attributes;
139 const {
140 setAttributes
141 } = this.props;
142 setAttributes({
143 displayPostCategory: !displayPostCategory
144 });
145 }
146 toggleDisplayPostComments() {
147 const {
148 displayPostComments
149 } = this.props.attributes;
150 const {
151 setAttributes
152 } = this.props;
153 setAttributes({
154 displayPostComments: !displayPostComments
155 });
156 }
157 toggleDisplayPostImage() {
158 const {
159 displayPostImage
160 } = this.props.attributes;
161 const {
162 setAttributes
163 } = this.props;
164 setAttributes({
165 displayPostImage: !displayPostImage
166 });
167 }
168
169 toggleDisplayPostLink() {
170 const {
171 displayPostLink
172 } = this.props.attributes;
173 const {
174 setAttributes
175 } = this.props;
176 setAttributes({
177 displayPostLink: !displayPostLink
178 });
179 }
180 toggleDisplayPostSocialshare() {
181 const {
182 displayPostSocialshare
183 } = this.props.attributes;
184 const {
185 setAttributes
186 } = this.props;
187 setAttributes({
188 displayPostSocialshare: !displayPostSocialshare
189 });
190 }
191 customizeReadMoreText() {
192 const {
193 readMoreText
194 } = this.props.attributes;
195 const {
196 setAttributes
197 } = this.props;
198 setAttributes({
199 readMoreText: !readMoreText
200 });
201 }
202
203 componentDidMount() {
204 this.props.setAttributes( { block_id: this.props.clientId } )
205 const $style = document.createElement( "style" )
206 $style.setAttribute( "id", "tb-style-" + this.props.clientId )
207 document.head.appendChild( $style )
208 }
209
210 render() {
211 const {
212 attributes,
213 isSelected,
214 categoriesList,
215 setAttributes,
216 latestPosts
217 } = this.props;
218 const {
219 // Typography Settings
220 block_id,
221 titleTag,
222 titlefontSize,
223 titleFontFamily,
224 titleFontWeight,
225 titleFontSubset,
226 postmetafontSize,
227 postexcerptfontSize,
228 postctafontSize,
229 metaFontFamily,
230 metaFontSubset,
231 metafontWeight,
232 excerptFontFamily,
233 excerptFontWeight,
234 excerptFontSubset,
235 ctaFontFamily,
236 ctaFontSubset,
237 ctafontWeight,
238 socialSharefontSize,
239 // Readmore Settings
240 readmoreView,
241 // Space Settings
242 belowTitleSpace,
243 belowImageSpace,
244 belowexerptSpace,
245 belowctaSpace,
246 innerSpace,
247 // Color Settings
248 boxbgColor,
249 titleColor,
250 postmetaColor,
251 postexcerptColor,
252 postctaColor,
253 socialShareColor,
254 readmoreBgColor,
255 timelineBgColor,
256 timelineFgColor,
257 // Post Settings
258 layoutcount,
259 displayPostDate,
260 displayPostExcerpt,
261 displayPostAuthor,
262 displayPostComments,
263 displayPostTag,
264 displayPostCategory,
265 displayPostImage,
266 displayPostLink,
267 displayPostSocialshare,
268 align,
269 columns,
270 order,
271 orderBy,
272 categories,
273 postsToShow,
274 width,
275 imageCrop,
276 readMoreText,
277 wordsExcerpt
278 } = attributes;
279
280 function createLevelControl( targetLevel ) {
281 return {
282 icon: 'shield',
283 title: sprintf( __( 'Template %d' ), targetLevel ),
284 default:1,
285 isActive: targetLevel === layoutcount,
286 onClick: () => setAttributes( { layoutcount: targetLevel } ),
287 subscript: String( targetLevel ),
288 };
289 }
290
291 // Thumbnail options
292 const imageCropOptions = [
293 { value: 'landscape', label: __('Landscape')},
294 { value: 'square', label: __('Square')},
295 ];
296 const isLandscape = imageCrop === 'landscape';
297 // Title tag options
298 const tbtitletag = [
299 { value: 'h1', label: __('H1') },
300 { value: 'h2', label: __('H2') },
301 { value: 'h3', label: __('H3') },
302 { value: 'h4', label: __('H4') },
303 { value: 'h5', label: __('H5') },
304 { value: 'h6', label: __('H6') },
305 ];
306 //Readmore options
307 const reamoreText = [
308 { value: 'text-only', label: __('Text Only') },
309 { value: 'tb-button', label: __('Button') },
310 ];
311 //Create title tag
312 const Tag = attributes.titleTag;
313
314 const inspectorControls = ( isSelected && ( <InspectorControls >
315 <PanelBody title = { __('Template Selection') } >
316 <Toolbar className="tb-timeline-template-selection" controls={ _.range( 1, 3 ).map( createLevelControl ) } />
317 </PanelBody>
318 <PanelBody title = { __('Post Settings') } initialOpen={ false } >
319 <QueryControls { ...{ order, orderBy } }
320 numberOfItems = { postsToShow }
321 categoriesList = { categoriesList }
322 selectedCategoryId = { categories }
323 onOrderChange = { (value) => setAttributes({ order: value }) }
324 onOrderByChange = { (value) => setAttributes({ orderBy: value })}
325 onCategoryChange = {(value) => setAttributes({ categories: '' !== value ? value : undefined }) }
326 onNumberOfItemsChange = {(value) => setAttributes({ postsToShow: value }) } />
327 <ToggleControl label = { __('Display Featured Image') } checked = { displayPostImage } onChange = { this.toggleDisplayPostImage } />
328 { displayPostImage && <SelectControl label = { __('Featured Image Style') }
329 options = { imageCropOptions } value = { imageCrop } onChange = {(value) => this.props.setAttributes({ imageCrop: value }) } /> }
330 <ToggleControl label = { __('Display Post Author') } checked = { displayPostAuthor } onChange = { this.toggleDisplayPostAuthor } />
331 <ToggleControl label = { __('Display Post Tag') } checked = { displayPostTag } onChange = { this.toggleDisplayPostTag } />
332 <ToggleControl label = { __('Display Post Category') } checked = { displayPostCategory } onChange = { this.toggleDisplayPostCategory}/>
333 <ToggleControl label = { __('Display Post Comment') } checked = { displayPostComments } onChange = { this.toggleDisplayPostComments } />
334 <ToggleControl label = { __('Display Post Date')} checked = { displayPostDate } onChange = { this.toggleDisplayPostDate } />
335 <ToggleControl label = { __('Display Post Excerpt') } checked = { displayPostExcerpt } onChange = { this.toggleDisplayPostExcerpt }/> {
336 displayPostExcerpt &&
337 <TextControl label = { __('Number of words for Excerpt') } type = "text" value = { wordsExcerpt } onChange = { (value) => this.props.setAttributes({ wordsExcerpt: value }) } />
338 }
339 <ToggleControl label = { __('Display Social share Icon') } checked = { displayPostSocialshare } onChange = { this.toggleDisplayPostSocialshare } />
340 </PanelBody>
341
342 <PanelBody title = { __('Readmore Settings') } initialOpen={ false } >
343 <ToggleControl label = { __('Display Read More Link') }
344 checked = { displayPostLink }
345 onChange = { this.toggleDisplayPostLink }
346 />
347 { displayPostLink &&
348 <Fragment>
349 <TextControl label = { __('Customize Read More Link') }
350 type = "text"
351 value = { readMoreText }
352 onChange = { (value) => this.props.setAttributes({ readMoreText: value }) }
353 />
354
355 <SelectControl label = { __('Readmore View') }
356 options = { reamoreText }
357 value = {readmoreView}
358 onChange = { (value) => this.props.setAttributes({ readmoreView: value}) }
359 />
360 </Fragment>
361 }
362 </PanelBody>
363
364 <PanelBody title={ __('Typography Settings')} initialOpen={ false }>
365
366 <SelectControl label = { __('Select Title tag') }
367 options = { tbtitletag }
368 value = { titleTag }
369 onChange = { (value) => this.props.setAttributes({ titleTag: value}) }
370 />
371
372 <RangeControl
373 label = { __('Title Fontsize') } value = { titlefontSize }
374 onChange = { (value) => setAttributes({ titlefontSize: value }) }
375 min = { 12 }
376 max = { 50 }
377 beforeIcon="editor-textcolor"
378 allowReset
379 />
380 <TypographyControl
381 label={ __( "Title Fontfamily" ) }
382 attributes = { attributes }
383 setAttributes = { setAttributes }
384 fontFamily = { { value: titleFontFamily, label: __( "titleFontFamily" ) } }
385 fontWeight = { { value: titleFontWeight, label: __( "titleFontWeight" ) } }
386 fontSubset = { { value: titleFontSubset, label: __( "titleFontSubset" ) } }
387 />
388
389 <hr class="tb-divider"/>
390 <RangeControl
391 label = { __('Meta Fontsize') } value = { postmetafontSize }
392 onChange = { (value) => setAttributes({ postmetafontSize: value }) }
393 min = { 12 }
394 max = { 50 }
395 beforeIcon="editor-textcolor"
396 allowReset
397 />
398 <TypographyControl
399 label={ __( "Meta Fontfamily" ) }
400 attributes = { attributes }
401 setAttributes = { setAttributes }
402 fontFamily = { { value: metaFontFamily, label: __( "metaFontFamily" ) } }
403 fontWeight = { { value: metafontWeight, label: __( "metafontWeight" ) } }
404 fontSubset = { { value: metaFontSubset, label: __( "metaFontSubset" ) } }
405 />
406
407 <hr class="tb-divider"/>
408 <RangeControl
409 label = { __('Excerpt Fontsize') } value = { postexcerptfontSize }
410 onChange = { (value) => setAttributes({ postexcerptfontSize: value }) }
411 min = { 12 }
412 max = { 30 }
413 beforeIcon="editor-textcolor"
414 allowReset
415 />
416 <TypographyControl
417 label={ __( "Excerpt Fontfamily" ) }
418 attributes = { attributes }
419 setAttributes = { setAttributes }
420 fontFamily = { { value: excerptFontFamily, label: __( "excerptFontFamily" ) } }
421 fontWeight = { { value: excerptFontWeight, label: __( "excerptFontWeight" ) } }
422 fontSubset = { { value: excerptFontSubset, label: __( "excerptFontSubset" ) } }
423 />
424
425 <hr class="tb-divider"/>
426 <RangeControl
427 label = { __('Readmore Fontsize') } value = { postctafontSize }
428 onChange = { (value) => setAttributes({ postctafontSize: value }) }
429 min = { 12 }
430 max = { 50 }
431 beforeIcon="editor-textcolor"
432 allowReset
433 />
434 <TypographyControl
435 label={ __( "Readmore Fontfamily" ) }
436 attributes = { attributes }
437 setAttributes = { setAttributes }
438 fontFamily = { { value: ctaFontFamily, label: __( "ctaFontFamily" ) } }
439 fontWeight = { { value: ctafontWeight, label: __( "ctafontWeight" ) } }
440 fontSubset = { { value: ctaFontSubset, label: __( "ctaFontSubset" ) } }
441 />
442
443 <hr class="tb-divider"/>
444 <RangeControl
445 label = { __('Social Icon Fontsize') } value = { socialSharefontSize }
446 onChange = { (value) => setAttributes({ socialSharefontSize: value }) }
447 min = { 12 }
448 max = { 50 }
449 beforeIcon="editor-textcolor"
450 allowReset
451 />
452 </PanelBody>
453
454 <PanelBody title={ __( 'Space Settings' )} initialOpen={ false } >
455
456 <RangeControl
457 label = { __('Inner Space') } value = { innerSpace }
458 onChange = { (value) => setAttributes({ innerSpace: value }) }
459 min = { 12 }
460 max = { 100 }
461 beforeIcon="editor-textcolor"
462 allowReset
463 />
464 <RangeControl
465 label = { __('Below Image Space') } value = { belowImageSpace }
466 onChange = { (value) => setAttributes({ belowImageSpace: value }) }
467 min = { 12 }
468 max = { 100 }
469 beforeIcon="arrow-down-alt"
470 allowReset
471 />
472 <RangeControl
473 label = { __('Below Title Space') } value = { belowTitleSpace }
474 onChange = { (value) => setAttributes({ belowTitleSpace: value }) }
475 min = { 12 }
476 max = { 100 }
477 beforeIcon="arrow-down-alt"
478 allowReset
479 />
480 <RangeControl
481 label = { __('Below Exerpt Space') } value = { belowexerptSpace }
482 onChange = { (value) => setAttributes({ belowexerptSpace: value }) }
483 min = { 12 }
484 max = { 100 }
485 beforeIcon="arrow-down-alt"
486 allowReset
487 />
488 <RangeControl
489 label = { __('Below Readmore Space') } value = { belowctaSpace }
490 onChange = { (value) => setAttributes({ belowctaSpace: value }) }
491 min = { 12 }
492 max = { 100 }
493 beforeIcon="arrow-down-alt"
494 allowReset
495 />
496 </PanelBody>
497
498 <PanelBody title={ __( 'Color Settings' )} initialOpen={ false }>
499 { layoutcount == '1' &&
500 <Fragment>
501 <p className="tb-color-label">{ __( "Background Color" ) }<span className="components-base-control__label"><span className="component-color-indicator" style={{ backgroundColor: boxbgColor }} ></span></span></p>
502 <ColorPalette
503 value={boxbgColor}
504 onChange={ ( colorValue ) => setAttributes( { boxbgColor: colorValue } )}
505 allowReset
506 />
507 </Fragment>
508 }
509 <p className="tb-color-label">{ __( "Title Color" ) }<span className="components-base-control__label"><span className="component-color-indicator" style={{ backgroundColor: titleColor }} ></span></span></p>
510 <ColorPalette
511 value={titleColor}
512 onChange={ ( colorValue ) => setAttributes( { titleColor: colorValue } )}
513 allowReset
514 />
515
516 <p className="tb-color-label">{ __( "Timeline Background Color" ) }<span className="components-base-control__label"><span className="component-color-indicator" style={{ backgroundColor: timelineBgColor }} ></span></span></p>
517 <ColorPalette
518 value={ timelineBgColor}
519 onChange={ ( colorValue ) => setAttributes( { timelineBgColor: colorValue } )}
520 allowReset
521 />
522
523 { layoutcount == 2 && (
524 <Fragment>
525 <p className="tb-color-label">{ __( "Timeline Icon Foreground Color" ) }<span className="components-base-control__label"><span className="component-color-indicator" style={{ backgroundColor: timelineFgColor }} ></span></span></p>
526 <ColorPalette
527 value={ timelineFgColor}
528 onChange={ ( colorValue ) => setAttributes( { timelineFgColor: colorValue } )}
529 allowReset>
530 </ColorPalette>
531 </Fragment>
532 )}
533
534 <p className="tb-color-label">{ __( "Meta Color" ) }<span className="components-base-control__label"><span className="component-color-indicator" style={{ backgroundColor: postmetaColor }} ></span></span></p>
535 <ColorPalette
536 value={ postmetaColor}
537 onChange={ ( colorValue ) => setAttributes( { postmetaColor: colorValue } )}
538 allowReset
539 />
540
541 <p className="tb-color-label">{ __( "Excerpt Color" ) }<span className="components-base-control__label"><span className="component-color-indicator" style={{ backgroundColor: postexcerptColor }} ></span></span></p>
542 <ColorPalette
543 value={ postexcerptColor}
544 onChange={ ( colorValue ) => setAttributes( { postexcerptColor: colorValue } )}
545 allowReset
546 />
547 { readmoreView == 'text-only' &&
548 <Fragment>
549 <p className="tb-color-label">{ __( "Readmore Color" ) }<span className="components-base-control__label"><span className="component-color-indicator" style={{ backgroundColor: postctaColor }} ></span></span></p>
550 <ColorPalette
551 value={ postctaColor}
552 onChange={ ( colorValue ) => setAttributes( { postctaColor: colorValue } )}
553 allowReset
554 />
555 </Fragment>
556 }
557
558 { readmoreView == 'tb-button' &&
559 <Fragment>
560 <p className="tb-color-label">{ __( "Readmore text Color" ) }<span className="components-base-control__label"><span className="component-color-indicator" style={{ backgroundColor: postctaColor }} ></span></span></p>
561 <ColorPalette
562 value={ postctaColor}
563 onChange={ ( colorValue ) => setAttributes( { postctaColor: colorValue } )}
564 allowReset
565 />
566
567 <p className="tb-color-label">{ __( "Readmore Background Color" ) }<span className="components-base-control__label"><span className="component-color-indicator" style={{ backgroundColor: readmoreBgColor }} ></span></span></p>
568 <ColorPalette
569 value={readmoreBgColor}
570 onChange={( colorValue ) => setAttributes( { readmoreBgColor: colorValue } )}
571 allowReset
572 />
573 </Fragment>
574 }
575 <p className="tb-color-label">{ __( "Social Share Color" ) }<span className="components-base-control__label"><span className="component-color-indicator" style={{ backgroundColor: socialShareColor }} ></span></span></p>
576 <ColorPalette
577 value={ socialShareColor}
578 onChange={ ( colorValue ) => setAttributes( { socialShareColor: colorValue } )}
579 allowReset
580 />
581
582 </PanelBody>
583 </InspectorControls>
584 ) );
585
586 var plelement = document.getElementById( "tb-style-" + this.props.clientId )
587
588 if( null != plelement && "undefined" != typeof plelement ) {
589 plelement.innerHTML = tb_styling( this.props, "tb_post_layouts" )
590 }
591
592 const hasPosts = Array.isArray(latestPosts) && latestPosts.length;
593 if (!hasPosts) {
594 return ( <Fragment> {
595 inspectorControls
596 }
597 <Placeholder icon = "admin-post"
598 label = {
599 __('Timeline Block By Techeshta')
600 } >
601 {!Array.isArray(latestPosts) ?
602 <
603 Spinner / > : __('No posts found.')
604 } </Placeholder>
605 </Fragment>
606 );
607 }
608
609 // Removing posts from display should be instant.
610 const displayPosts = latestPosts.length > postsToShow ? latestPosts.slice(0, postsToShow) : latestPosts;
611
612 return ( <Fragment > {
613 inspectorControls
614 }
615 <BlockControls >
616 <BlockAlignmentToolbar
617 value = { align }
618 onChange = { (value) => { setAttributes({ align: value }); } }
619 controls = {['center', 'wide']} />
620 </BlockControls>
621
622 <div id={ `tb_post_layouts-${ block_id }` } className = { classnames( this.props.className, `tb-timeline-template${ layoutcount }` ) } >
623 { layoutcount == 1 && ( <div className = { `tb-timeline` } >
624 { displayPosts.map((post, i) =>
625
626 <article key={ i } className={ classnames( post.featured_image_src && displayPostImage ? 'has-thumb tb-items' : 'no-thumb tb-items','tb-timeline-item' )} >
627 <div className={ `tb-timeline-content` }>
628 <div class="tb-first-inner-wrap">
629 <div class="tb-blogpost-title ">
630 <Tag className={'tb-title'}>
631 <a href={ post.link } target="_blank" rel="bookmark" className={` tb-timeline-title tb-layout-1` }>{ decodeEntities( post.title.rendered.trim() ) || __( '(Untitled)' ) }</a>
632 </Tag>
633 </div>
634 { displayPostImage && post.featured_image_src !== undefined && post.featured_image_src ? (
635 <div class="tb-image">
636 <a href={ post.link } target="_blank" rel="bookmark">
637 <img
638 src={ isLandscape ? post.featured_image_src : post.featured_image_src_square }
639 alt={ decodeEntities( post.title.rendered.trim() ) || __( '(Untitled)' ) }
640 />
641 </a>
642 </div>
643 ) : ( null) }
644 </div>
645 <div class="tb-timeline-second-content-wrap">
646 <div class="tb-content-wrap">
647 <div class="tb-timeline-byline">
648 { displayPostCategory && post.category_info && post.category_info.length !== 0 &&
649 <div class="tb-category-link-wraper">
650 <div class="tb-timeline-category-link" dangerouslySetInnerHTML={ { __html: post.category_info } } />
651 </div>
652 }
653 <div class="tb-timeline-metadatabox">
654 { displayPostAuthor && post.author_info.display_name &&
655 <div class="post-author"> <i class="fas fa-pencil-alt"></i>&nbsp;
656 <span class="tb-blogpost-author">
657 <a class="tb-timelinetext-link" target="_blank" href="{ post.author_info.author_link } "> { post.author_info.display_name } </a>
658 </span>
659 </div>
660 }
661 { displayPostDate && post.date_gmt &&
662 <div class="mdate "><i class="fas fa-calendar-alt"></i>
663 <span> { moment( post.date_gmt ).local().format( 'MMMM, Y' ) }</span>
664 </div>
665 }
666 { displayPostComments && post.comment_info &&
667 <div class="post-comments"><i class="fas fa-comment"></i>&nbsp;
668 { post.comment_info }
669 </div>
670 }
671 </div>
672 <div class="tb-timeline-text">
673 <div class="tb-blogpost-excerpt">
674 { displayPostExcerpt &&
675 <div dangerouslySetInnerHTML={ { __html: post.wordExcerpt_info.split(/\s+/).slice(0,wordsExcerpt).join(" ") } } />
676 }
677 {
678 displayPostLink && readmoreView == 'text-only' &&
679 <div className={`${readmoreView}`}>
680 <a class = "tb-link " href = { post.link } target = "_blank" rel = "bookmark" > { readMoreText } </a>
681 </div>
682 }
683 {
684 displayPostLink && readmoreView == 'tb-button' &&
685 <div className = "tb-button-view">
686 <a className = {`${readmoreView}`} href = { post.link } target = "_blank" rel = "bookmark" > { readMoreText } </a>
687 </div>
688 }
689 </div>
690 <div class="tb-timeline-bototm-wrap">
691 { displayPostTag && post.tags_info && post.tags_info.length !== 0 &&
692 <div class="tb-timeline-tags-wrap">
693 <div class="tb-timeline-post-tags" dangerouslySetInnerHTML={ { __html: post.tags_info } } />
694 </div>
695 }{ displayPostSocialshare &&
696 <div class="tb-social-wrap">
697 <div class="social-share-data" dangerouslySetInnerHTML={ { __html: post.social_share_info } } />
698 </div>
699 }
700 </div></div></div>
701 <div class="tb-clearfix"></div>
702 </div>
703 </div>
704 </div>
705 </article>
706 )}
707 </div>
708 )}
709 { layoutcount == 2 && ( <div className = { `tb-timeline` } >
710 { displayPosts.map((post, i) =>
711 <article key={ i } className={ classnames( post.featured_image_src && displayPostImage ? 'has-thumb tb-items' : 'no-thumb tb-items','tb-timeline-item' )} >
712 <div class="timeline-icon">
713 <svg class="tb-svg-icon" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
714 width="21px" height="20px" viewBox="0 0 21 20" enable-background="new 0 0 21 20">
715 <path fill="#FFFFFF" d="M19.998,6.766l-5.759-0.544c-0.362-0.032-0.676-0.264-0.822-0.61l-2.064-4.999
716 c-0.329-0.825-1.5-0.825-1.83,0L7.476,5.611c-0.132,0.346-0.462,0.578-0.824,0.61L0.894,6.766C0.035,6.848-0.312,7.921,0.333,8.499
717 l4.338,3.811c0.279,0.246,0.395,0.609,0.314,0.975l-1.304,5.345c-0.199,0.842,0.708,1.534,1.468,1.089l4.801-2.822
718 c0.313-0.181,0.695-0.181,1.006,0l4.803,2.822c0.759,0.445,1.666-0.23,1.468-1.089l-1.288-5.345
719 c-0.081-0.365,0.035-0.729,0.313-0.975l4.34-3.811C21.219,7.921,20.855,6.848,19.998,6.766z"/>
720 </svg>
721 </div>
722 <div className={ `tb-timeline-content` }>
723 <div>
724 { displayPostImage && post.featured_image_src !== undefined && post.featured_image_src ? (
725 <div class="tb-image">
726 <a href={ post.link } target="_blank" rel="bookmark">
727 <img src={ isLandscape ? post.featured_image_src : post.featured_image_src_square }
728 alt={ decodeEntities( post.title.rendered.trim() ) || __( '(Untitled)' ) } />
729 </a>
730 </div>
731 ) : ( null) }
732 </div>
733 <div class="tb-first-inner-wrap">
734 <div class="tb-content-wrap">
735 <div class="tb-blogpost-title">
736 <Tag className="tb-title">
737 <a href={ post.link } target="_blank" rel="bookmark" className={` tb-timeline-title` }>{ decodeEntities( post.title.rendered.trim() ) || __( '(Untitled)' ) }</a>
738 </Tag>
739 </div>
740 { displayPostDate && post.date_gmt &&
741 <div class="mdate tb-inline "><i class="fas fa-calendar-alt"></i>
742 <span> { moment( post.date_gmt ).local().format( 'MMMM, Y' ) }</span>
743 </div>
744 }
745 { displayPostAuthor && post.author_info.display_name &&
746 <div class="post-author tb-inline"> <i class="fas fa-pencil-alt"></i>&nbsp;
747 <span class="tb-blogpost-author">
748 <a class="tb-timelinetext-link" target="_blank" href="{ post.author_info.author_link } "> { post.author_info.display_name } </a>
749 </span>
750 </div>
751 }
752 { displayPostComments && post.comment_info &&
753 <div class="post-comments tb-inline"> <i class="fas fa-comment"></i>&nbsp;
754 { post.comment_info }
755 </div>
756 }
757 { displayPostCategory && post.category_info && post.category_info.length !== 0 &&
758 <div class="tb-category-link-wraper tb-inline">
759 <div class="tb-timeline-category-link" dangerouslySetInnerHTML={ { __html: post.category_info } } />
760 </div>
761 }
762 <div class="tb-timeline-second-content-wrap">
763 <div class="tb-timeline-byline">
764 <div class="tb-timeline-metadatabox">
765 <div class="tb-timeline-excerpt">
766 { displayPostExcerpt &&
767 <div class="tb-blogpost-excerpt" dangerouslySetInnerHTML={ { __html: post.wordExcerpt_info.split(/\s+/).slice(0,wordsExcerpt).join(" ") } } />
768 }
769 { displayPostLink && readmoreView == 'text-only' &&
770 <div className={`${readmoreView}`}>
771 <a class = "tb-link" href = { post.link } target = "_blank" rel = "bookmark" > { readMoreText } </a>
772 </div>
773 }
774 {
775 displayPostLink && readmoreView == 'tb-button' &&
776 <div className = "tb-button-view">
777 <a className = {`${readmoreView}`} href = { post.link } target = "_blank" rel = "bookmark" > { readMoreText } </a>
778 </div>
779 }
780 </div>
781 <div class="tb-timeline-bototm-wrap">
782 { displayPostTag && post.tags_info && post.tags_info.length !== 0 &&
783 <div class="tb-timeline-tags-wrap">
784 <div class="tb-timeline-post-tags" dangerouslySetInnerHTML={ { __html: post.tags_info } } />
785 </div>
786 }{ displayPostSocialshare &&
787 <div class="tb-social-wrap">
788 <div class="social-share-data" dangerouslySetInnerHTML={ { __html: post.social_share_info } } />
789 </div>
790 }
791 </div></div></div>
792 <div class="tb-clearfix"></div>
793 </div>
794 </div>
795 </div>
796 </div>
797 </article>
798 )}
799 </div>
800 )}
801 </div>
802 </Fragment>
803 );
804 }
805 }
806
807 export default withSelect((select, props) => {
808 const {
809 postsToShow,
810 order,
811 orderBy,
812 categories
813 } = props.attributes;
814 const {
815 getEntityRecords
816 } = select('core');
817 const latestPostsQuery = pickBy({
818 categories,
819 order,
820 orderby: orderBy,
821 per_page: postsToShow,
822 }, (value) => !isUndefined(value));
823 const categoriesListQuery = {
824 per_page: 100,
825 };
826 return {
827 latestPosts: getEntityRecords('postType', 'post', latestPostsQuery),
828 categoriesList: getEntityRecords('taxonomy', 'category', categoriesListQuery),
829 };
830 })(LatestPostsBlock);
831