Skip to content

Commit

Permalink
Move Layout Builder to Core (#2223)
Browse files Browse the repository at this point in the history
This PR addresses #1921 

It adds a new Layout, called Layout Builder, that has dynamic rows for
the fields.

💾 [Build
file](https://www.dropbox.com/scl/fi/zh4uqp6yidb1zkqqs98bh/gravityview-2.32-33bacbeef.zip?rlkey=w47ub1vhuj0pwetbjwmpb99w3&dl=1)
(33bacbe).
  • Loading branch information
mrcasual authored Dec 12, 2024
2 parents 26370fd + a42ad3b commit 3f0f199
Show file tree
Hide file tree
Showing 23 changed files with 611 additions and 6 deletions.
2 changes: 1 addition & 1 deletion assets/css/admin-entries-list.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion assets/css/admin-global.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion assets/css/admin-views.css

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions assets/js/admin-views.js
Original file line number Diff line number Diff line change
Expand Up @@ -2558,10 +2558,10 @@
revert: 75,
connectWith: ".active-drop-field",
start: function( event, ui ) {
$( panel ).find( ".active-drop-container-field" ).addClass('is-receivable');
$( document.body ).find( ".active-drop-container-field" ).addClass('is-receivable');
},
stop: function( event, ui ) {
$( panel ).find( ".active-drop-container-field" ).removeClass('is-receivable');
$( document.body ).find( ".active-drop-container-field" ).removeClass('is-receivable');
},
change: function( event, ui ) {
vcfg.setUnsavedChanges( true );
Expand Down
2 changes: 1 addition & 1 deletion assets/js/admin-views.min.js

Large diffs are not rendered by default.

26 changes: 26 additions & 0 deletions future/includes/class-gv-template-entry-layout-builder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php
namespace GV;

/** If this file is called directly, abort. */
if ( ! defined( 'GRAVITYVIEW_DIR' ) ) {
die();
}

require_once 'trait-gv-field-renderer.php';

/**
* The single Entry template.
*
* @since $ver$
*/
final class Entry_Layout_Builder_Template extends Entry_Template {
use Field_Renderer_Trait;
/**
* {@inheritDoc}
*
* @since $ver$
*
* @var string
*/
public static $slug = \GravityView_Layout_Builder::ID;
}
1 change: 1 addition & 0 deletions future/includes/class-gv-template-entry.php
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,4 @@ public function get_back_label( $do_replace = true ) {
require gravityview()->plugin->dir( 'future/includes/class-gv-template-entry-table.php' );
require gravityview()->plugin->dir( 'future/includes/class-gv-template-entry-list.php' );
require gravityview()->plugin->dir( 'future/includes/class-gv-template-entry-legacy.php' );
require gravityview()->plugin->dir( 'future/includes/class-gv-template-entry-layout-builder.php' );
27 changes: 27 additions & 0 deletions future/includes/class-gv-template-view-layout-builder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php
namespace GV;

/** If this file is called directly, abort. */
if ( ! defined( 'GRAVITYVIEW_DIR' ) ) {
die();
}

require_once 'trait-gv-field-renderer.php';

/**
* The View template.
*
* @since $ver$
*/
final class View_Layout_Builder_Template extends View_Template {
use Field_Renderer_Trait;

/**
* {@inheritDoc}
*
* @since $ver$
*
* @var string
*/
public static $slug = \GravityView_Layout_Builder::ID;
}
1 change: 1 addition & 0 deletions future/includes/class-gv-template-view.php
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,4 @@ public function render() {
require gravityview()->plugin->dir( 'future/includes/class-gv-template-view-table.php' );
require gravityview()->plugin->dir( 'future/includes/class-gv-template-view-list.php' );
require gravityview()->plugin->dir( 'future/includes/class-gv-template-view-legacy.php' );
require gravityview()->plugin->dir( 'future/includes/class-gv-template-view-layout-builder.php' );
66 changes: 66 additions & 0 deletions future/includes/trait-gv-field-renderer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php
namespace GV;

/**
* Trait responsible for rendering a single field for an entry.
*
* @since $ver$
*/
trait Field_Renderer_Trait {
/**
* Output the field in the diy view.
*
* @param Field $field The field to output.
* @param Entry $entry The entry.
* @param array $extras Extra stuff, like wpautop, etc.
*
* @return string The field HTML.
*/
public function the_field( Field $field, Entry $entry, array $extras = [] ): string {
$form = $this->view->form;

$context = Template_Context::from_template( $this, compact( 'field', 'entry' ) );

$renderer = new Field_Renderer();
$source = is_numeric( $field->ID ) ? $this->view->form : new Internal_Source();

$value = $renderer->render( $field, $this->view, $source, $entry, $this->request );
$label = apply_filters(
'gravityview/template/field_label',
$field->get_label( $this->view, $form ),
$field->as_configuration(),
$form->form ?: null,
null,
);

/**
* @filter `gravityview/template/field/label` Override the field label.
* @since 2.0
*
* @param [in,out] string $label The label to override.
* @param \GV\Template_Context $context The context.
*/
$label = apply_filters( 'gravityview/template/field/label', $label, $context );

/**
* @filter `gravityview/template/table/entry/hide_empty`
*
* @param boolean $hide_empty Should the row be hidden if the value is empty? Default: don't hide.
* @param \GV\Template_Context $context The context ;) Love it, cherish it. And don't you dare modify it!
*/
$hide_empty = apply_filters(
'gravityview/render/hide-empty-zone',
Utils::get( $extras, 'hide_empty', $this->view->settings->get( 'hide_empty', false ) ),
$context,
);

$markup = '<div id="{{ field_id }}" class="{{ class }}">
{{ label }}
<div class="gv-grid-value">{{ value }}</div>
</div>';

$extras = array_merge( $extras, compact( 'hide_empty', 'value', 'label', 'markup' ) );

return \gravityview_field_output( $extras, $context );
}
}
Empty file.
161 changes: 161 additions & 0 deletions includes/presets/layout-builder/class-gravityview-layout-builder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
<?php

use GV\Entry_Layout_Builder_Template;
use GV\Field_Collection;
use GV\Grid;
use GV\View_Layout_Builder_Template;

/**
* Registers the Layout Builder Layout.
*
* @since $ver$
*/
final class GravityView_Layout_Builder extends GravityView_Template {
/**
* The Layout ID.
*
* @since $ver$
*
* @var string
*/
public const ID = 'gravityview-layout-builder';

/**
* Creates the layout.
*
* @since $ver$
*/
public function __construct() {
$areas = Grid::prefixed(
self::ID,
static fn() => [ Grid::get_row_by_type( '100' ) ],
);

parent::__construct(
self::ID,
[
'slug' => self::ID,
'type' => 'custom',
'label' => __( 'Layout Builder', 'gk-gravityview' ),
'description' => __(
'Display items in customizable rows and columns.',
'gk-gravityview',
),
'css_source' => null,
'logo' => plugins_url( 'includes/presets/layout-builder/logo-layout-builder.svg', GRAVITYVIEW_FILE ),
],
[
'show_as_link' => [
'type' => 'checkbox',
'label' => esc_html__( 'Link to single entry', 'gk-gravityview' ),
'value' => false,
'context' => 'directory',
'priority' => 1190,
'group' => 'display',
],
],
$areas,
);

add_filter( 'gravityview/template/view/class', [ __CLASS__, 'get_view_class' ] );
add_filter( 'gravityview/template/entry/class', [ __CLASS__, 'get_view_class' ] );

add_filter( 'gk/gravityview/admin-views/view/is-dynamic', [ __CLASS__, 'make_dynamic' ], 5, 3 );
add_filter( 'gk/gravityview/admin-views/view/template/active-areas', [ __CLASS__, 'replace_active_areas' ], 5, 4 );

add_action( 'wp_enqueue_scripts', [ __CLASS__, 'register_style_assets' ] );
}

/**
* Returns {@see ViewTemplate} class name to be used as the View template class.
*
* @used-by `gravityview/template/view/class` filter.
*
* @since TBD
*
* @param string $template_class View template class.
*
* @return string The template class to use.
*/
public static function get_view_class( string $template_class ): string {
// GravityView expects the class to be in the "GV\View_<name>_Template" format.
$is_layout_builder_template = false !== stripos( $template_class, '_' . self::ID . '_' );
if ( ! $is_layout_builder_template ) {
return $template_class;
}

return stripos( $template_class, 'view_' ) !== false
? View_Layout_Builder_Template::class
: Entry_Layout_Builder_Template::class;
}

/**
* Returns the dynamic areas, stored in the fields array.
*
* @since $ver$
*
* @param array $areas The current areas.
* @param string $template_id The template ID.
* @param string $context The context / zone.
* @param array $fields The fields to render.
*
* @return array The rows with the active dynamic areas.
*/
public static function replace_active_areas(
array $areas,
string $template_id,
string $context,
array $fields
): array {
if ( self::ID !== $template_id ) {
return $areas;
}

$collection = Field_Collection::from_configuration( $fields );
$rows = Grid::prefixed(
self::ID,
static fn() => Grid::get_rows_from_collection( $collection, $context ),
);

return $rows ?: $areas;
}

/**
* Makes the field sections for the Layout Builder template sortable.
*
* @since $ver$
*
* @param bool $is_dynamic Whether it is dynamic.
* @param string $template_id The template ID.
* @param string $type The object type.
*
* @return bool Whether it is sortable
*/
public static function make_dynamic( bool $is_dynamic, string $template_id, string $type ): bool {
if (
self::ID !== $template_id
|| 'field' !== $type
) {
return $is_dynamic;
}

return true;
}

/**
* Registers the style assets for the View layout.
*
* @since $ver$
*/
public static function register_style_assets(): void {
$style = 'gravityview_style_' . self::ID;
wp_register_style(
$style,
plugin_dir_url( GRAVITYVIEW_FILE ) . 'templates/css/layout-builder.css',
[],
GV_PLUGIN_VERSION
);
}
}

new GravityView_Layout_Builder();
1 change: 1 addition & 0 deletions includes/presets/layout-builder/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<?php // Silence is golden
1 change: 1 addition & 0 deletions includes/presets/layout-builder/logo-layout-builder.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions includes/presets/register-default-templates.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ function gravityview_register_default_templates() {
include_once $path . 'resume-board/class-gravityview-preset-resume-board.php';
include_once $path . 'job-board/class-gravityview-preset-job-board.php';
include_once $path . 'event-listings/class-gravityview-preset-event-listings.php';
include_once $path . 'layout-builder/class-gravityview-layout-builder.php';
}


Expand Down
1 change: 1 addition & 0 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Beautifully display your Gravity Forms entries. Learn more on [gravitykit.com](h
= develop =

#### 🚀 Added
* New Layout Builder View type for creating custom layouts with single or multi-column configurations and adjustable widths.
* `:initials` merge tag modifier for Name fields to display initials.

#### 🐛 Fixed
Expand Down
Loading

0 comments on commit 3f0f199

Please sign in to comment.