Skip to:
Content

BuddyPress.org

Ticket #8526: 8526.patch

File 8526.patch, 22.6 KB (added by imath, 5 years ago)
  • Gruntfile.js

    diff --git Gruntfile.js Gruntfile.js
    index e470da5cd..663ac7963 100644
    module.exports = function( grunt ) { 
    4949                        '!bp-friends/css/blocks/friends.css',
    5050                        '!bp-members/css/blocks/dynamic-members.css',
    5151                        '!bp-groups/css/blocks/dynamic-groups.css',
    52                         '!bp-messages/css/blocks/sitewide-notices.css'
     52                        '!bp-messages/css/blocks/sitewide-notices.css',
     53                        '!bp-blogs/css/blocks/recent-posts.css'
    5354                ],
    5455
    5556                autoprefixer = require('autoprefixer');
    module.exports = function( grunt ) { 
    195196                                flatten: true,
    196197                                src: ['bp-messages/sass/blocks/*.scss'],
    197198                                dest: SOURCE_DIR + 'bp-messages/css/blocks/'
     199                        },
     200                        blogs_blocks: {
     201                                cwd: SOURCE_DIR,
     202                                extDot: 'last',
     203                                expand: true,
     204                                ext: '.css',
     205                                flatten: true,
     206                                src: ['bp-blogs/sass/blocks/*.scss'],
     207                                dest: SOURCE_DIR + 'bp-blogs/css/blocks/'
    198208                        }
    199209                },
    200210                rtlcss: {
  • new file src/bp-blogs/bp-blogs-blocks.php

    diff --git src/bp-blogs/bp-blogs-blocks.php src/bp-blogs/bp-blogs-blocks.php
    new file mode 100644
    index 000000000..47bf94596
    - +  
     1<?php
     2/**
     3 * BP Blogs Blocks Functions.
     4 *
     5 * @package BuddyPress
     6 * @subpackage BlogsBlocks
     7 * @since 9.0.0
     8 */
     9
     10// Exit if accessed directly.
     11if ( ! defined( 'ABSPATH' ) ) {
     12        exit;
     13}
     14
     15/**
     16 * Callback function to render the Recent Posts Block.
     17 *
     18 * @since 9.0.0
     19 *
     20 * @param array $attributes The block attributes.
     21 * @return string           HTML output.
     22 */
     23function bp_blogs_render_recent_posts_block( $attributes = array() ) {
     24        $block_args = wp_parse_args(
     25                $attributes,
     26                array(
     27                        'title'     => __( 'Recent Networkwide Posts', 'buddypress' ),
     28                        'maxPosts'  => 10,
     29                        'linkTitle' => false,
     30                )
     31        );
     32
     33        $classnames           = 'widget_bp_blogs_widget buddypress widget';
     34        $wrapper_attributes   = get_block_wrapper_attributes( array( 'class' => $classnames ) );
     35        $blogs_directory_link = bp_get_blogs_directory_permalink();
     36        $max_posts            = (int) $block_args['maxPosts'];
     37        $no_posts             = __( 'Sorry, there were no posts found.', 'buddypress' );
     38
     39        // Set the Block's title.
     40        if ( true === $block_args['linkTitle'] ) {
     41                $widget_content = sprintf(
     42                        '<h2 class="widget-title"><a href="%1$s">%2$s</a></h2>',
     43                        esc_url( $blogs_directory_link ),
     44                        esc_html( $block_args['title'] )
     45                );
     46        } else {
     47                $widget_content = sprintf( '<h2 class="widget-title">%s</h2>', esc_html( $block_args['title'] ) );
     48        }
     49
     50        $blog_activities = bp_activity_get(
     51                array(
     52                        'max'      => $max_posts,
     53                        'per_page' => $max_posts,
     54                        'user_id'  => 0,
     55                        'scope'    => false,
     56                        'filter'   => array(
     57                                'object'     => false,
     58                                'primary_id' => false,
     59                                'action'     => 'new_blog_post',
     60                        ),
     61                )
     62        );
     63
     64        $blog_activities = reset( $blog_activities );
     65
     66        if ( ! $blog_activities ) {
     67                $widget_content .= sprintf( '<div class="widget-error">%s</div>', $no_posts );
     68        } else {
     69                // Avoid conflicts with other activity loops.
     70                $reset_activities_template = null;
     71                if ( ! empty( $GLOBALS['activities_template'] ) ) {
     72                        $reset_activities_template = $GLOBALS['activities_template'];
     73                }
     74
     75                $GLOBALS['activities_template'] = new \stdClass();
     76                $activities                     = array();
     77
     78                foreach ( $blog_activities as $blog_activity ) {
     79                        $activity_content                         = '';
     80                        $GLOBALS['activities_template']->activity = $blog_activity;
     81
     82                        if ( $blog_activity->content ) {
     83                                /** This filter is documented in bp-activity/bp-activity-template.php. */
     84                                $activity_content = apply_filters_ref_array( 'bp_get_activity_content_body', array( $blog_activity->content, &$blog_activity ) );
     85                                $activity_content = sprintf(
     86                                        '<div class="activity-inner">%s</div>',
     87                                        $activity_content
     88                                );
     89                        }
     90
     91                        /** This filter is documented in bp-activity/bp-activity-template.php. */
     92                        $actity_action = apply_filters_ref_array(
     93                                'bp_get_activity_action',
     94                                array(
     95                                        bp_insert_activity_meta( $blog_activity->action ),
     96                                        &$blog_activity,
     97                                        array( 'no_timestamp' => false ),
     98                                )
     99                        );
     100
     101                        $activities[] = sprintf(
     102                                '<li>
     103                                        <div class="activity-content">
     104                                                <div class="activity-header">%1$s</div>
     105                                                %2$s
     106                                        </div>
     107                                </li>',
     108                                $actity_action,
     109                                $activity_content
     110                        );
     111                }
     112
     113                // Reset the global template loop.
     114                $GLOBALS['activities_template'] = $reset_activities_template;
     115
     116                $widget_content .= sprintf(
     117                        '<ul class="activity-list item-list">
     118                                %s
     119                        </ul>',
     120                        implode( "\n", $activities )
     121                );
     122        }
     123
     124        // Adds a container to make sure the block is styled even when used into the Columns parent block.
     125        $widget_content = sprintf( '<div class="bp-recent-posts-block-container">%s</div>', "\n" . $widget_content . "\n" );
     126
     127        // Only add a block wrapper if not loaded into a Widgets sidebar.
     128        if ( ! did_action( 'dynamic_sidebar_before' ) ) {
     129                return sprintf(
     130                        '<div %1$s>%2$s</div>',
     131                        $wrapper_attributes,
     132                        $widget_content
     133                );
     134        }
     135
     136        return $widget_content;
     137}
  • src/bp-blogs/classes/class-bp-blogs-component.php

    diff --git src/bp-blogs/classes/class-bp-blogs-component.php src/bp-blogs/classes/class-bp-blogs-component.php
    index fa4bae095..fb963935b 100644
    class BP_Blogs_Component extends BP_Component { 
    8181                        'autocomplete_all'      => defined( 'BP_MESSAGES_AUTOCOMPLETE_ALL' ),
    8282                        'global_tables'         => $global_tables,
    8383                        'meta_tables'           => $meta_tables,
     84                        'block_globals'         => array(
     85                                'bp/recent-posts' => array(
     86                                        'widget_classnames' => array( 'widget_bp_blogs_widget', 'buddypress' ),
     87                                ),
     88                        ),
    8489                );
    8590
    8691                // Setup the globals.
    class BP_Blogs_Component extends BP_Component { 
    136141
    137142                if ( is_multisite() ) {
    138143                        $includes[] = 'widgets';
     144                        $includes[] = 'blocks';
    139145                }
    140146
    141147                // Include the files.
    class BP_Blogs_Component extends BP_Component { 
    389395         *                      description.
    390396         */
    391397        public function blocks_init( $blocks = array() ) {
    392                 parent::blocks_init( array() );
     398                $blocks = array();
     399
     400                if ( is_multisite() ) {
     401                        $blocks['bp/recent-posts'] = array(
     402                                'name'               => 'bp/recent-posts',
     403                                'editor_script'      => 'bp-recent-posts-block',
     404                                'editor_script_url'  => plugins_url( 'js/blocks/recent-posts.js', dirname( __FILE__ ) ),
     405                                'editor_script_deps' => array(
     406                                        'wp-blocks',
     407                                        'wp-element',
     408                                        'wp-components',
     409                                        'wp-i18n',
     410                                        'wp-block-editor',
     411                                        'bp-block-components',
     412                                ),
     413                                'style'              => 'bp-recent-posts-block',
     414                                'style_url'          => plugins_url( 'css/blocks/recent-posts.css', dirname( __FILE__ ) ),
     415                                'attributes'         => array(
     416                                        'title'     => array(
     417                                                'type'    => 'string',
     418                                                'default' => __( 'Recent Networkwide Posts', 'buddypress' ),
     419                                        ),
     420                                        'maxPosts'  => array(
     421                                                'type'    => 'number',
     422                                                'default' => 10,
     423                                        ),
     424                                        'linkTitle' => array(
     425                                                'type'    => 'boolean',
     426                                                'default' => false,
     427                                        ),
     428                                ),
     429                                'render_callback'    => 'bp_blogs_render_recent_posts_block',
     430                        );
     431                }
     432
     433                parent::blocks_init( $blocks );
    393434        }
    394435}
  • new file src/bp-blogs/css/blocks/recent-posts-rtl.css

    diff --git src/bp-blogs/css/blocks/recent-posts-rtl.css src/bp-blogs/css/blocks/recent-posts-rtl.css
    new file mode 100644
    index 000000000..694dc3536
    - +  
     1.bp-recent-posts-block-container a {
     2        box-shadow: none;
     3        text-decoration: none;
     4}
     5
     6.bp-recent-posts-block-container ul.item-list {
     7        list-style: none;
     8        margin: 10px 0;
     9}
     10
     11.bp-recent-posts-block-container ul.activity-list {
     12        padding: 0;
     13}
     14
     15.bp-recent-posts-block-container ul.activity-list blockquote {
     16        margin: 0 0 1.5em;
     17        overflow: visible;
     18        padding: 0 0.75em 0.75em 0;
     19}
     20
     21.bp-recent-posts-block-container ul.activity-list img {
     22        margin-bottom: 0.5em;
     23}
     24
     25.bp-recent-posts-block-container ul.activity-list li {
     26        border-bottom: 1px solid #ccc;
     27        margin-bottom: 1em;
     28}
     29
     30.bp-recent-posts-block-container ul.activity-list li .activity-header p {
     31        margin-bottom: 0.5em;
     32}
     33
     34.bp-recent-posts-block-container ul.activity-list li .activity-header p .time-since {
     35        font-size: 80%;
     36        color: #767676;
     37        text-decoration: none;
     38}
     39
     40.bp-recent-posts-block-container ul.activity-list li:last-child {
     41        border-bottom: 0;
     42}
  • new file src/bp-blogs/css/blocks/recent-posts.css

    diff --git src/bp-blogs/css/blocks/recent-posts.css src/bp-blogs/css/blocks/recent-posts.css
    new file mode 100644
    index 000000000..b6eb6adf0
    - +  
     1.bp-recent-posts-block-container a {
     2        box-shadow: none;
     3        text-decoration: none;
     4}
     5
     6.bp-recent-posts-block-container ul.item-list {
     7        list-style: none;
     8        margin: 10px 0;
     9}
     10
     11.bp-recent-posts-block-container ul.activity-list {
     12        padding: 0;
     13}
     14
     15.bp-recent-posts-block-container ul.activity-list blockquote {
     16        margin: 0 0 1.5em;
     17        overflow: visible;
     18        padding: 0 0 0.75em 0.75em;
     19}
     20
     21.bp-recent-posts-block-container ul.activity-list img {
     22        margin-bottom: 0.5em;
     23}
     24
     25.bp-recent-posts-block-container ul.activity-list li {
     26        border-bottom: 1px solid #ccc;
     27        margin-bottom: 1em;
     28}
     29
     30.bp-recent-posts-block-container ul.activity-list li .activity-header p {
     31        margin-bottom: 0.5em;
     32}
     33
     34.bp-recent-posts-block-container ul.activity-list li .activity-header p .time-since {
     35        font-size: 80%;
     36        color: #767676;
     37        text-decoration: none;
     38}
     39
     40.bp-recent-posts-block-container ul.activity-list li:last-child {
     41        border-bottom: 0;
     42}
  • new file src/bp-blogs/js/blocks/recent-posts.js

    diff --git src/bp-blogs/js/blocks/recent-posts.js src/bp-blogs/js/blocks/recent-posts.js
    new file mode 100644
    index 000000000..69a2add7f
    - +  
     1// modules are defined as an array
     2// [ module function, map of requires ]
     3//
     4// map of requires is short require name -> numeric require
     5//
     6// anything defined in a previous bundle is accessed via the
     7// orig method which is the require for previous bundles
     8parcelRequire = (function (modules, cache, entry, globalName) {
     9  // Save the require from previous bundle to this closure if any
     10  var previousRequire = typeof parcelRequire === 'function' && parcelRequire;
     11  var nodeRequire = typeof require === 'function' && require;
     12
     13  function newRequire(name, jumped) {
     14    if (!cache[name]) {
     15      if (!modules[name]) {
     16        // if we cannot find the module within our internal map or
     17        // cache jump to the current global require ie. the last bundle
     18        // that was added to the page.
     19        var currentRequire = typeof parcelRequire === 'function' && parcelRequire;
     20        if (!jumped && currentRequire) {
     21          return currentRequire(name, true);
     22        }
     23
     24        // If there are other bundles on this page the require from the
     25        // previous one is saved to 'previousRequire'. Repeat this as
     26        // many times as there are bundles until the module is found or
     27        // we exhaust the require chain.
     28        if (previousRequire) {
     29          return previousRequire(name, true);
     30        }
     31
     32        // Try the node require function if it exists.
     33        if (nodeRequire && typeof name === 'string') {
     34          return nodeRequire(name);
     35        }
     36
     37        var err = new Error('Cannot find module \'' + name + '\'');
     38        err.code = 'MODULE_NOT_FOUND';
     39        throw err;
     40      }
     41
     42      localRequire.resolve = resolve;
     43      localRequire.cache = {};
     44
     45      var module = cache[name] = new newRequire.Module(name);
     46
     47      modules[name][0].call(module.exports, localRequire, module, module.exports, this);
     48    }
     49
     50    return cache[name].exports;
     51
     52    function localRequire(x){
     53      return newRequire(localRequire.resolve(x));
     54    }
     55
     56    function resolve(x){
     57      return modules[name][1][x] || x;
     58    }
     59  }
     60
     61  function Module(moduleName) {
     62    this.id = moduleName;
     63    this.bundle = newRequire;
     64    this.exports = {};
     65  }
     66
     67  newRequire.isParcelRequire = true;
     68  newRequire.Module = Module;
     69  newRequire.modules = modules;
     70  newRequire.cache = cache;
     71  newRequire.parent = previousRequire;
     72  newRequire.register = function (id, exports) {
     73    modules[id] = [function (require, module) {
     74      module.exports = exports;
     75    }, {}];
     76  };
     77
     78  var error;
     79  for (var i = 0; i < entry.length; i++) {
     80    try {
     81      newRequire(entry[i]);
     82    } catch (e) {
     83      // Save first error but execute all entries
     84      if (!error) {
     85        error = e;
     86      }
     87    }
     88  }
     89
     90  if (entry.length) {
     91    // Expose entry point to Node, AMD or browser globals
     92    // Based on https://github.com/ForbesLindesay/umd/blob/master/template.js
     93    var mainExports = newRequire(entry[entry.length - 1]);
     94
     95    // CommonJS
     96    if (typeof exports === "object" && typeof module !== "undefined") {
     97      module.exports = mainExports;
     98
     99    // RequireJS
     100    } else if (typeof define === "function" && define.amd) {
     101     define(function () {
     102       return mainExports;
     103     });
     104
     105    // <script>
     106    } else if (globalName) {
     107      this[globalName] = mainExports;
     108    }
     109  }
     110
     111  // Override the current require with this new one
     112  parcelRequire = newRequire;
     113
     114  if (error) {
     115    // throw error from earlier, _after updating parcelRequire_
     116    throw error;
     117  }
     118
     119  return newRequire;
     120})({"Pfcj":[function(require,module,exports) {
     121"use strict";
     122
     123Object.defineProperty(exports, "__esModule", {
     124  value: true
     125});
     126exports.default = void 0;
     127
     128/**
     129 * WordPress dependencies.
     130 */
     131var _wp = wp,
     132    InspectorControls = _wp.blockEditor.InspectorControls,
     133    _wp$components = _wp.components,
     134    Disabled = _wp$components.Disabled,
     135    PanelBody = _wp$components.PanelBody,
     136    RangeControl = _wp$components.RangeControl,
     137    TextControl = _wp$components.TextControl,
     138    ToggleControl = _wp$components.ToggleControl,
     139    _wp$element = _wp.element,
     140    Fragment = _wp$element.Fragment,
     141    createElement = _wp$element.createElement,
     142    __ = _wp.i18n.__;
     143/**
     144 * BuddyPress dependencies.
     145 */
     146
     147var _bp = bp,
     148    ServerSideRender = _bp.blockComponents.ServerSideRender;
     149
     150var editRecentPostsBlock = function editRecentPostsBlock(_ref) {
     151  var attributes = _ref.attributes,
     152      setAttributes = _ref.setAttributes;
     153  var title = attributes.title,
     154      maxPosts = attributes.maxPosts,
     155      linkTitle = attributes.linkTitle;
     156  return createElement(Fragment, null, createElement(InspectorControls, null, createElement(PanelBody, {
     157    title: __('Settings', 'buddypress'),
     158    initialOpen: true
     159  }, createElement(TextControl, {
     160    label: __('Title', 'buddypress'),
     161    value: title,
     162    onChange: function onChange(text) {
     163      setAttributes({
     164        title: text
     165      });
     166    }
     167  }), createElement(RangeControl, {
     168    label: __('Max posts to show', 'buddypress'),
     169    value: maxPosts,
     170    onChange: function onChange(value) {
     171      return setAttributes({
     172        maxPosts: value
     173      });
     174    },
     175    min: 1,
     176    max: 10,
     177    required: true
     178  }), createElement(ToggleControl, {
     179    label: __('Link block title to Blogs directory', 'buddypress'),
     180    checked: !!linkTitle,
     181    onChange: function onChange() {
     182      setAttributes({
     183        linkTitle: !linkTitle
     184      });
     185    }
     186  }))), createElement(Disabled, null, createElement(ServerSideRender, {
     187    block: "bp/recent-posts",
     188    attributes: attributes
     189  })));
     190};
     191
     192var _default = editRecentPostsBlock;
     193exports.default = _default;
     194},{}],"D8sC":[function(require,module,exports) {
     195"use strict";
     196
     197Object.defineProperty(exports, "__esModule", {
     198  value: true
     199});
     200exports.default = void 0;
     201
     202/**
     203 * WordPress dependencies.
     204 */
     205var _wp = wp,
     206    createBlock = _wp.blocks.createBlock;
     207/**
     208 * Transforms Legacy Widget to Recent Posts Block.
     209 *
     210 * @type {Object}
     211 */
     212
     213var transforms = {
     214  from: [{
     215    type: 'block',
     216    blocks: ['core/legacy-widget'],
     217    isMatch: function isMatch(_ref) {
     218      var idBase = _ref.idBase,
     219          instance = _ref.instance;
     220
     221      if (!(instance !== null && instance !== void 0 && instance.raw)) {
     222        return false;
     223      }
     224
     225      return idBase === 'bp_blogs_recent_posts_widget';
     226    },
     227    transform: function transform(_ref2) {
     228      var instance = _ref2.instance;
     229      return createBlock('bp/recent-posts', {
     230        title: instance.raw.title,
     231        maxPosts: instance.raw.max_posts,
     232        linkTitle: instance.raw.link_title
     233      });
     234    }
     235  }]
     236};
     237var _default = transforms;
     238exports.default = _default;
     239},{}],"PMBS":[function(require,module,exports) {
     240"use strict";
     241
     242var _edit = _interopRequireDefault(require("./recent-posts/edit"));
     243
     244var _transforms = _interopRequireDefault(require("./recent-posts/transforms"));
     245
     246function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
     247
     248/**
     249 * WordPress dependencies.
     250 */
     251var _wp = wp,
     252    registerBlockType = _wp.blocks.registerBlockType,
     253    __ = _wp.i18n.__;
     254/**
     255 * Internal dependencies.
     256 */
     257
     258registerBlockType('bp/recent-posts', {
     259  title: __('Recent Networkwide Posts', 'buddypress'),
     260  description: __('A list of recently published posts from across your network.', 'buddypress'),
     261  icon: {
     262    background: '#fff',
     263    foreground: '#d84800',
     264    src: 'wordpress'
     265  },
     266  category: 'buddypress',
     267  attributes: {
     268    title: {
     269      type: 'string',
     270      default: __('Recent Networkwide Posts', 'buddypress')
     271    },
     272    maxPosts: {
     273      type: 'number',
     274      default: 10
     275    },
     276    linkTitle: {
     277      type: 'boolean',
     278      default: false
     279    }
     280  },
     281  edit: _edit.default,
     282  transforms: _transforms.default
     283});
     284},{"./recent-posts/edit":"Pfcj","./recent-posts/transforms":"D8sC"}]},{},["PMBS"], null)
     285 No newline at end of file
  • new file src/bp-blogs/sass/blocks/recent-posts.scss

    diff --git src/bp-blogs/sass/blocks/recent-posts.scss src/bp-blogs/sass/blocks/recent-posts.scss
    new file mode 100644
    index 000000000..efc8ced7f
    - +  
     1.bp-recent-posts-block-container {
     2
     3        a {
     4                box-shadow: none;
     5                text-decoration: none;
     6        }
     7
     8        ul.item-list {
     9                list-style: none;
     10                margin: 10px 0;
     11        }
     12
     13        ul.activity-list {
     14
     15                padding: 0;
     16
     17                blockquote {
     18                        margin: 0 0 1.5em;
     19                        overflow: visible;
     20                        padding: 0 0 0.75em 0.75em;
     21                }
     22
     23                img {
     24                        margin-bottom: 0.5em;
     25                }
     26
     27                li {
     28                        border-bottom: 1px solid #ccc;
     29                        margin-bottom: 1em;
     30
     31                        .activity-header p {
     32                                margin-bottom: 0.5em;
     33
     34                                .time-since {
     35                                        font-size: 80%;
     36                                        color: #767676;
     37                                        text-decoration: none;
     38                                }
     39                        }
     40
     41                        &:last-child {
     42                                border-bottom: 0;
     43                        }
     44                }
     45        }
     46}
  • src/bp-core/classes/class-bp-core.php

    diff --git src/bp-core/classes/class-bp-core.php src/bp-core/classes/class-bp-core.php
    index 0a010c2a9..2a8e56faf 100644
    class BP_Core extends BP_Component { 
    296296                                'block_globals' => array(
    297297                                        'bp/login-form' => array(
    298298                                                'widget_classnames' => array( 'widget_bp_core_login_widget', 'buddypress' ),
    299                                         )
    300                                 )
     299                                        ),
     300                                ),
    301301                        )
    302302                );
    303303        }
  • new file src/js/bp-blogs/js/blocks/.babelrc

    diff --git src/js/bp-blogs/js/blocks/.babelrc src/js/bp-blogs/js/blocks/.babelrc
    new file mode 100644
    index 000000000..ab258a69c
    - +  
     1{
     2        "presets": ["@wordpress/default"]
     3}
  • new file src/js/bp-blogs/js/blocks/recent-posts.js

    diff --git src/js/bp-blogs/js/blocks/recent-posts.js src/js/bp-blogs/js/blocks/recent-posts.js
    new file mode 100644
    index 000000000..5c5cc2094
    - +  
     1/**
     2 * WordPress dependencies.
     3 */
     4const {
     5        blocks: {
     6                registerBlockType,
     7        },
     8        i18n: {
     9                __,
     10        },
     11} = wp;
     12
     13/**
     14 * Internal dependencies.
     15 */
     16import editRecentPostsBlock from './recent-posts/edit';
     17import transforms from './recent-posts/transforms';
     18
     19registerBlockType( 'bp/recent-posts', {
     20        title: __( 'Recent Networkwide Posts', 'buddypress' ),
     21        description: __( 'A list of recently published posts from across your network.', 'buddypress' ),
     22        icon: {
     23                background: '#fff',
     24                foreground: '#d84800',
     25                src: 'wordpress',
     26        },
     27        category: 'buddypress',
     28        attributes: {
     29                title: {
     30                        type: 'string',
     31                        default: __( 'Recent Networkwide Posts', 'buddypress' ),
     32                },
     33                maxPosts: {
     34                        type: 'number',
     35                        default: 10
     36                },
     37                linkTitle: {
     38                        type: 'boolean',
     39                        default: false,
     40                },
     41        },
     42        edit: editRecentPostsBlock,
     43        transforms: transforms,
     44} );
  • new file src/js/bp-blogs/js/blocks/recent-posts/edit.js

    diff --git src/js/bp-blogs/js/blocks/recent-posts/edit.js src/js/bp-blogs/js/blocks/recent-posts/edit.js
    new file mode 100644
    index 000000000..921087ac0
    - +  
     1/**
     2 * WordPress dependencies.
     3 */
     4const {
     5        blockEditor: {
     6                InspectorControls,
     7        },
     8        components: {
     9                Disabled,
     10                PanelBody,
     11                RangeControl,
     12                TextControl,
     13                ToggleControl,
     14        },
     15        element: {
     16                Fragment,
     17                createElement,
     18        },
     19        i18n: {
     20                __,
     21        },
     22} = wp;
     23
     24/**
     25 * BuddyPress dependencies.
     26 */
     27const {
     28        blockComponents: {
     29                ServerSideRender,
     30        },
     31} = bp;
     32
     33const editRecentPostsBlock = ( { attributes, setAttributes } ) => {
     34        const { title, maxPosts, linkTitle } = attributes;
     35
     36        return (
     37                <Fragment>
     38                        <InspectorControls>
     39                                <PanelBody title={ __( 'Settings', 'buddypress' ) } initialOpen={ true }>
     40                                        <TextControl
     41                                                label={ __( 'Title', 'buddypress' ) }
     42                                                value={ title }
     43                                                onChange={ ( text ) => {
     44                                                        setAttributes( { title: text } );
     45                                                } }
     46                                        />
     47                                        <RangeControl
     48                                                label={ __( 'Max posts to show', 'buddypress' ) }
     49                                                value={ maxPosts }
     50                                                onChange={ ( value ) =>
     51                                                        setAttributes( { maxPosts: value } )
     52                                                }
     53                                                min={ 1 }
     54                                                max={ 10 }
     55                                                required
     56                                        />
     57                                        <ToggleControl
     58                                                label={ __( 'Link block title to Blogs directory', 'buddypress' ) }
     59                                                checked={ !! linkTitle }
     60                                                onChange={ () => {
     61                                                        setAttributes( { linkTitle: ! linkTitle } );
     62                                                } }
     63                                        />
     64                                </PanelBody>
     65                        </InspectorControls>
     66                        <Disabled>
     67                                <ServerSideRender block="bp/recent-posts" attributes={ attributes } />
     68                        </Disabled>
     69                </Fragment>
     70        );
     71};
     72
     73export default editRecentPostsBlock;
  • new file src/js/bp-blogs/js/blocks/recent-posts/transforms.js

    diff --git src/js/bp-blogs/js/blocks/recent-posts/transforms.js src/js/bp-blogs/js/blocks/recent-posts/transforms.js
    new file mode 100644
    index 000000000..04d227fcf
    - +  
     1/**
     2 * WordPress dependencies.
     3 */
     4const {
     5        blocks: {
     6                createBlock,
     7        },
     8} = wp;
     9
     10/**
     11 * Transforms Legacy Widget to Recent Posts Block.
     12 *
     13 * @type {Object}
     14 */
     15const transforms = {
     16        from: [
     17                {
     18                        type: 'block',
     19                        blocks: [ 'core/legacy-widget' ],
     20                        isMatch: ( { idBase, instance } ) => {
     21                                if ( ! instance?.raw ) {
     22                                        return false;
     23                                }
     24
     25                                return idBase === 'bp_blogs_recent_posts_widget';
     26                        },
     27                        transform: ( { instance } ) => {
     28                                return createBlock( 'bp/recent-posts', {
     29                                        title: instance.raw.title,
     30                                        maxPosts: instance.raw.max_posts,
     31                                        linkTitle: instance.raw.link_title,
     32                                } );
     33                        },
     34                },
     35        ],
     36};
     37
     38export default transforms;