1. Go to this page and download the library: Download rjp2525/laravel-tiptap library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
rjp2525 / laravel-tiptap example snippets
return [
/*
|--------------------------------------------------------------------------
| Default Extensions
|--------------------------------------------------------------------------
|
| Default extensions to be loaded when creating a new Tiptap instance.
| Available extensions: StarterKit, Color, FontFamily, TextAlign
|
*/
'extensions' => [
// Use StarterKit for basic functionality
\Tiptap\Extensions\StarterKit::class => [],
// Additional extensions (uncomment as needed)
// \Tiptap\Extensions\Color::class => [],
// \Tiptap\Extensions\FontFamily::class => [],
// \Tiptap\Extensions\TextAlign::class => [],
],
/*
|--------------------------------------------------------------------------
| Cache Configuration
|--------------------------------------------------------------------------
|
| Configure caching for parsed content to improve performance.
|
*/
'cache' => [
'enabled' => env('TIPTAP_CACHE_ENABLED', true),
'store' => env('TIPTAP_CACHE_STORE', null), // null uses default cache store
'ttl' => env('TIPTAP_CACHE_TTL', 3600), // 1 hour
'prefix' => 'tiptap',
],
/*
|--------------------------------------------------------------------------
| Validation Rules
|--------------------------------------------------------------------------
|
| Default validation rules for content validation
|
*/
'validation' => [
'max_length' => 50000,
'max_depth' => 10,
'allowed_tags' => null, // null means all configured extensions are allowed
],
];
// In your .env file
TIPTAP_CACHE_ENABLED=true
TIPTAP_CACHE_TTL=3600
TIPTAP_CACHE_STORE=redis
// Or disable caching for specific operations
$result = Tiptap::make()
->content($content)
->withoutCache()
->toHtml();
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use RJP\Tiptap\Facades\Tiptap;
class CreateArticleRequest extends FormRequest
{
public function rules(): array
{
return [
'title' => ['oo deeply nested.');
}
}],
];
}
}
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Casts\Attribute;
use RJP\Tiptap\Facades\Tiptap;
class Article extends Model
{
protected $fillable = ['title', 'content'];
protected $casts = ['content' => 'array'];
// Automatically generate HTML from JSON content
protected function contentHtml(): Attribute
{
return Attribute::make(
get: fn () => Tiptap::parseJson($this->content),
);
}
// Get content statistics
protected function contentStats(): Attribute
{
return Attribute::make(
get: fn () => collect(Tiptap::getStats($this->content)),
);
}
// Get plain text version
protected function contentText(): Attribute
{
return Attribute::make(
get: fn () => Tiptap::toText($this->content),
);
}
// Sanitize content before saving
protected static function boot()
{
parent::boot();
static::saving(function ($article) {
if ($article->isDirty('content')) {
$article->content = Tiptap::make()
->content($article->content)
->validateOrFail()
->sanitize()
->raw();
}
});
}
}
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use RJP\Tiptap\Facades\Tiptap;
use App\Models\Article;
class ProcessArticleContentJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct(
private int $articleId,
private array $content
) {}
public function handle(): void
{
$processed = Tiptap::make()
->content($this->content)
->starterKit()
->color()
->textAlign()
->maxLength(100000)
->sanitize()
->raw();
$stats = Tiptap::make()
->content($processed)
->stats();
Article::where('id', $this->articleId)->update([
'content' => $processed,
'content_html' => Tiptap::parseJson($processed),
'content_text' => Tiptap::toText($processed),
'word_count' => $stats['words'],
'character_count' => $stats['characters'],
'reading_time' => $stats['reading_time'],
'paragraph_count' => $stats['paragraphs'],
'processed_at' => now(),
]);
}
}
namespace App\View\Components;
use Illuminate\View\Component;
use RJP\Tiptap\Facades\Tiptap;
class TiptapContent extends Component
{
public function __construct(
public array|string $content,
public bool $showStats = false,
public bool $sanitize = true,
) {}
public function render()
{
$builder = Tiptap::make()->content($this->content);
if ($this->sanitize) {
$builder->sanitize();
}
$html = is_array($this->content)
? $builder->toHtml()
: $this->content;
$stats = $this->showStats
? $builder->stats()
: null;
return view('components.tiptap-content', [
'html' => $html,
'stats' => $stats,
]);
}
}
// In a service provider
use RJP\Tiptap\Tiptap;
$this->app->extend(TiptapInterface::class, function (Tiptap $service) {
// Add your custom extension logic here
// Note: This
namespace App\Services;
use RJP\Tiptap\Contracts\TiptapInterface;
use RJP\Tiptap\Tiptap;
class CustomTiptap implements TiptapInterface
{
public function __construct(private Tiptap $tiptap) {}
// Delegate to original service
public function parseJson(array|string $json, array $extensions = []): string
{
return $this->tiptap->parseJson($json, $extensions);
}
// Add custom methods
public function parseMarkdown(string $markdown): array
{
// Your markdown parsing logic
$json = $this->convertMarkdownToTiptapJson($markdown);
return $json;
}
public function extractImages(array|string $content): array
{
// Extract image nodes from content
return $this->findImageNodes($content);
}
// Implement other interface methods...
}
// Register in AppServiceProvider
$this->app->bind(TiptapInterface::class, CustomTiptap::class);
namespace App\Services;
use RJP\Tiptap\Builders\TiptapBuilder;
class CustomTiptapBuilder extends TiptapBuilder
{
/**
* Add markdown support to the fluent interface.
*/
public function markdown(string $markdown): self
{
$json = $this->convertMarkdownToJson($markdown);
return $this->content($json);
}
/**
* Enforce word limit validation.
*/
public function wordLimit(int $limit): self
{
return $this->tap(function ($builder) use ($limit) {
if ($builder->wordCount() > $limit) {
throw new InvalidArgumentException("Content exceeds {$limit} word limit");
}
});
}
/**
* Add reading level analysis.
*/
public function readingLevel(): array
{
$text = $this->toText();
return $this->calculateReadingLevel($text);
}
private function convertMarkdownToJson(string $markdown): array
{
// Your markdown to Tiptap JSON conversion logic
return [];
}
private function calculateReadingLevel(string $text): array
{
// Your reading level calculation logic
return ['grade' => 8, 'difficulty' => 'medium'];
}
}
namespace App\Services;
use RJP\Tiptap\Tiptap;
class ExtendedTiptap extends Tiptap
{
public function make(): CustomTiptapBuilder
{
return new CustomTiptapBuilder($this);
}
}
// In a service provider boot method
use RJP\Tiptap\Builders\TiptapBuilder;
TiptapBuilder::macro('seoAnalysis', function () {
return [
'word_count' => $this->wordCount(),
'reading_time' => $this->readingTime(),
'headings' => $this->extractHeadings(),
'images' => $this->extractImages(),
];
});
// Usage
$seoData = Tiptap::make()
->content($content)
->seoAnalysis();