Skip to content

Commit c7d21b3

Browse files
release(minor): version 2.3.0
- Add Custom Taxonomy Support to Dynamic Values - Add More New Fields to Form Block - Add Option to Store Form Block Emails to WordPress Dashboard - Add Api Field in Stripe Block - Add Support for HTML in Stripe Block Messages - Add CDN Links in Patterns - Various Form Block Enhancements - Bump Minimum PHP Compatibility to 5.6 - Fix Dynamic Tags Not Working in Widgets - Fix Review Comparison Table Not Taking Reusable Review Blocks into Consideration - Fix Unused Assets Being Loaded When a Block Is Removed from Widgets - Fix Custom CSS Module Not Working with FSE - Fix Accordion Block Schema Conflicts with Neve PRO Performance Module and Lazy-loading Off-screen Elements
2 parents d4da09f + 874e738 commit c7d21b3

File tree

146 files changed

+7605
-1395
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

146 files changed

+7605
-1395
lines changed

Diff for: .github/PULL_REQUEST_TEMPLATE.md

+1
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,5 @@ new QueryQA().select('blocks').run()
3030
- [ ] In case of deprecation, old blocks are safely migrated.
3131
- [ ] It is usable in Widgets and FSE.
3232
- [ ] Copy/Paste is working if the attributes are modified.
33+
- [ ] PR is following [the best practices]()
3334

Diff for: CONTRIBUTING.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
## Setup
22

3+
More details about the setup can be found in [docs/environment-installation.md](docs/environment-installation.md).
4+
35
This projects requires you to have Node.js (with npm) and Composer.
46

57
- You can run `npm ci` & `composer install` to install dependencies.
68
- Once done, you can run `npm run build` to generate build files.
79
- You can also use `npm run start` to generate dev build if you are working on the files.
810

9-
The project also ships with a `docker-compose.yml` file, you can run `docker compose up-d` to bring the instance up.
11+
The project also ships with a `docker-compose.yml` file, you can run `docker compose up -d` to bring the instance up.
1012

1113
## Project Structure
1214

Diff for: assets/images/form-submissions-upsell.svg

+48
Loading

Diff for: blocks.json

+7-1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@
9393
"form-textarea": {
9494
"block": "blocks/blocks/form/textarea/block.json"
9595
},
96+
"form-multiple-choice": {
97+
"block": "blocks/blocks/form/multiple-choice/block.json"
98+
},
99+
"form-file": {
100+
"block": "blocks/blocks/form/file/block.json"
101+
},
96102
"google-map": {
97103
"block": "blocks/blocks/google-map/block.json",
98104
"assets": {
@@ -267,4 +273,4 @@
267273
"isPro": true,
268274
"block": "pro/woocommerce/upsells/block.json"
269275
}
270-
}
276+
}

Diff for: development.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,25 @@
1616
'themeisle_sdk_products',
1717
function ( $products ) {
1818
$products[] = dirname( __FILE__ ) . '/plugins/otter-pro/otter-pro.php';
19-
19+
2020
return $products;
2121
}
2222
);
23-
23+
2424
add_filter(
2525
'themesle_sdk_namespace_' . md5( dirname( __FILE__ ) . '/plugins/otter-pro/otter-pro.php' ),
2626
function () {
2727
return 'otter';
2828
}
2929
);
30-
30+
3131
add_filter(
3232
'otter_pro_lc_no_valid_string',
3333
function ( $message ) {
3434
return str_replace( '<a href="%s">', '<a href="' . admin_url( 'options-general.php?page=otter' ) . '">', $message );
3535
}
3636
);
37-
37+
3838
add_filter( 'otter_pro_hide_license_field', '__return_true' );
3939

4040
\ThemeIsle\OtterPro\Main::instance();

Diff for: docs/adding-patterns.md

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Patterns
2+
3+
Patterns are big part of Gutenberg ecosystem. In the old days, plugin developer made their own mechanism to add them, but things are now more organized.
4+
5+
Adding a new pattern for Otter is straight forward.
6+
7+
- All the patterns are located in `./src/patterns` folder.
8+
- Every pattern is just an array with keys described by the [Gutenberg documentation](https://developer.wordpress.org/block-editor/developers/block-api/block-patterns/).
9+
- After creating a file for it, register it on `./inc/patterns.php` file in `$block_patterns` array.
10+
11+
## Mentions
12+
13+
- The pattern name should be unique.
14+
- Do not use specific theme CSS vars as values for attributes. Like `"color": "var(--neve-custom-color)"`. This will make the pattern unusable on other themes. Patterns should be theme agnostic. Exceptions can be made, but only if it is intended.
15+
- Pay attention to image links. The images should the accessible from internet. If use the image that are in a private network, they can not used by users.
16+
- Always test the pattern. There is chance that you might have doing a small modification without thinking it will affect the code.
17+
- Pay attention to the blocks that you use. You accidentally might use a block that is not available in Otter or Gutenberg. Of course, you can add any block, but if it is external, it must intended.
18+
19+

Diff for: docs/coding-best-practices.md

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Coding Best Practices
2+
3+
<img src="https://imgs.xkcd.com/comics/standards_2x.png" width="400" alt="Coding practices meme from xkcd">
4+
5+
## Introduction
6+
7+
Best practices are a set of guidelines that help you write code that is easy to read, understand, and maintain. They are a set of rules that you should follow when writing code. They are not rules that you must follow, but they are recommended.
8+
9+
We follow the [WordPress Coding Standards](https://make.wordpress.org/core/handbook/best-practices/coding-standards/). For PHP, you can inspire from https://github.com/piotrplenik/clean-code-php
10+
11+
But this is not enough...
12+
13+
## Code for the Team
14+
15+
> When you write code, you are not writing it for yourself. You are writing it for the team. You are writing it for the future you. You are writing it for the future team members. You are writing it for the future clients. -- Copilot, April 2023
16+
17+
The sign of code quality are:
18+
- Easy to read and understand.
19+
- Easy to maintain.
20+
- Easy to extend.
21+
- Easy to debug.
22+
23+
To general, let's make an example for it:
24+
25+
Suppose you have this task: `Given a list of numbers, sum only the even numbers.`
26+
27+
A simple book-like solution would be:
28+
29+
```javascript
30+
const numbers = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
31+
32+
let sum = 0;
33+
34+
for ( let i = 0; i < numbers.length; i++ ) {
35+
if ( numbers[ i ] % 2 === 0 ) {
36+
sum += numbers[ i ];
37+
}
38+
}
39+
40+
console.log( sum );
41+
```
42+
43+
This is a simple solution. But it can be better. Let's refactor it:
44+
45+
```javascript
46+
const numbers = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
47+
48+
const sum = numbers
49+
.filter( ( number ) => number % 2 === 0 )
50+
.reduce( ( sum, number ) => sum + number, 0 );
51+
52+
console.log( sum );
53+
```
54+
55+
Why is this better?
56+
57+
- It is easier to read and understand. When you have a classic `for` loop, you need to read the whole loop to understand what it does. With the `filter` and `reduce` functions, you can understand what it does by reading only the first line. `filter` and `reduce` are specialized loops, they have a specific purpose.
58+
- Easy to maintain. It it easier to spot where to make a change.
59+
- Easy to extend. If the numbers are send as `string` instead of `number`, you can easily change the code to convert them to `number` before filtering and reducing. Example: Add `.map( ( number ) => parseInt( number, 10 ) )` before filter.
60+
- Easy to debug. The functionality is modular, so you can remove things one at the time and check them. One neat trick you can do is to create an inspection function like this:
61+
62+
```javascript
63+
const inspect = ( value ) => {
64+
console.log( value );
65+
return value;
66+
};
67+
```
68+
69+
Then, you can add it in the chain like this:
70+
71+
```javascript
72+
const sum = numbers
73+
.filter( ( number ) => number % 2 === 0 )
74+
.map( inspect )
75+
.reduce( ( sum, number ) => sum + number, 0 );
76+
```
77+
78+
This will out the result at each step of the chain. This is very useful when you need to debug a chain of functions.
79+
80+
The first version might me more faster, but if the code is running only at a press of a button or an event, it is not a big deal.
81+
82+
## Elegant Code
83+
84+
In era of generated code, we still need to have elegant code. At the end of the day, we are still writing code for humans (this might be obsolete in feature). We need to write code that is easy to read and understand.
85+
86+
Since the beginning of coding, people made a lot of articles and principles about how to write elegant code. Here are some of them:
87+
88+
- DRY (Don't Repeat Yourself) - [Wikipedia](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)
89+
- KISS (Keep It Simple, Stupid) - [Wikipedia](https://en.wikipedia.org/wiki/KISS_principle)
90+
- YAGNI (You Ain't Gonna Need It) - [Wikipedia](https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it)
91+
- SOLID - [Wikipedia](https://en.wikipedia.org/wiki/SOLID)
92+
- Design Patterns - [Wikipedia](https://en.wikipedia.org/wiki/Software_design_pattern)
93+
94+
## Performance
95+
96+
If you come from a background where performance is a big deal, you might be tempted to write code that is optimized for performance. Example: game development, HPC, etc.
97+
98+
In this project, we do not have cases when the code must do a lot of things at a high rate (like rendering a scene in a game). So, we can write code that is easy to read and understand, and we can optimize it later if needed.
99+
100+
> Early optimization is the root of all evil. -- Donald Knuth
101+
102+
The challenge in this project is to extend the code to support more features. The more we have, the harder it will be to maintain the code. Fancy tricks without a good reason are not good.
103+
104+
A piece code that is performant, easy to read and understand, and easy to maintain is the best. [But sometime you can not have it all](https://www.youtube.com/watch?v=hFDcoX7s6rE). So, you need to choose what is more important for your case.

0 commit comments

Comments
 (0)