editor.php é um pacote projetado para auxiliar na análise e manipulação da saída do Editor.js com facilidade. Ele pode ser usado com PHP vanilla ou com Larave. Laravel oferece alguns recursos adicionais.
editor.php | Laravel | PHP |
---|---|---|
1.x | 10.x ~ 11.x | 8,1 ~ 8,3 |
Instale o pacote por:
composer require bumpcore/ editor.php
editor.php é muito simples de começar;
use BumpCore EditorPhp EditorPhp ;
// Passing Editor.js's output directly to the `make`.
// This will render blocks into html.
echo EditorPhp:: make ( $ json )-> render ();
editor.php suporta os seguintes blocos;
Todos eles têm regras de validação padrão e visualizações para renderizar. No entanto, a personalização da validação e das visualizações é altamente recomendada.
A classe EditorPhp
é a classe principal para gerenciamento de blocos. Você pode acessar, renderizar, converter em um array e converter em JSON por meio desta classe.
Existem duas maneiras de criar uma nova instância do EditorPhp:
use BumpCore EditorPhp EditorPhp ;
// Using the `new` syntax.
$ editor = new EditorPhp ( $ json );
// Using the `make` syntax.
$ editor = EditorPhp:: make ( $ json );
Ambas as sintaxes são iguais e quase não há diferença entre elas.
Você pode acessar os blocos através da propriedade de blocos.
use BumpCore EditorPhp EditorPhp ;
use BumpCore EditorPhp Block Block ;
use BumpCore EditorPhp Blocks Paragraph ;
$ editor = EditorPhp:: make ( $ json );
// Stripping all tags from paragraph block's text.
$ editor -> blocks -> transform ( function ( Block $ block )
{
if ( $ block instanceof Paragraph)
{
$ block -> set ( ' text ' , strip_tags ( $ block -> get ( ' text ' )));
}
return $ block ;
});
Os blocos são armazenados como IlluminateSupportCollection
. Usando métodos de coleta, você pode manipular os blocos como desejar. Você pode aprender sobre coleções na documentação do Laravel.
Renderizar HTML é muito simples. Existem várias maneiras de renderizar sua instância:
use BumpCore EditorPhp EditorPhp ;
$ editor = EditorPhp:: make ( $ json );
// Using the `render` function.
echo $ editor -> render ();
// Using the `toHtml` function.
echo $ editor -> toHtml ();
// Or by casting to a string.
echo $ editor ;
Novamente, todos os três casos são iguais, sem nenhum acima do outro. Você pode usar o que mais gostar.
Por padrão, você tem duas opções para os modelos de bloco padrão; tailwindcss
e Bootstrap 5
. O modelo padrão usado é tailwindcss
Você pode alternar os modelos:
use BumpCore EditorPhp EditorPhp ;
// Using tailwind.
EditorPhp:: useTailwind ();
// Using Bootstrap.
EditorPhp:: useBootstrapFive ();
Você pode aprender mais sobre renderização na seção de criação de blocos personalizados.
Você pode gerar dados falsos com EditorPhp
.
use BumpCore EditorPhp EditorPhp ;
// This will return a generated fake JSON.
$ fake = EditorPhp:: fake ();
// If we pass first argument true, it will return new `EditorPhp` instance with fake data.
$ fakeEditor = EditorPhp:: fake ( true );
// You can also pass min lenght and max lenght of blocks.
// Below code will generate blocks between 1 and 3.
$ fakeEditor = EditorPhp:: fake ( true , 1 , 3 );
echo $ fakeEditor -> render ();
Você pode aprender mais sobre como gerar dados falsos para os blocos na geração de dados falsos.
Você pode converter sua instância em um array usando o método toArray()
.
use BumpCore EditorPhp EditorPhp ;
$ editor = EditorPhp:: make ( $ json );
// This will return ['time' => ..., 'blocks' => [...], 'version' => '...']
$ array = $ editor -> toArray ();
Você pode converter sua instância em JSON usando o método toJson(/** options */)
. Este método é útil quando você manipula sua instância.
use BumpCore EditorPhp EditorPhp ;
$ editor = EditorPhp:: make ( $ json );
// This will return encoded JSON.
$ json = $ editor -> toJson ( JSON_PRETTY_PRINT );
Você pode acessar a hora e a versão:
use BumpCore EditorPhp EditorPhp ;
$ editor = EditorPhp:: make ( $ json );
$ editor -> time ;
$ editor -> version ;
A propriedade time
é uma instância Carbon
. Você pode aprender mais sobre isso na documentação do Carbon.
Você pode registrar macros e usá-las posteriormente. As macros são baseadas no Laravel.
use BumpCore EditorPhp EditorPhp ;
// Registering new macro.
EditorPhp:: macro (
' getParagraphs ' ,
fn () => $ this -> blocks -> filter ( fn ( Block $ block ) => $ block instanceof Paragraph)
);
$ editor = EditorPhp:: make ( $ json );
// This will return a collection that only contains paragraphs.
$ paragraphs = $ editor -> getParagraphs ();
Os blocos são as principais partes de construção do editor EditorPhp
. Você pode manipulá-los como quiser, e a melhor parte é que você pode usá-los para armazenar a lógica do seu bloco. Por exemplo, o bloco de imagem requer um uploader para funcionar. Você pode implementar a funcionalidade correspondente na classe BumpCoreEditorPhpBlocksImage
.
Antes de começarmos a aprender como personalizar blocos, veja como você pode registrá-los:
use BumpCore EditorPhp EditorPhp ;
// This will merge without erasing already registered blocks. Other blocks will still remain with the recently registered `image` and `paragraph` blocks.
EditorPhp:: register ([
' image ' => Blocks MyCustomImageBlock::class,
' paragraph ' => Blocks MyCustomParagraphBlock::class,
]);
// This will override already registered blocks. We now only have `image` and `paragraph` blocks.
EditorPhp:: register ([
' image ' => Blocks MyCustomImageBlock::class,
' paragraph ' => Blocks MyCustomParagraphBlock::class,
], true );
Ao registrar blocos, é importante usar a chave correta. A chave deve ser igual à chave type
do Editor.js
. Para esclarecer:
{
"time" : 1672852569662 ,
"blocks" : [
{
"type" : " paragraph " ,
"data" : {
"text" : " ... "
}
}
],
"version" : " 2.26.4 "
}
Nesta saída, nossa chave de tipo é paragraph
, então devemos registrá-la como 'paragraph' => Paragraph::class
. Isso pode variar dependendo de como você registra seus blocos em Editor.js
. Os blocos padrão no EditorPhp
são registrados usando camelCase
.
Conforme mencionado anteriormente, quase todos os blocos são suportados no EditorPhp
. No entanto, eles lidam principalmente com a validação de dados de bloco e renderização. Para que o bloco Image
funcione corretamente, é necessário um upload. Podemos implementar esta lógica de upload na classe Image
:
use BumpCore EditorPhp Blocks Image ;
class MyImageBlock extends Image
{
public static function uploadTemp ( string $ fileName = ' image ' ): array
{
// ...
// Temporary upload logic.
return [
' success ' => . . . ,
' file ' => [
' url ' => . . . ,
],
];
}
public function upload (): void
{
$ file = $ this -> get ( ' file.url ' );
// Your logic.
// ...
// Altering the current block's data.
$ this -> set ( ' file.url ' , ...);
}
}
// ...
// Registering customized block.
EditorPhp:: register ([
' image ' => MyImageBlock::class
]);
Como você pode ver, estendemos o bloco Image
e adicionamos duas funções para lidar com nossos uploads.
A função uploadTemp
executa um upload de arquivo temporário. Este método é estático e pode ser usado em qualquer lugar usando Image::uploadTemp()
. Ele retorna os dados exigidos pela ferramenta de imagem.
A função upload
tem uma finalidade diferente. Representa o upload final do bloco, mas não é estático. Este método assume que a imagem já foi carregada temporariamente e o $json
foi carregado e analisado. Portanto, podemos usar esta função da seguinte forma:
use BumpCore EditorPhp EditorPhp ;
use Blocks MyImageBlock ;
$ editor = EditorPhp:: make ( $ json );
$ editor -> blocks -> each ( function ( Block $ block )
{
if ( $ block instanceof MyImageBlock)
{
$ block -> upload ();
}
});
return $ editor -> toJson ();
Agora o bloco realiza o upload final e é salvo como JSON.
É impossível suportar todos os blocos existentes, então podemos implementar nossos próprios blocos de maneira fácil. Um bloco padrão se parece com o seguinte:
use BumpCore EditorPhp Block Block ;
class MyCustomBlock extends Block
{
public function render (): string
{
return view ( ' blocks.my-custom-block ' , [ ' data ' => $ this -> data ]);
}
}
Como você pode ver, por padrão, só precisamos implementar a lógica de renderização. No entanto, há mais do que apenas renderização.
Existem várias maneiras de acessar os dados de um bloco. No exemplo abaixo, você pode ver diferentes métodos para acessar dados de bloco:
public function render (): string
{
// ...
// Method 1: Accessing through the data object.
$ data = $ this -> data ;
$ data -> get ( ' custom.data ' );
$ data -> set ( ' custom.data ' , ' Hello World! ' );
// Method 2: Accessing by invoking the data object.
$ data ( ' custom.data ' ); // Hello World!
// Method 3: Using shortcuts.
$ this -> get ( ' custom.data ' );
$ this -> set ( ' custom.data ' , ' Nice! ' );
// ...
}
Você pode escolher qualquer um dos métodos acima para acessar e manipular os dados do bloco. Além disso, você também pode verificar se os dados existem ou não usando os seguintes métodos:
$ data -> has ( ' custom.data ' );
// or
$ this -> has ( ' custom.data ' );
A validação de dados não é obrigatória, mas pode torná-los mais seguros. Validar dados de bloco é bastante fácil. Só precisamos adicionar um método rules
ao nosso bloco:
use BumpCore EditorPhp Block Block ;
class MyCustomBlock extends Block
{
// ...
public function rules (): array
{
return [
' text ' => ' required|string|max:255 ' ,
' items ' => ' sometimes|array ' ,
' items.*.name ' => ' required|string|max:255 ' ,
' items.*.html ' => ' required|string|min:255 ' ,
];
}
// ...
}
Quando a validação dos dados do bloco falhar, os dados ficarão vazios. A validação de dados é realizada usando a biblioteca de validação do Laravel. Você pode aprender mais sobre isso na documentação do Laravel.
Você pode purificar o HTML dos seus dados, se desejar. É importante prevenir injeções. A purificação de dados se parece muito com a validação:
use BumpCore EditorPhp Block Block ;
class MyCustomBlock extends Block
{
// ...
public function allow (): array | string
{
// Specifying one by one.
return [
' text ' => [
' a:href,target,title ' , // Will allow `a` tag and href, target, and title attributes.
' b ' , // Will only allow `b` tag with no attributes.
],
' items.*.name ' => ' b:* ' , // Will allow `b` tag with all attributes.
' items.*.html ' => ' * ' , // Will allow every tag and every attribute.
];
// Or just allowing all attributes and tags for all data.
return ' * ' ;
}
// ...
}
Ao contrário da validação, a purificação removerá apenas tags e atributos indesejados.
Como mencionamos anteriormente, podemos gerar dados falsos com EditorPhp
. Mas é necessário gerar os próprios dados falsos de cada bloco. Para gerar dados falsos devemos adicionar um método estático ao nosso bloco:
use BumpCore EditorPhp Block Block ;
class MyCustomBlock extends Block
{
// ...
public static function fake ( Faker Generator $ faker ): array
{
$ items = [];
foreach ( range ( 0 , $ faker -> numberBetween ( 0 , 10 )) as $ index )
{
$ items [] = [
' name ' => fake ()-> name (),
' html ' => $ faker -> randomHtml (),
];
}
return [
' text ' => fake ()-> text ( 255 ),
' items ' => $ items ,
];
}
// ...
}
Ao adicionar o método fake
ao nosso bloco, agora EditorPhp
também incluirá MyCustomBlock
ao gerar dados falsos. Você pode aprender mais na documentação do FakerPHP.
Existem alguns recursos do Laravel que tornarão sua vida um pouco mais fácil.
Você pode usar EditorPhpCast
para converter o atributo do seu modelo para a instância EditorPhp
.
use BumpCore EditorPhp Casts EditorPhpCast ;
use Illuminate Database Eloquent Model ;
class Post extends Model
{
protected $ casts = [
' content ' => EditorPhpCast::class,
];
}
// ...
$ post = Post:: find ( 1 );
// Content is `EditorPhp` instance in here.
echo $ post -> content -> render ();
Além disso, se você estiver usando cast, poderá acessar seu modelo em instâncias de bloco:
use BumpCore EditorPhp Block Block ;
use App Models Post ;
class MyBlock extends Block
{
// ...
public static function render (): string
{
if ( $ this -> root -> model instanceof Post)
{
// Do the other thing.
}
}
// ...
}
Você também pode alterar o modelo do bloco.
A instância EditorPhp
pode ser retornada como resposta. Se a solicitação espera JSON, ela se codificará em JSON. Caso contrário, será renderizado em HTML.
namespace App Http Controllers ;
use App Http Controllers Controller ;
use App Models Post ;
class ShowPostController extends Controller
{
public function __invoke ( Post $ post )
{
// Depending on the request it will return json or rendered html.
return $ post -> content ;
}
}
Você também pode usar a instância EditorPhp
para renderizar a visualização interna diretamente:
{{-- blog.show.blade.php --}}
< article >
< h1 > {{ $post -> title } } </ h1 >
< div > {{ $post -> content } } </ div >
</ article >
Tenho que verificar isso antes de documentar.
Você pode criar um novo bloco com o comando block:make <name>
:
php artisan make:block CustomImageBlock
O novo bloco será colocado no diretório app/Blocks
.
Contribuições são bem-vindas! Se você encontrar um bug ou tiver uma sugestão de melhoria, abra um problema ou crie uma solicitação pull. Abaixo estão algumas diretrizes a serem seguidas:
Forneça uma descrição detalhada de suas alterações e do problema que elas resolvem. Sua contribuição será analisada e feedback poderá ser fornecido. Obrigado por sua ajuda para tornar este projeto melhor!