Kodlayarak bir Gutenberg Block Editörü bloğu oluşturmayı merak ediyorsan hoş geldin. Bu derste, uygulamalı olarak bir block nasıl kodlanırı anlatıyorum. Keyifli okumalar.
Sonuç olarak elde edeceğimiz bloğun tema görünümü şöyle olacak:


Oluşturacağımız bloğun; Resim Ayarları ve Renkler olmak üzere iki adet ayar paneli olacak olacak:


Blok (Block) Kodlamak İçin Ne Gerekli?
Gutenberg (Block) Editör İçin Bir Block Tasarlama işi ile ilgilendiğinize göre, kodlama konusunda temel bilgilere sahipsinizdir diye düşünüyorum. Bu yüzden, burada, temel kavramlar üzerinde durmadan, doğrudan işin teknik boyutlarını açıklamayı düşünüyorum.
Ben bu derste, block geliştirmek için şu gereçleri kullanacağım:
- Xampp server ile localde kurulmuş bir WordPress ile çalışacağız
- Visiual Sutdio Code (Kod editörü olarak kullanacağız)
- npm (yüklü olmalı)
- webpack
- es6
- jsx
Listeyi görüp, karamsarlığa kapılan arkadaşlar için şunu söyleyebilirim: Çok da sıkıntı yapmayın, sırayı bozmandan, burada verilenleri takip edin. Bazen, kervanı yolda düzmek de fena fikir değildir. Ama, tek bir yazıda bütün bu teknolojileri açıklayabileceğim gibi bir iyimserlik içinde olmanızı da istemem. Ben sizlere örnek bir blok kodlayacağım, verdiğim kodların incelenmesi ve anlaşılmasını sizlere bırakacağım.
Önce Bir Eklenti Oluşturalım
Gutenberg Editörü’nde kullanılan “blocklar”, tema dosyaları ile değil eklentiler ile eklenir. Bu yüzden öncelikle bir eklenti oluşturmamız gerekiyor.
- Bir eklenti oluşturmak için öncelikle;
wp-content/pluginsdizinine gideriz.- Türkçe karakter ve boşluk kullanmadan, küçük harfler ile bir klasör ismi oluştururuz. (Klasörün ismi, genellikle, eklentiye vereceğimiz ismin nicename’i olur.) :
deneme-blocks - Bu klasörün içine, bir php dosyası ekleriz:
plugin.php
// Eklenti klasörü ve dosyaları
|- wp-content (klasör)
|-- plugins (klasör)
|--- deneme-blocks (klasör)
|---- plugin.php (dosya)
plugin.phpdosyasında, eklentimizi WordPress ile tanıştırıyoruz:
plugin.php
<?php
/*
Plugin Name: Deneme Blocks
Description: Bu bir deneme eklentisidir.
Text Domain: deneme_textd
Version: 1.0.0
*/
defined('ABSPATH') || exit(); // Doğrudan ulaşım kapalı
Eklenti Klasöründe Block İçin Gerekli Dosya ve Klasörleri Oluşturalım
- Eklentimizde, oluşturacağımız blokların
cssvejsdosyaları için,assetsadında bir klasör oluşturuyoruz:assetsklasörünün içinde, js ve css dosyaları için iki klasör daha açalım ki kafamız karışmasın.assets/jsklasöründe;- Tema tarafı için:
scripts.js - Admin tarafı için:
editor.jsdosyaları olsun.
- Tema tarafı için:
assets/cssklasöründe;- Tema tarafı için:
style.css - Admin tarafı için:
editor.cssdosyaları olsun.
- Tema tarafı için:
srcklasörü oluşturuyoruz.src: Kaynak klasörü. Block için yazacağımız kodların merkezi burası olacaktır.- Bu klasörün içinde,
index.jsadında bir dosya oluşturuyoruz.src/index.js: Block, bu dosyada tasarlanacak, webpack tarafından derlenecektir ve ilgili klasörlere aktarılacak.
- Bu klasör ve dosyalar oluşturulduktan sonra, eklenti dizinimiz şu hali alacaktır:
// Eklenti klasörü ve dosyaları
|- wp-content (klasör)
|-- plugins (klasör)
|--- deneme-blocks (klasör)
|---- assets (klasör)
|----- js (klasör)
|------ sripts.js (dosya)
|------ editor.js (dosya)
|----- css (klasör)
|------ style.css (dosya)
|------ editor.css (dosya)
|---- src(klasör)
|----- index.js (dosya)
|---- plugin.php (dosya)
- Gutenberg blokları için oluşturduğumuz bu dosyaları WordPress’e tanıtıyoruz:
plugin.php
<?php
/*
Plugin Name: Deneme Blocks
Description: Bu bir deneme eklentisidir.
Text Domain: deneme_textd
Version: 1.0.0
*/
defined('ABSPATH') || exit(); // Doğrudan ulaşım kapalı
/**
* HER EVE LAZIM
*/
define( 'STCNNT_BLOCKS_PLUGIN_PATH', trailingslashit( plugin_dir_path( __FILE__ ) ) );
define( 'STCNNT_BLOCKS_PLUGIN_URL', trailingslashit( plugins_url( '/', __FILE__ ) ) );
/**
* BLOCK İÇİN GEREKLİ JS VE CSS DOSYALARINI TANITILYORUZ
*/
function stcnnt_deneme_blocks_scripts() {
// Bu klasör ve dosya, otomatik olarak oluşturulacak
$asset_file = include( STCNNT_BLOCKS_PLUGIN_PATH . 'build/index.asset.php');
wp_register_script(
'stcnnt-deneme-blocks-editor-js',
STCNNT_BLOCKS_PLUGIN_URL . 'build/index.js',
$asset_file['dependencies'],
$asset_file['version']
);
wp_register_style(
'stcnnt-deneme-blocks-editor-style',
STCNNT_BLOCKS_PLUGIN_URL . 'assets/css/editor.css',
array( 'wp-edit-blocks', ),
filemtime( plugin_dir_path( __FILE__ ) . '/assets/css/editor.css' )
);
wp_register_style(
'stcnnt-deneme-blocks-style',
STCNNT_BLOCKS_PLUGIN_URL . 'assets/css/style.css',
array(),
filemtime( plugin_dir_path( __FILE__ ) . '/assets/css/style.css' )
);
register_block_type( 'stcnnt-deneme-blocks/hero-img-block', array(
'api_version' => 2,
'style' => 'stcnnt-deneme-blocks-style', // Hem tema hem de editor tarafında
'editor_style' => 'stcnnt-deneme-blocks-editor-style', // Sadece editor tarafında
'editor_script' => 'stcnnt-deneme-blocks-js', // Sadece editor tarafında
) );
register_block_type( 'stcnnt-deneme-blocks/google-ads-block', array(
'api_version' => 2,
'style' => 'stcnnt-deneme-blocks-style', // Hem tema hem de editor tarafında
'editor_style' => 'stcnnt-deneme-blocks-editor-style', // Sadece editor tarafında
'editor_script' => 'stcnnt-deneme-blocks-editor-js', // Sadece editor tarafında
) );
}
add_action( 'init', 'stcnnt_deneme_blocks_scripts' );
/**
* OLUŞTURACAĞIMIZ BLOCKLAR AYRI BİR KATEGORİDE GÖRÜNSÜN
*/
function stcnnt_block_category( $categories, $post ) {
return array_merge(
$categories,
array(
array(
'slug' => 'stcnnt-deneme-blocks-category',
'title' => __( 'Stcnnt Deneme Blockları', 'deneme_textd' ),
),
)
);
}
add_filter( 'block_categories', 'stcnnt_block_category', 10, 2);
/**
* Bloklar için bağımsız iki adet js dosayası da kenarda dursun
*/
//sadece tema tarafında çalışır.
function stcnnt_enqueue_theme_scripts(){
wp_enqueue_script(
'stcnnt-only-theme-js',
STCNNT_BLOCKS_PLUGIN_URL . 'assets/js/scripts.js',
array('jquery'),
true
);
}
add_action( 'init', 'stcnnt_enqueue_theme_scripts' );
// Sadece editör tarafında çalışır
function stcnnt_enqueue_admin_scripts(){
wp_enqueue_script(
'stcnnt-only-admin-js',
STCNNT_BLOCKS_PLUGIN_URL . 'assets/js/editor.js',
array('jquery'),
true
);
}
add_action( 'admin_enqueue_scripts', 'stcnnt_enqueue_admin_scripts' );
- Artık eklentimiz kullanıma hazırdır ve yönetim panelinde, “Eklentiler” menüsünde yer almaktadır:

Henüz, eklentiyi “Etkinleştir“mek için erken. Bu aşamada çalıştırırsak, uyarı mesajları alabiliriz.
npm İşleri
- Visiual Studio Code editöründe, mümkünse yönetici olarak, eklenti klasörünü açıyoruz.
- Bu klasörde iken, “Terminali” açıyoruz ve komut satırı eklenti dizininde olmalıdır:
PS C:\xampp\htdocs\benimsitem\wp-content\plugins\deneme-blocks> - Bu dizinde iken şu komutu çalıştırıyoruz ve fare imleci tekrar eklenti dizininin sonunda belirene kadar bekliyoruz:
npm init --yes
- Bu koddan sonra, eklenti dizinimize
package.jsonadına bir dosya daha eklenmiş olacak ve dizinin son hali şöyle olacaktır:
// Eklenti klasörü ve dosyaları
|- wp-content (klasör)
|-- plugins (klasör)
|--- deneme-blocks (klasör)
|---- assets (klasör)
|----- js (klasör)
|------ sripts.js (dosya)
|------ editor.js (dosya)
|----- css (klasör)
|------ style.css (dosya)
|------ editor.css (dosya)
|---- src(klasör)
|----- index.js (dosya)
|---- plugin.php (dosya)
|---- package.json (dosya)
- Eklenen
package.jsondosyasının içeriği şöyledir:
package.json
{
"name": "deneme-blocks",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
- Yine aynı dizinde şu komutu çalıştırıyoruz ve uzunca bir süre bekliyoruz:
npm i --save-dev @wordpress/scripts
- Yukarıdaki komuttan sonra, dizinimize “node_modules” adında kocaman bir klasör yüklenir ve eklenti dizinimiz şöyle görünür:
// Eklenti klasörü ve dosyaları
|- wp-content (klasör)
|-- plugins (klasör)
|--- deneme-blocks (klasör)
|---- assets (klasör)
|----- js (klasör)
|------ sripts.js (dosya)
|------ editor.js (dosya)
|----- css (klasör)
|------ style.css (dosya)
|------ editor.css (dosya)
|---- node_modules (klasör)
|---- src(klasör)
|----- index.js (dosya)
|---- plugin.php (dosya)
|---- package.json (dosya)
Artık, bir block geliştirmek için, WordPress’in bütün yardımcı elemanları elimizin altında.
- Bu kodu çalıştırdıktan sonra package.json dosyası şöyle görünmelidir:
{
"name": "deneme-blocks",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@wordpress/scripts": "^16.1.3"
}
}
package.jsondosyasını aşağıdaki şekilde düzenlememiz gerekiyor:
package.json
{
"name": "deneme-blocks",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "wp-scripts start",
"build": "wp-scripts build"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@wordpress/scripts": "^16.1.3"
}
}
- Bu aşamada terminalde aşağıdaki komutu yazıp, enter tuşuna basmalı ve biraz beklemeliyiz:
npm run start
- Her şey yolunda giderse, terminal bize, aşağıdaki gibi bir cevap vermelidir:

- Bu cevap bize diyor ki:
buildadında bir klasör oluşturduk.- Bu klasörün içinde,
index.asset.phpadına bir dosya oluşturduk. - Bu klasörün içinde,
index.jsadında bir dosya daha oluşturduk. - Bu klasörün içinde,
index.js.mapadında bir dosya daha oluşturduk.- İşte bütün bu işleri yapan, webpack adındaki paketleyicidir.
- Biraz önce yüklediğimiz
@wordpress/scriptspaketi, bizim için, gerekli webpack ayarlarını yapmıştır.
buildklasörü, bizim eklentimizin oluştuğu klasördür.- Yani işimiz bitince, eklenti klasörü içinde, bize lazım olacak dosya ve klasörler sadece şu 3 tanesidir.
plugin.phpdosyasıbuildklasörü- assets klasörü
- Bu üçünün dışındaki bütün dosya ve klasörler, block yazmak için bize yadım ederler.
- Kodladığımız eklentiyi alıp giderken, eklenti klasörünün içindeki diğer dosyalara ihtiyacımız olmayacaktır.
- Yani işimiz bitince, eklenti klasörü içinde, bize lazım olacak dosya ve klasörler sadece şu 3 tanesidir.
npm run start Komutu
- Bu komut; editörün bizi devamlı dinlemesini sağlar.
- Bu komut çalıştırıldığında, terminal dinleme moduna geçer.
- Terminal dinleme modunda iken;
- komut kabul etmez
- yaptığımız değişiklerden sonra, bir dosyayı kaydettiğimizde;
buildklasörü yoksa tekrar oluşturulur, varsa üzerine yazılır.
- kodlarımızın otomatik olarak derlenir ve
buildklasörüne taşınır. - derleme işlemi
webpackmarifetiyle yapılır.
- Dinleme modundan tekrar komut satırına geçmek için
Ctrl + Ctuş çiftine birlikte basmamız yeterlidir.
build ve src Klasörleri Nedir?
srcklasörü bizim mutfağımızdır, block ile ilgili bütün kodları burada yazarız.- Block yazarken, web tarayıcıların henüz desteklemediği;
babel, jsx, esnextgibi js uygulamalarını/kütüphanelerini de kullanırız. webpackpaketi;srcklasöründe yazılan kodları, tarayıcıların anlayabildiği şekle getirir vebuildklasöründe paketler.- Bu işlem;
npm run startkomutu ilk defa çalıştırıldığındanpm run startkomutu çalıyor iken, dosyaların her kaydedilişinde (Ctrl + s) gerçekleşir.
- Bu işlem;
buildklasörünü silip, tekrarnpm run startdersek veya bu komut çalıştıktan sonra bir dosyayı kaydedersek,buildklasörü ve içindeki dosyalar, tekrar en güncel haliyle oluştur.srcklasörünün başına bir iş gelmediği müddetçe,buildklasörünü en güncel haliyle oluşturmak tek bir komut kadar kolaydır.
- Bu aşamada, eklenti dizinimiz şöyle görünmelidir:
// Eklenti klasörü ve dosyaları
|- wp-content (klasör)
|-- plugins (klasör)
|--- deneme-blocks (klasör)
|---- assets (klasör)
|----- js (klasör)
|------ sripts.js (dosya)
|------ editor.js (dosya)
|----- css (klasör)
|------ style.css (dosya)
|------ editor.css (dosya)
|---- build (klasör)
|----- index.asset.php (dosya)
|----- index.js (dosya)
|----- index.js.map (dosya)
|---- node_modules (klasör)
|---- src(klasör)
|----- index.js (dosya)
|---- plugin.php (dosya)
|---- package.json (dosya)
- Artık eklentimizi etkinleştirebiliriz. (Yönetim paneli: Eklentiler -> Deneme Blocks -> Etkinleştir)
npm – Block Kodlaması İçin Gerekli Scriptleri Yükleme
npm run startkomutundan sonra, terminal bizi dinleme moduna geçmiştir.- Terminal dinleme modunda iken, bir dosyada bir değişiklik yaparsak bunu algılar ve dosyanın en güncel haliyle tekrar derlenmesini sağlar.
- Terminali, dinleme modundan çıkarıp tekrar bir komut girebilmek için, öncelikte, fare terminalde iken:
Ctrl + C
ikilisine basmamız gerekiyor.
- Bu tuşlardan sonra karşımıza şöyle bir soru çıkacaktır:
Terminate batch job (Y/N)?
- Bu soruyu, “Y” ve enter tuşlarına basarak cevaplıyoruz.
- Bu işlemlerden sonra, terminal, dinleme modundan çıkacak ve komut satırı tekrar aktif olacaktır.
- Komut satırı eklentinin kök dizininde iken, aşağıdaki komutu girerek, scriptin yüklenmesini bekleyelim (İşlem biraz uzun sürebilir.):
npm install @wordpress/blocks --save
- Block kodlamaya geçemeden önce, kodlama esnasında ihtiyacımız olacak bazı paketleri yükleyelim.
- Bunun için, eklentinin kök dizininde iken, aşağıdaki işlemleri yapalım:
- Aşağıdaki komutu girerek, scriptin yüklenmesini bekleyelim:
npm install @wordpress/i18n --save
- Aşağıdaki komutu girerek, scriptin yüklenmesini bekleyelim:
npm install @wordpress/element --save
- Aşağıdaki komutu girerek, scriptin yüklenmesini bekleyelim:
npm install @wordpress/block-editor --save
- Aşağıdaki komutu girerek, scriptin yüklenmesini bekleyelim:
npm install @wordpress/components --save
Birden Çok Bloğu Tek Eklentide Kodlama
- Amacımız bir tane block kodlamak ise;
src/index.jsdosyası yeterlidir.
- Birden fazla block kodlamak istiyorsak:
src/block-1/index.jssrc/block-2/index.js- …
şeklinde, alt klasörler ile dilediğimiz kadar block oluşturabiliriz.
- Biz, iki tane block kodlayacağız. Bu blockların isimleri şöyle olacak:
- hero-img-block:

- google-ads-block
- hero-img-block:
- Bu iki bloğu kodlamak için, eklenti dizininde,
srcklasörüne şu iki klasör ve dosyayı ekliyoruz:hero-img-block(klasör)block.js(dosya)
google-ads-block(klasör)block.js(dosya)
- Bu aşamadan sonra, eklenti dizinimiz şöyle görünecektir:
// Eklenti klasörü ve dosyaları
|- wp-content (klasör)
|-- plugins (klasör)
|--- deneme-blocks (klasör)
|---- assets (klasör)
|----- js (klasör)
|------ sripts.js (dosya)
|------ editor.js (dosya)
|----- css (klasör)
|------ style.css (dosya)
|------ editor.css (dosya)
|---- build (klasör)
|----- index.asset.php (dosya)
|----- index.js (dosya)
|----- index.js.map (dosya)
|---- node_modules (klasör)
|---- src(klasör)
|----- hero-img-block (klasör)
|------ block.js (dosya)
|----- google-ads-block (klasör)
|------ block.js (dosya)
|----- index.js (dosya)
|---- plugin.php (dosya)
|---- package.json (dosya)
- Eklediğimiz blockları,
src/index.jsdosyasına tanıtalım:
src/index.js
import './hero-img-block/block.js';
import './google-ads-block/block.js';
Temel Block Kodları
- İki tane block kodlayacağımızı belirtmiştik.
- Önce hero-img-block adını verdiğimiz block üzerinden, bir block nasıl kodlanır görelim:
Örnek Bir Block: hero-img-block
- Bizim hazırladığımız eklenti dizininde
hero-img-blockbloğunun temel dosyasıhero-img-block/block.jsdosyasıdır. - Bir WordPress Gutenberg Editörü bloğu, ana hatları ile şu şablona göre kodlanır:
hero-img-block/block.js
import { registerBlockType } from '@wordpress/blocks';
registerBlockType( 'stcnnt-deneme-blocks/hero-img-block', {
apiVersion: 2,
title: '',
icon: '',
category: '',
attributes: {},
example: {},
edit: ( props ) => {
return (
<p>Burası sadece editör sayfasında görünür.</p>
);
},
save: ( props ) => {
return (
<p>Burası sadece temada görünür.</p>
);
},
} );
Block Şablonundaki Kodların Anlamları:
import { registerBlockType } from '@wordpress/blocks';
- Yukarıdaki kod, bir block kaydetmek için gerekli olan
registerBlockTypefonksiyonunu çağırır. - Block ile ilgili bütün kodlar bu fonksiyonun parametreleridir.
registerBlockType( 'blok-kimliği', {block argümanları})
- Yukarıdaki fonksiyon, bir bloğun bütün kodlarının barındığı fonksiyondur.
- Fonksiyonun 2 parametresi vardır:
- Parametre: Block Kimliği
- Bloğun veritabanına kaydedilecek ismidir.
- Bu isim,
plugin.phpdosaysında,register_block_type()fonksiyonunun birinci parametresi ile aynı olmalıdır.- Örnek-1:
'benim-super-blocklarim/super-bir-block' - Örnek-2:
'benim-super-blocklarim/super-başka-bir-block'
- Örnek-1:
- Parametre: Block Argümanları
- Bir javascript nesnesidir.
- Bloğun adı, kategorisi, ikonu, örnek görünümü, editör görünümü, tema görünümü…. gibi bütün özellikleri bu parametrede belirlenir.
- Block argümanları şunlardır:
title: (string) Bloğun adıdır. Block, editörde bu ad ile karşımıza çıkar.- Örnek:
title: __( 'Book' )
- Örnek:
description: (string) Bloğun tanımıdır. Zorunlu değildir.- Örnek:
description: __( 'Block showing a Book card.' );
- Örnek:
category: (string) Bloğun, diğer blocklar için kullanılan kategorilerden hangisinde gösterileceğini belirtir.- Örnek:
category: 'widgets', - WordPress’in block kategorileri:
textcommonformattinglayoutmediadesignwidgetsthemeembed
- Örnek:
icon: (string|object) Bloğun ikonudur. Zorunlu değildir.- Örnek-1:
icon: 'book-alt', - Örnek-2:
icon: <svgviewBox="0 0 24 24"xmlns="http://www.w3.org/2000/svg"><path fill="none"d="M0 0h24v24H0V0z"/><path d="M19 13H5v-2h14v2z"/></svg> - Örnek-3:
icon: {background: '#7e70af',foreground: '#fff',src: <svg viewBox="0 0 24 24"xmlns="http://www.w3.org/2000/svg"><path fill="none"d="M0 0h24v24H0V0z"/><path d="M19 13H5v-2h14v2z"/></svg>,} , - Kullanabileceğiniz bütün WordPress’in dashiconları (seçtiğiniz ikonun isminin önündeki
dashicon-ifadesini kullanmayın.)
- Örnek-1:
attributes: (object) Block için yapacağımız ayarlarda kullanacağımız değişkenlerdir.- Örnek:
attributes: {cover: {type: 'string', source: 'attribute', selector: 'img', attribute: 'src',},author: {type: 'string',source: 'html',selector: '.book-author',},pages: {type: 'number',},},
- Örnek:
example: (object) Block için varsayılan bir görünüm oluşturmak için, kullanılır. Editörde, bloğu seçmeden önce, fareyi üzerinde bekletirsek, burada verdiğimiz değerlere göre bir örnek görünüm oluşur.- Örnek:
example: {
attributes: {
cover: 'https://example.com/image.jpg',
author: 'William Shakespeare',
pages: 500
},},
- Örnek:
edit: Bloğun, editör görünümüne ait html yapısını döndüren bir fonksiyondur. Block için kullanacağımız bütün ayarlar, form elemanları bu fonksiyonun içinde döndürülür.- Fonksiyonun bir tane parametresi vardır ve genellikle
propsadıyla çağırılır. - Bu parametre,
attributesnesnesinde tanımladığımız değişkenler de dahil bir çok gerekli elemana sahiptir.
- Fonksiyonun bir tane parametresi vardır ve genellikle
save: Bloğun, tema görünümüne ait html yapısını döndüren bir fonksiyondur.- Fonksiyonun bir tane parametresi vardır ve genellikle
propsadıyla çağırılır. - Bu parametre,
attributesnesnesinde tanımladığımız değişkenler de dahil bir çok gerekli elemana sahiptir.
- Fonksiyonun bir tane parametresi vardır ve genellikle
- Parametre: Block Kimliği
Hazırlıklar Bitti, Artık Bloğu Kodlayalım

registerBlockTypefonksiyonuna gerekli bilgileri girerek, yukarıdaki gibi görünecek olan, ilk bloğumuzu oluşturalım:
hero-img-block/block.js
import { registerBlockType } from '@wordpress/blocks';
import { __ } from '@wordpress/i18n';
import {
useBlockProps,
RichText,
AlignmentToolbar,
BlockControls,
InspectorControls,
ColorPalette,
MediaUpload,
} from '@wordpress/block-editor';
import { Panel, PanelBody, PanelRow, Button, ToggleControl, SelectControl } from '@wordpress/components';
import { __experimentalNumberControl as NumberControl } from '@wordpress/components';
import { image } from '@wordpress/icons';
registerBlockType( 'stcnnt-deneme-blocks/hero-img-block', {
apiVersion: 2,
title: 'SC Hero Resmi',
icon: 'format-image', //dashicons-format-image
category: 'stcnnt-deneme-blocks-category',
attributes: {
useContent: {
type: 'boolean',
default: true,
},
content: {
type: 'array',
source: 'children',
selector: 'p',
},
alignment: {
type: 'string',
default: 'none',
},
useOverlay: {
type: 'boolean',
default: true,
},
overlayColor: {
type: 'string',
default: null // varsayılan bir renk yok
},
overlayColorAlpha: {
type: 'string',
default: '40'
},
fontColor: {
type: 'string',
default: '#ffffff'
},
fontTag: {
type: 'string',
default: 'p'
},
useFontBg: {
type: 'boolean',
default: true,
},
backgroundImage: {
type: 'string',
default: null, // isterseniz varsayılan bir resim atayabilirsiniz
}
},
example: {
attributes: {
content: __('Herkese Merhaba :)', 'deneme_textd'),
alignment: 'right',
},
},
edit: ( { attributes, setAttributes } ) => {
const onChangeContent = ( newContent ) => {
setAttributes( { content: newContent } );
};
const onChangeAlignment = ( newAlignment ) => {
setAttributes( {
alignment: newAlignment === undefined ? 'none' : newAlignment,
} );
};
const onImageSelect = ( imageObject ) => {
setAttributes( {
backgroundImage: imageObject.sizes.full.url
} );
};
const onOverlayColorChange = ( changes ) => {
setAttributes( {
overlayColor: changes
} );
};
const onTextColorChange = ( changes ) => {
setAttributes( {
fontColor: changes
} );
};
const resmiKaldir = () => {
setAttributes( {
backgroundImage: null
} );
}
const useOverlaySelection = (val) => {
setAttributes( {useOverlay: val} );
}
const useContentSelection = (val) => {
setAttributes( {useContent: val} );
}
const useFontBgSelection = (val) => {
setAttributes( {useFontBg: val} );
}
const overlayColorAlphaChange = (val) => {
setAttributes( {overlayColorAlpha: val} );
}
const scSettingsSection = (attributes) => (
<Panel header="">
<PanelBody title="Resim Ayarları" className="wp-block-stcnnt-deneme-blocks-hero-setting" initialOpen={ true }>
<PanelRow className="wp-block-stcnnt-deneme-blocks-hero-img-container">
{attributes.backgroundImage != null ?
<img className="sc-hero-img" src={attributes.backgroundImage} />
:
<p className="sc-hero-img-placeholder">{__('Resim yüklenmedi.', 'deneme_textd')}</p>
}
</PanelRow>
<PanelRow>
<div>
<MediaUpload
onSelect={ onImageSelect }
type="image"
value={attributes.backgroundImage} // make sure you destructured backgroundImage from props.attributes!
render={({ open }) => (
<Button
variant="primary"
icon= {image}
onClick={open}>
{attributes.backgroundImage != null ? __('Değiştir', 'deneme_textd') : __('Resim yükle', 'deneme_textd')}
</Button>
)}
/>
{attributes.backgroundImage != null ?
<Button
variant="primary"
icon= {image}
onClick={resmiKaldir}
className="sc-resmi-kaldir"
>{__('Kaldır', 'deneme_textd')}</Button>
: null
}
</div>
</PanelRow>
<hr />
<PanelRow>
<ToggleControl
label= {__('Overlay kullan', 'deneme_textd')}
help= {__('Resmin üzerinde yarı şeffaf bir tabaka oluşturmak için kullanılır.', 'deneme_textd')}
checked={ attributes.useOverlay }
onChange={ useOverlaySelection }
/>
</PanelRow>
<PanelRow>
<ToggleControl
label= {__('Metin kullan', 'deneme_textd')}
help= {__('Resmin üzerine kısa bir açıklama yazmak için kullanılır.', 'deneme_textd')}
checked={ attributes.useContent }
onChange={ useContentSelection }
/>
</PanelRow>
<PanelRow>
<SelectControl
label="Metnin HTML etiketi:"
value={ attributes.fontTag }
options={ [
{ label: 'p', value: 'p' },
{ label: 'h1', value: 'h1' },
{ label: 'h2', value: 'h2' },
{ label: 'h3', value: 'h3' },
{ label: 'h4', value: 'h4' },
{ label: 'h5', value: 'h5' },
{ label: 'h6', value: 'h6' },
{ label: 'div', value: 'div' },
{ label: 'span', value: 'span' },
] }
onChange={ ( val ) => {
setAttributes( { fontTag: val } );
} }
/>
</PanelRow>
<PanelRow>
<ToggleControl
label= {__('Metin için arkplan kullan:', 'deneme_textd')}
help= {__('Resmin metni için arkplan oluşturur.', 'deneme_textd')}
checked={ attributes.useFontBg }
onChange={ useFontBgSelection }
/>
</PanelRow>
</PanelBody>
<PanelBody title={__('Renkler', 'deneme_textd')} initialOpen={ false }>
<PanelRow>
<div>
<label className="sc-setting-section-label">{__('Overlay rengi:', 'deneme_textd')}</label>
<ColorPalette
value={attributes.overlayColor}
onChange={onOverlayColorChange}
/>
</div>
</PanelRow>
<PanelRow>
<label>{__('Şeffaflık değeri:', 'deneme_textd')}</label>
<NumberControl
onChange={ overlayColorAlphaChange }
value={ attributes.overlayColorAlpha }
/>
</PanelRow>
<hr />
<PanelRow>
<div>
<label className="sc-setting-section-label">{__('Metin rengi:', 'deneme_textd')}</label>
<ColorPalette
value={attributes.fontColor}
onChange={onTextColorChange}
/>
</div>
</PanelRow>
</PanelBody>
</Panel>
);
const textBg = attributes.useFontBg ? ' sc-text-bg' : '';
return (
[
<InspectorControls>
{scSettingsSection(attributes)}
</InspectorControls>,
<div
{ ...useBlockProps() }
style={{
backgroundImage: `url(${attributes.backgroundImage})`,
backgroundSize: 'cover',
backgroundPosition: 'center',
height: '300px',
}}>
{
<BlockControls>
<AlignmentToolbar
value={ attributes.alignment }
onChange={ onChangeAlignment }
/>
</BlockControls>
}
{attributes.useContent ?
<div className={`sc-hero-text-container ${textBg}`}
style={{
color: attributes.fontColor,
textAlign: attributes.alignment,
}}
>
<RichText
className={ attributes.className }
tagName= {attributes.fontTag}
onChange={ onChangeContent }
value={ attributes.content }
placeholder={__('Resim metni...', 'deneme_textd')}
/>
</div>
: null
}
{attributes.useOverlay ?
<div
className="sc-hero-img-overlay"
style={{
backgroundColor: attributes.overlayColor,
opacity: attributes.overlayColorAlpha/100,
}}
></div>
: null
}
</div>
]
);
},
save: ( { attributes } ) => {
const blockProps = useBlockProps.save();
const textBg = attributes.useFontBg ? ' sc-text-bg' : '';
return (
<div { ...blockProps }
style={{
backgroundImage: `url(${attributes.backgroundImage})`,
backgroundSize: 'cover',
backgroundPosition: 'center',
height: '300px',
}}
>
{(attributes.content.length != 0 && attributes.useContent) ?
<div
className={ `sc-hero-text-container align-${ attributes.alignment } ${textBg}` }
style={{
color: `${attributes.fontColor} !important`,
}}
>
<RichText.Content
tagName={attributes.fontTag}
value={ attributes.content }
className='sc-hero-text'
/>
</div>
: null
}
{attributes.useOverlay ?
<div
className="sc-hero-img-overlay"
style={{
backgroundColor: attributes.overlayColor,
opacity: attributes.overlayColorAlpha/100,
}}
></div>
: null
}
</div>
);
},
} );
- Yukarıdaki kodları kaydettikten sonra, dinleme modunda değilse, terminalde şu komutu çalıştırıyoruz:
npm run start
- Artık, kendimize ait bir bloğumuz var.
- Yönetim panelinden, block editörü açıp, bloklar içinde ‘SC Hero Resmi‘ araması yaparsak, oluşturduğumuz block karşımıza çıkacaktır.

block.jsdeki kodların bir kısmı da, block ayarlarına aittir. Bu kodlar ile şu ayarlar oluşturulmuştur:


- Bloğun editör görünümü için biraz CSS yaptık:
assets/css/editor.css
.interface-complementary-area {
width: auto !important;
max-width: 280px !important;
overflow-x: hidden !important;
}
.wp-block-stcnnt-deneme-blocks-hero-img-block .sc-hero-text-container
{
z-index: 2;
height: 35px;
min-width: 100px;
display: table;
margin:0 auto;
}
.wp-block-stcnnt-deneme-blocks-hero-img-block .sc-hero-text-container p
{
margin-top: 0 !important;
margin-bottom: 0 !important;
}
label.sc-setting-section-label
{
padding-bottom: 15px;
}
.sc-hero-img-placeholder
{
width: 80%;
position: relative;
margin: 10px auto;
background-color: rgb(226, 226, 226);
height: 90px;
display: flex;
justify-content: center;
align-items: center;
}
.css-1wgusda-Text-BaseLabel.css-1wgusda-Text-BaseLabel.css-1wgusda-Text-BaseLabel
{
text-overflow: inherit !important;
}
- Tema tarafı için de biraz CSS yapalım:
assets/css/style.css
.wp-block-stcnnt-deneme-blocks-hero-img-block
{
position: relative;
border: 9px solid rgba(0, 0, 0, .5);
display: flex;
justify-content: center;
align-items: center;
border-radius: 20px;
}
.wp-block-stcnnt-deneme-blocks-hero-img-block .sc-hero-img-overlay
{
position:absolute;
width: 100%;
height: 100%;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.wp-block-stcnnt-deneme-blocks-hero-img-block .sc-hero-text-container
{
font-size: 4.5rem;
padding: 15px;
border-radius: 20px;
z-index: 2;
display: flex;
justify-content: center;
align-items: center;
}
.sc-text-bg {
border: 3px solid rgba(156, 150, 150, 0.5);
background-color: rgba(0, 0, 0, .5);
}
.sc-hero-text
{
color: inherit !important;
font-size: inherit !important;
margin: 0 !important;
padding: 0 !important;
}
.align-left
{
text-align: left;
}
.align-right
{
text-align: right;
}
.align-center
{
text-align: center;
}
SC Hero Resmi Bloğu İle Örnek Tasarımlar
Yeteneklerini görmek için, oluşturduğumuz blockla neler yapabiliriz bir bakalım:
- Overlay kullanmadan bir resim ve metin örneği:

- Resmin üzerine overlay efekti verdik:

- Resimsiz olarak, 100 şeffaflıkta bir overlay kullanarak, metin backgroundu olmayan tasarımlar da mümkün:
