-
Notifications
You must be signed in to change notification settings - Fork 6
[Gutenberg] Add "Featured Destinations" homepage block #34
Changes from all commits
9f745ae
29b6ca5
51845c0
1085dc7
ec20263
d12ad1b
bafa358
d00e00b
b4fc6fc
72ad5a4
c984df8
be159ec
fe7bb55
d5a5646
c133eed
b8a9d41
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/* global wp */ | ||
|
||
/** | ||
* JS functions for terms in admin UI. | ||
*/ | ||
|
||
( function( $ ) { | ||
'use strict'; | ||
|
||
let component = {}; | ||
|
||
/** | ||
* Init. | ||
*/ | ||
component.init = function init() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like the selected image is persisting even after saving a new "Location"
But the workflow looks fine when editing a location: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for fixing this. |
||
_.extend( component, { | ||
fileFrame: [], | ||
uploadButton: $( '#location-cover-image' ), | ||
removeButton: $( '#location-cover-image-remove' ), | ||
imgContainer: $( '#location-cover-image-preview' ), | ||
imgIdInput: $( '#location-cover-image-value' ), | ||
saveNewTermButton: $( '#addtag #submit' ) | ||
} ); | ||
|
||
component.setupLocationMediaUploader(); | ||
component.setupAddTerm(); | ||
}; | ||
|
||
/** | ||
* Add media uploader for location cover image. | ||
*/ | ||
component.setupLocationMediaUploader = function() { | ||
component.uploadButton.on( 'click', function ( event ) { | ||
|
||
event.preventDefault(); | ||
|
||
let self = $( this ), | ||
id = self.attr( 'id' ); | ||
|
||
// If the media frame already exists, reopen it. | ||
if ( component.fileFrame[ id ] ) { | ||
component.fileFrame[ id ].open(); | ||
|
||
return; | ||
} | ||
|
||
// Create the media frame. | ||
component.fileFrame[ id ] = wp.media.frames.fileFrame = wp.media( { | ||
title: wp.i18n.__( 'Select Location Cover Image' ), | ||
button: { | ||
text: wp.i18n.__( 'Select Image' ) | ||
}, | ||
multiple: false | ||
} ); | ||
|
||
// When an image is selected, run a callback. | ||
component.fileFrame[ id ].on( 'select', function() { | ||
let attachment = component.fileFrame[ id ].state().get( 'selection' ).first().toJSON(); | ||
|
||
// Set input value. | ||
component.imgIdInput.val( attachment.id ); | ||
component.imgContainer.html( '<img src="' + attachment.url + '" style="max-width: 100%;" />' ); | ||
component.removeButton.removeClass( 'hidden' ); | ||
|
||
} ); | ||
|
||
// Finally, open the modal | ||
component.fileFrame[ id ].open(); | ||
|
||
} ); | ||
|
||
component.removeButton.on( 'click', function( event ) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you have time, could you display this It could be confusing to have a "Remove" button if there's no image to remove. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for making this change, @miina. This works well. |
||
event.preventDefault(); | ||
component.imgIdInput.val( '' ); | ||
component.imgContainer.html( '' ); | ||
component.removeButton.addClass( 'hidden' ); | ||
|
||
} ); | ||
}; | ||
|
||
/** | ||
* Set up events when adding new term. | ||
*/ | ||
component.setupAddTerm = function() { | ||
component.saveNewTermButton.on( 'click', function() { | ||
|
||
if ( ! validateForm( $( this ).parents( 'form' ) ) ) { | ||
return; | ||
} | ||
|
||
// Wait for ajax save stopping. | ||
$( document ).ajaxStop( function() { | ||
if ( 0 === $( '#ajax-response .error' ).length ) { | ||
component.imgIdInput.val( '' ); | ||
component.imgContainer.html( '' ); | ||
component.removeButton.addClass( 'hidden' ); | ||
$( '.location-is-featured-wrap input[type="checkbox"]' ).prop( 'checked', false ); | ||
} | ||
} ); | ||
} ); | ||
}; | ||
|
||
$( document ).ready( function() { | ||
component.init(); | ||
} ); | ||
|
||
})( jQuery ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,85 +6,15 @@ | |
*/ | ||
const { __ } = wp.i18n; | ||
const { registerBlockType } = wp.blocks; | ||
|
||
import { deamplify } from '../amp-transformer'; | ||
|
||
/** | ||
* Render the featured block. | ||
* | ||
* @return {wp.element.Component} Rendered component. | ||
*/ | ||
const renderStaticFeaturedBlock = () => { | ||
return ( | ||
<section className='travel-featured pt3 relative clearfix'> | ||
<header className='max-width-2 mx-auto px1 md-px2 relative'> | ||
<h3 className='travel-featured-heading h1 bold line-height-2 mb2 center'>Featured Destinations</h3> | ||
</header> | ||
<div className='max-width-3 mx-auto relative'> | ||
<div className='travel-featured-grid flex flex-wrap items-stretch'> | ||
<div className='col-12 md-col-6 flex items-stretch flex-auto'> | ||
<a href='travel-results.amp' className='travel-featured-tile flex flex-auto relative travel-featured-color-blue' on="tap:AMP.setState({fields_query: 'New York', query_query: 'New York'})"> | ||
<amp-img class='travel-object-cover flex-auto' layout='responsive' width='336' height='507' src={travelGlobals.themeUrl + '/img/new-york.jpg'}></amp-img> | ||
<div className='travel-featured-overlay absolute z1 center top-0 right-0 bottom-0 left-0 white p2'> | ||
<div className='travel-featured-tile-heading caps bold line-height-2 h3'>New York</div> | ||
<div className='h5'>379 adventures</div> | ||
</div> | ||
</a> | ||
<div className='flex flex-column items-stretch flex-auto'> | ||
<a href='travel-results.amp' className='travel-featured-tile flex flex-auto relative travel-featured-color-cyan' on="tap:AMP.setState({fields_query: 'Barcelona', query_query: 'Barcelona'})"> | ||
<amp-img class='travel-object-cover flex-auto' layout='responsive' width='264' height='246' src={travelGlobals.themeUrl + '/img/barcelona.jpg'}></amp-img> | ||
<div className='travel-featured-overlay absolute z1 center top-0 right-0 bottom-0 left-0 white p2'> | ||
<div className='travel-featured-tile-heading bold caps line-height-2 h3'>Barcelona</div> | ||
<div className='h5'>68 adventures</div> | ||
</div> | ||
</a> | ||
<a href='travel-results.amp' className='travel-featured-tile flex flex-auto pointer relative travel-featured-color-orange' on="tap:AMP.setState({fields_query: 'Paris', query_query: 'Paris'})"> | ||
<amp-img class='travel-object-cover flex-auto' layout='responsive' width='264' height='264' src={travelGlobals.themeUrl + '/img/paris.jpg'}></amp-img> | ||
<div className='travel-featured-overlay absolute z1 center top-0 right-0 bottom-0 left-0 white p2'> | ||
<div className='travel-featured-tile-heading bold caps line-height-2 h3'>Paris</div> | ||
<div className='h5'>221 adventures</div> | ||
</div> | ||
</a> | ||
</div> | ||
</div> | ||
<div className='col-12 md-col-6 flex items-stretch flex-auto'> | ||
<div className='flex flex-column items-stretch flex-auto'> | ||
<a href='travel-results.amp' className='travel-featured-tile flex flex-auto pointer relative travel-featured-color-purple' on="tap:AMP.setState({fields_query: 'Tokyo', query_query: 'Tokyo'})"> | ||
<amp-img class='travel-object-cover flex-auto' layout='responsive' width='276' height='207' src={travelGlobals.themeUrl + '/img/tokyo.jpg'}></amp-img> | ||
<div className='travel-featured-overlay absolute z1 center top-0 right-0 bottom-0 left-0 white p2'> | ||
<div className='travel-featured-tile-heading caps bold line-height-2 h3'>Tokyo</div> | ||
<div className='h5'>500+ adventures</div> | ||
</div> | ||
</a> | ||
<a href='travel-results.amp' className='travel-featured-tile flex flex-auto relative travel-featured-color-cornflower' on="tap:AMP.setState({fields_query: 'Chicago', query_query: 'Chicago'})"> | ||
<amp-img class='travel-object-cover flex-auto' layout='responsive' width='264' height='286' src={travelGlobals.themeUrl + '/img/chicago.jpg'}></amp-img> | ||
<div className='travel-featured-overlay absolute z1 center top-0 right-0 bottom-0 left-0 white p2'> | ||
<div className='travel-featured-tile-heading caps bold line-height-2 h3'>Chicago</div> | ||
<div className='h5'>143 adventures</div> | ||
</div> | ||
</a> | ||
</div> | ||
<a href='travel-results.amp' className='travel-featured-tile flex flex-auto relative travel-featured-color-teal' on="tap:AMP.setState({fields_query: 'Reykjavik', query_query: 'Reykjavik'})"> | ||
<amp-img class='travel-object-cover flex-auto' layout='responsive' width='312' height='507' src={travelGlobals.themeUrl + '/img/reykjavik.jpg'}></amp-img> | ||
<div className='travel-featured-overlay absolute z1 center top-0 right-0 bottom-0 left-0 white p2'> | ||
<div className='travel-featured-tile-heading caps bold h3'>Reykjavik</div> | ||
<div className='h5'>87 adventures</div> | ||
</div> | ||
</a> | ||
</div> | ||
</div> | ||
</div> | ||
</section> | ||
); | ||
}; | ||
const { Placeholder, withAPIData } = wp.components; | ||
|
||
/** | ||
* Register block. | ||
*/ | ||
export default registerBlockType( | ||
'amp-travel/featured', | ||
{ | ||
title: __( 'Featured' ), | ||
title: __( 'Featured Destinations' ), | ||
category: 'common', | ||
icon: 'wordpress-alt', | ||
keywords: [ | ||
|
@@ -93,11 +23,125 @@ export default registerBlockType( | |
__( 'Travel' ) | ||
], | ||
|
||
edit() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is outside of this PR's diff. But could the title of this block be 'Featured Destinations,' instead of 'Featured'? Or something that's descriptive. title: __( 'Featured Destinations' ),
category: 'common',
icon: 'wordpress-alt', There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for making this change. |
||
return deamplify( renderStaticFeaturedBlock() ); | ||
attributes: { | ||
heading: { | ||
selector: '.travel-featured-heading', | ||
source: 'children', | ||
type: 'array' | ||
} | ||
}, | ||
|
||
edit: withAPIData( () => { | ||
return { | ||
featuredLocations: '/wp/v2/locations?per_page=6&meta_value=1&meta_key=amp_travel_featured' | ||
}; | ||
} )( ( { featuredLocations } ) => { // eslint-disable-line | ||
const hasLocations = Array.isArray( featuredLocations.data ) && 6 <= featuredLocations.data.length; | ||
if ( ! hasLocations ) { | ||
return ( | ||
<Placeholder key="placeholder" | ||
icon="admin-post" | ||
label={ __( 'Locations' ) } | ||
> | ||
{ __( 'Not enough featured locations found. Please add at least six "Locations" terms, select an image, and check "Featured destination."' ) } | ||
</Placeholder> | ||
); | ||
} | ||
|
||
const locations = featuredLocations.data; | ||
const imgStyles = [ | ||
{ | ||
width: 336, | ||
height: 507 | ||
}, | ||
{ | ||
width: 264, | ||
height: 246 | ||
}, | ||
{ | ||
width: 264, | ||
height: 264 | ||
}, | ||
{ | ||
width: 276, | ||
height: 207 | ||
}, | ||
{ | ||
width: 264, | ||
height: 286 | ||
}, | ||
{ | ||
width: 312, | ||
height: 507 | ||
} | ||
]; | ||
|
||
return ( | ||
<section className='travel-featured pt3 relative clearfix'> | ||
<header className='max-width-2 mx-auto px1 md-px2 relative'> | ||
<h3 className='travel-featured-heading h1 bold line-height-2 mb2 center'>{ __( 'Featured Destinations' ) }</h3> | ||
</header> | ||
<div className='max-width-3 mx-auto relative'> | ||
<div className='travel-featured-grid flex flex-wrap items-stretch'> | ||
<div className='col-12 md-col-6 flex items-stretch flex-auto'> | ||
<a href={ locations[0].link } className='travel-featured-tile flex flex-auto relative travel-featured-color-blue'> | ||
<img className='travel-object-cover flex-auto' layout='responsive' style={ imgStyles[0] } width='336' height='507' src={ locations[0].meta.amp_travel_location_img }></img> | ||
<div className='travel-featured-overlay absolute z1 center top-0 right-0 bottom-0 left-0 white p2'> | ||
<div className='travel-featured-tile-heading caps bold line-height-2 h3'>{ locations[0].name }</div> | ||
<div className='h5'>{ locations[0].count + __( ' adventures' ) }</div> | ||
</div> | ||
</a> | ||
<div className='flex flex-column items-stretch flex-auto'> | ||
<a href={ locations[1].link } className='travel-featured-tile flex flex-auto relative travel-featured-color-cyan'> | ||
<img className='travel-object-cover flex-auto' layout='responsive' style={ imgStyles[1] } width='264' height='246' src={ locations[1].meta.amp_travel_location_img }></img> | ||
<div className='travel-featured-overlay absolute z1 center top-0 right-0 bottom-0 left-0 white p2'> | ||
<div className='travel-featured-tile-heading bold caps line-height-2 h3'>{ locations[1].name }</div> | ||
<div className='h5'>{ locations[1].count + __( ' adventures' ) }</div> | ||
</div> | ||
</a> | ||
<a href={ locations[2].link } className='travel-featured-tile flex flex-auto pointer relative travel-featured-color-orange'> | ||
<img className='travel-object-cover flex-auto' layout='responsive' style={ imgStyles[2] } width='264' height='264' src={ locations[2].meta.amp_travel_location_img }></img> | ||
<div className='travel-featured-overlay absolute z1 center top-0 right-0 bottom-0 left-0 white p2'> | ||
<div className='travel-featured-tile-heading bold caps line-height-2 h3'>{ locations[2].name }</div> | ||
<div className='h5'>{ locations[2].count + __( ' adventures' ) }</div> | ||
</div> | ||
</a> | ||
</div> | ||
</div> | ||
<div className='col-12 md-col-6 flex items-stretch flex-auto'> | ||
<div className='flex flex-column items-stretch flex-auto'> | ||
<a href={ locations[3].link } className='travel-featured-tile flex flex-auto pointer relative travel-featured-color-purple'> | ||
<img className='travel-object-cover flex-auto' layout='responsive' style={ imgStyles[3] } width='276' height='207' src={ locations[3].meta.amp_travel_location_img }></img> | ||
<div className='travel-featured-overlay absolute z1 center top-0 right-0 bottom-0 left-0 white p2'> | ||
<div className='travel-featured-tile-heading caps bold line-height-2 h3'>{ locations[3].name }</div> | ||
<div className='h5'>{ locations[3].count + __( ' adventures' ) }</div> | ||
</div> | ||
</a> | ||
<a href={ locations[4].link } className='travel-featured-tile flex flex-auto relative travel-featured-color-cornflower'> | ||
<img className='travel-object-cover flex-auto' layout='responsive' style={ imgStyles[4] } width='264' height='286' src={ locations[4].meta.amp_travel_location_img }></img> | ||
<div className='travel-featured-overlay absolute z1 center top-0 right-0 bottom-0 left-0 white p2'> | ||
<div className='travel-featured-tile-heading caps bold line-height-2 h3'>{ locations[4].name }</div> | ||
<div className='h5'>{ locations[4].count + __( ' adventures' ) }</div> | ||
</div> | ||
</a> | ||
</div> | ||
<a href={ locations[5].link } className='travel-featured-tile flex flex-auto relative travel-featured-color-teal'> | ||
<img className='travel-object-cover flex-auto' layout='responsive' style={ imgStyles[5] } width='312' height='507' src={ locations[5].meta.amp_travel_location_img }></img> | ||
<div className='travel-featured-overlay absolute z1 center top-0 right-0 bottom-0 left-0 white p2'> | ||
<div className='travel-featured-tile-heading caps bold h3'>{ locations[5].name }</div> | ||
<div className='h5'>{ locations[5].count + __( ' adventures' ) }</div> | ||
</div> | ||
</a> | ||
</div> | ||
</div> | ||
</div> | ||
</section> | ||
); | ||
} ), // eslint-disable-line | ||
save() { | ||
return renderStaticFeaturedBlock(); | ||
|
||
// Render in PHP. | ||
return null; | ||
} | ||
} | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice structure of the file.