This comprehensive guide will teach you OOP concepts applied to modern WordPress development with Twig, Gutenberg blocks, SCSS, React, and TypeScript (TSX). We’ll focus on creating a table of contents block that connects to NoCoDB with loan percentage data.
Table of Contents
- OOP Fundamentals for WordPress
- WordPress Block Architecture
- Setting Up the Development Environment
- Creating a Table of Contents Block
- Connecting to NoCoDB
- Block Attributes with Logo, Text, and Percentages
- Study Materials
1. OOP Fundamentals for WordPress <a name=”oop-fundamentals”></a>
Core OOP Concepts in PHP (WordPress Context)
php
// Basic class structure
class LoanCalculator {
// Properties (attributes)
private float $principal;
private float $rate;
private int $term;
// Constructor
public function __construct(float $principal, float $rate, int $term) {
$this->principal = $principal;
$this->rate = $rate;
$this->term = $term;
}
// Method (behavior)
public function calculateMonthlyPayment(): float {
$monthlyRate = $this->rate / 12 / 100;
return $this->principal * $monthlyRate *
pow(1 + $monthlyRate, $this->term) /
(pow(1 + $monthlyRate, $this->term) - 1);
}
// Static method (class-level behavior)
public static function formatCurrency(float $amount): string {
return '$' . number_format($amount, 2);
}
}
// Usage
$calculator = new LoanCalculator(100000, 3.5, 360);
echo $calculator->calculateMonthlyPayment();
WordPress-Specific OOP Patterns
- Singleton Pattern (for main plugin classes)
- Factory Pattern (for block registration)
- Decorator Pattern (for extending blocks)
- Dependency Injection (for services)
2. WordPress Block Architecture <a name=”block-architecture”></a>
Modern WordPress blocks use a combination of:
- PHP (for server-side registration)
- React/TypeScript (for editor interface)
- Twig (for templating)
- SCSS (for styling)
text
block-plugin/ ├── build/ # Compiled assets ├── src/ │ ├── blocks/ # Individual blocks │ │ └── table-of-contents/ │ │ ├── block.json # Block metadata │ │ ├── edit.tsx # Editor component │ │ ├── index.ts # Block registration │ │ ├── save.tsx # Frontend save component │ │ ├── style.scss # Editor styles │ │ └── view.twig # Frontend template │ ├── models/ # OOP data models │ ├── services/ # Service classes │ └── index.php # Main plugin file ├── webpack.config.js # Build configuration └── package.json
3. Setting Up the Development Environment <a name=”development-environment”></a>
- Install Node.js and npm/yarn
- Set up WordPress development environment (Local by Flywheel, Docker, etc.)
- Install required tools:bashnpm install @wordpress/scripts @wordpress/blocks @wordpress/block-editor @wordpress/components @wordpress/data sass twig-loader typescript @types/react @types/react-dom
4. Creating a Table of Contents Block <a name=”toc-block”></a>
Block Registration (OOP Approach)
php
// src/index.php
class TableOfContentsBlock {
private static $instance = null;
private function __construct() {
add_action('init', [$this, 'registerBlock']);
}
public static function getInstance(): self {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
public function registerBlock(): void {
register_block_type(__DIR__ . '/build/table-of-contents');
}
}
TableOfContentsBlock::getInstance();
TypeScript Interface for Block Attributes
typescript
// src/blocks/table-of-contents/types.ts
interface LoanItem {
id: string;
title: string;
percentage: number;
logoUrl?: string;
}
interface TableOfContentsAttributes {
title: string;
items: LoanItem[];
showPercentages: boolean;
backgroundColor: string;
}
5. Connecting to NoCoDB <a name=”noco-db”></a>
Service Class for NoCoDB Integration
php
// src/services/NocoDBService.php
class NocoDBService {
private string $apiUrl;
private string $apiKey;
public function __construct(string $apiUrl, string $apiKey) {
$this->apiUrl = $apiUrl;
$this->apiKey = $apiKey;
}
public function fetchLoanData(): array {
$response = wp_remote_get($this->apiUrl . '/api/v1/tables/loans/records', [
'headers' => [
'xc-auth' => $this->apiKey
]
]);
if (is_wp_error($response)) {
return [];
}
$body = json_decode(wp_remote_retrieve_body($response), true);
return array_map(function($item) {
return [
'id' => $item['Id'],
'title' => $item['Title'],
'percentage' => (float)$item['Percentage'],
'logoUrl' => $item['LogoUrl'] ?? ''
];
}, $body['list'] ?? []);
}
}
React Component with Data Fetching
typescript
// src/blocks/table-of-contents/edit.tsx
import { useBlockProps } from '@wordpress/block-editor';
import { useState, useEffect } from '@wordpress/element';
const Edit = ({ attributes, setAttributes }: { attributes: TableOfContentsAttributes, setAttributes: any }) => {
const [loading, setLoading] = useState(false);
const [error, setError] = useState('');
useEffect(() => {
const fetchData = async () => {
setLoading(true);
try {
const response = await fetch('/wp-json/table-of-contents/v1/loan-data');
const data = await response.json();
setAttributes({ items: data });
} catch (err) {
setError('Failed to fetch loan data');
} finally {
setLoading(false);
}
};
fetchData();
}, []);
return (
<div {...useBlockProps()}>
{loading ? (
<p>Loading loan data...</p>
) : error ? (
<p>{error}</p>
) : (
<div className="loan-toc">
<h2>{attributes.title || 'Loan Options'}</h2>
<ul>
{attributes.items.map(item => (
<li key={item.id}>
{item.logoUrl && <img src={item.logoUrl} alt="" />}
<span>{item.title}</span>
{attributes.showPercentages && (
<span>{item.percentage}%</span>
)}
</li>
))}
</ul>
</div>
)}
</div>
);
};
6. Block Attributes with Logo, Text, and Percentages <a name=”block-attributes”></a>
block.json Configuration
json
{
"apiVersion": 2,
"name": "my-plugin/table-of-contents",
"title": "Loan Table of Contents",
"category": "widgets",
"icon": "list-view",
"description": "Displays a table of contents with loan percentages from NoCoDB",
"attributes": {
"title": {
"type": "string",
"default": "Loan Options"
},
"items": {
"type": "array",
"default": [],
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"title": { "type": "string" },
"percentage": { "type": "number" },
"logoUrl": { "type": "string" }
}
}
},
"showPercentages": {
"type": "boolean",
"default": true
},
"backgroundColor": {
"type": "string",
"default": "#ffffff"
}
},
"editorScript": "file:./index.js",
"style": "file:./style.css"
}
Twig Template for Frontend
twig
{# src/blocks/table-of-contents/view.twig #}
<div class="wp-block-my-plugin-table-of-contents" style="background-color: {{ attributes.backgroundColor }};">
<h2>{{ attributes.title }}</h2>
<ul class="loan-items">
{% for item in attributes.items %}
<li class="loan-item">
{% if item.logoUrl %}
<img src="{{ item.logoUrl }}" alt="{{ item.title }} logo" class="loan-logo" />
{% endif %}
<span class="loan-title">{{ item.title }}</span>
{% if attributes.showPercentages %}
<span class="loan-percentage">{{ item.percentage }}%</span>
{% endif %}
</li>
{% endfor %}
</ul>
</div>
SCSS Styling
scss
// src/blocks/table-of-contents/style.scss
.wp-block-my-plugin-table-of-contents {
padding: 20px;
border-radius: 8px;
h2 {
margin-top: 0;
color: #333;
}
.loan-items {
list-style: none;
padding: 0;
margin: 0;
}
.loan-item {
display: flex;
align-items: center;
padding: 10px 0;
border-bottom: 1px solid #eee;
&:last-child {
border-bottom: none;
}
}
.loan-logo {
width: 30px;
height: 30px;
margin-right: 15px;
object-fit: contain;
}
.loan-title {
flex-grow: 1;
font-weight: 500;
}
.loan-percentage {
background: #4CAF50;
color: white;
padding: 3px 8px;
border-radius: 12px;
font-size: 0.8em;
}
}
7. Study Materials <a name=”study-materials”></a>
Fast-Track OOP Learning
- PHP OOP Crash Course
- WordPress-Specific OOP
- Modern WordPress Development
- React/TypeScript for WordPress
- NoCoDB Integration
Practical Exercises
- Create a simple PHP class that calculates loan amortization
- Convert a traditional WordPress shortcode to a Gutenberg block
- Implement a service class that fetches data from an external API
- Create a parent block with child blocks using composition
- Implement a block variation that shows loan data in different formats
Remember, the key to mastering OOP in WordPress is practice. Start with small, focused classes and gradually build more complex systems as you become comfortable with the patterns.