Adding Mobile Image Field in Photo Module

Original Message

Could you make a tutorial on adding a mobile image for the Beaver Builder photo module? So you can set a different image on mobile. You did a similar tutorial for a row background image, but this would be useful for the photo module.

Mobile Image Field in Photo Module

Mobile Image Field in Photo Module

Creating Fields into Settings From

Creating two new photo upload fields into Photo module’s settings form. Beaver builder have a filter “fl_builder_register_settings_form”. So you can easily customize the any module’s settings form without updating the core files of Beaver Builder plugin.

Open the functions.php file of your active theme and add this PHP snippets there.

Adding Photo Upload Field for Medium & Small Device

add_filter( 'fl_builder_register_settings_form', 'probb_photo_module_settings_form', 1005, 2 );
function probb_photo_module_settings_form( $form, $slug )
{
	//* Checking we are editing the photo module
	if( $slug == 'photo' )
	{
		//* Excluding the default Photo field
		$arr = array_slice( $form['general']['sections']['general']['fields'], 0, 2, true );

		//* Creating 2nd photo field for medium device
		$photo_2 = array(
			'photo_2' 	=> array(
				'type' 			=> 'photo',
				'label' 		=> __( 'Photo for medium devices', 'fl-builder' ),
				'show_remove' 	=> true,
				'preview'         => array(
					'type'            => 'none',
				),
				'connections'	=> array( 'photo' )
			)
		);

		//* Creating 3rd photo field for small device
		$photo_3 = array(
			'photo_3' 	=> array(
				'type' 			=> 'photo',
				'label' 		=> __( 'Photo for small devices', 'fl-builder' ),
				'show_remove' 	=> true,
				'preview'         => array(
					'type'            => 'none',
				),
				'connections'	=> array( 'photo' )
			)
		);

		//* Appending the photo fields with existing photo module's settings form
		$form['general']['sections']['general']['fields'] = array_merge( $arr, $photo_2, $photo_3, $form['general']['sections']['general']['fields'] );
	}

	//* Returning the form
	return $form;
}

Adding Two New Images Markup into Photo Module HTML Markup

If you are using the latest version of Beaver Builder plugin, you can add/edit the content of frontend.php file. There have a filter “fl_builder_render_module_content”. With this filter you can alter the exiting module’s HTML content with your’s one. This filter is accepting two parameters: $out (content of frontend.php) and $module (it is a object. With it you can target the specific module and edit the content).

Again open the functions.php file of your active theme and add the following PHP snippets.

Editing the content of frontend.php file of Photo module.

//* Adding the two new images into photo modules HTML markup
add_filter('fl_builder_render_module_content', function ( $out, $module ) {
	if( 'photo' === $module->slug && 'library' == $module->settings->photo_source )
	{
		$img = '';
		
		//* Checking there have a photo for medium device 
		if( ! empty( $module->settings->photo_2_src ) )
		{
			//* getting the image for medium device
			$img .= probb_generate_responsive_photo_markup( $module, 'photo_2' );
		}

		//* Checking there have a photo for small device
		if(  ! empty( $module->settings->photo_3_src ) )
		{
			//* getting the image for small device
			$img .= probb_generate_responsive_photo_markup( $module, 'photo_3' );
		}

		//* Appending the these two images with existing photo module's html
		$out = str_replace( 'settings->$key ) ) {
		$src = $key . '_src';
		$photo = FLBuilderPhoto::get_attachment_data( $module->settings->$key );

		if ( is_object( $photo ) && isset( $photo->sizes ) ) {
			$alt = '';

			if ( ! empty( $photo->alt ) ) {
				$alt = htmlspecialchars( $photo->alt );
			} elseif ( ! empty( $photo->description ) ) {
				$alt = htmlspecialchars( $photo->description );
			} elseif ( ! empty( $photo->caption ) ) {
				$alt = htmlspecialchars( $photo->caption );
			} elseif ( ! empty( $photo->title ) ) {
				$alt = htmlspecialchars( $photo->title );
			}

			$classes = $module->get_classes();
			
			if( $key === 'photo_2' )
				$classes .= ' photo-medium-device';

			if( $key === 'photo_3' )
				$classes .= ' photo-small-device';

			$img = sprintf ( '%ssettings->$src, $alt );

			foreach ( $photo->sizes as $size ) {
				if ( $size->url == $module->settings->$src ) {
					$img .= 'height="' . $size->height . '" width="' . $size->width . '" ';
				}
			}

			$img .= ' />' . "n";
		}
	}

	return $img;
}

Displaying The Images at Front-end via Media Queries

Beaver Builder have another filter fl_builder_render_css. You can add your custom CSS via this filter. Here I am creating media query CSS. So mobile images will show based on the device width. You will add the following PHP snippets into your theme’s functions.php file.

Show/Hide the images via media queries

//* Show/Hide the images via media queries
add_filter( 'fl_builder_render_css', 'probb_filter_render_photo_css',1001, 3 );
function probb_filter_render_photo_css( $css, $nodes, $global_settings )
{
	foreach( $nodes['modules'] as $module )
	{
		if( 'photo' === $module->slug && 'library' == $module->settings->photo_source )
		{
			if( ! empty( $module->settings->photo_2_src ) || ! empty( $module->settings->photo_3_src ) )
			{
				$css .= '.fl-node-' . $module->node . ' .photo-medium-device { display: block; }';
			}

			if( ! empty( $module->settings->photo_2_src ) )
			{
				$css .= '.fl-node-' . $module->node . ' .photo-medium-device { display: none; }
					@media (min-width: '. ( absint( $global_settings->responsive_breakpoint ) + 1 ) . 'px) and (max-width: ' . $global_settings->medium_breakpoint . 'px)
					{
						.fl-node-' . $module->node . ' .photo-desktop {
							display: none;
						}

						.fl-node-' . $module->node . ' .photo-medium-device {
							display: block;
						}
					}';
			}

			if( ! empty( $module->settings->photo_3_src ) )
			{
				$css .= '
					.fl-node-' . $module->node . ' .photo-small-device { display: none; }
					@media (max-width: ' . $global_settings->responsive_breakpoint . 'px)
					{
						.fl-node-' . $module->node . ' .photo-desktop,
						.fl-node-' . $module->node . ' .photo-medium-device {
							display: none;
						}

						.fl-node-' . $module->node . ' .photo-small-device {
							display: block;
						}
					}';
			}
		}
	}

	return $css;
}
Posted in