Incorporating CKEditor 5 with Nette Application

Cupara
Member | 90
+
0
-

I'm trying to incorporate CKEditor 5 with my application. As far as I know, I have to do this with my forms to get the editor to display:

<div class="form" style="width: 100%;">
    {form editForm}
        <input type="hidden" name="id" value="{$post->id}">
        <div class="input-group mb-3">
            <label for="author" class="form-label">Author</label>
            <input type="text" class="form-control" id="author" name="author" value="{$post->author}" required>
        </div>
        <div class="input-group mb-3">
            <label for="title" class="form-label">Title</label>
            <input type="text" class="form-control" id="title" name="title" value="{$post->title}" required>
        </div>
        <div class="input-group mb-3">
            <label for="slugify" class="form-label">Slug</label>
            <input type="text" class="form-control" id="slugify" name="slug" value="{$post->slug}" required>
        </div>
        <div class="input-group mb-3">
            <label for="content" class="form-label">Content</label>
            <textarea class="form-control" id="content" name="content" rows="10" value="{$post->content}" required></textarea>
        </div>
        <div class="input-group mb-3">
            <label for="updated_at" class="form-label">Updated</label>
            <type="date" class="form-control" id="updated_at" name="updated_at" required>
        </div>
        <button type="submit" class="btn btn-success">Submit</button>
    {/form}
</div>

Is there a way to incorporate it in my presenters so I can use Bootstrap forms? I found Nette-CKEditor on Github but that seems more like I would have to start over from scratch which I don't want to do since I'm very close to being finished with my site.

Also is there a way to make my slugify field autofill from the title field?

Infanticide0
Member | 103
+
+1
-

https://doc.nette.org/…ms/rendering#…

Why would you want to write all input properties again? You already defined them in createComponentEditForm method.
Using {input name} or <input n:name=“name”> in Latte you get whole input/label HTML generated with all attributes defined (name, type, value, rules, class).

You just add custom class=“form-control ckeditor” or data-editor for JS initializing CKEditor.

	latte:
	<label n:name="content" />
	<input n:name="content" data-editor>

	render:
	<label for="content" class="form-label">Content</label>
	<textarea class="form-control" data-editor id="content" name="content" rows="10" NO VALUE ATTRIBUTE HERE required>
		value content
	</textarea>

	<script>
	    ClassicEditor
.create( document.querySelector( '[data-editor]' ) )
.catch( error => {
    console.error( error );
} );
	</script>
Cupara
Member | 90
+
0
-

@Infanticide0 ah ok I didn't realize I could do that to get the editor to show. There isn't a package installation for the editor? If not, I'll have to continue with what I'm doing and use NPM to install it and hope everything works good together.

filisko
Member | 9
+
+2
-

This is what I do:

		$form->addTextArea('content', 'Diario')
            ->getControlPrototype()
            ->class('html-editor');
Cupara
Member | 90
+
0
-

@filisko Thanks, that helps a lot.

Cupara
Member | 90
+
0
-

@filisko I tried your method but it's not working. On the line .create( document.querySelector( 'data-editor' ), { what should the querySelector look like so it knows where to put the editor?

filisko
Member | 9
+
+2
-
document.querySelector( '.yourClass' )
<textarea class="form-control yourClass">
		value content
	</textarea>
Cupara
Member | 90
+
0
-

@Infanticide0 is there anyway to have the slug field fill itself out as the user types in the title field replacing spaces with dashes and making capitalized words lowercase?

Infanticide0
Member | 103
+
+1
-

@Cupara

Do you mean this? https://doc.nette.org/…tils/strings#…

Cupara
Member | 90
+
0
-

@Infanticide0 Yes I believe that's what I'm looking for.

Cupara
Member | 90
+
0
-

@Infanticide0 how would I implement webalize if I need to pass $form->addText('title', 'Title:')->setRequired(); to it?

Infanticide0
Member | 103
+
+1
-

@Cupara

Use webalize before saving form data to the database in onSuccess callback. There is not only one right way to do it, depends on use case.

//$title = "My page title!" (form input value)
$title = $values->title;
$slug = Strings::webalize($title);
//sql insert

Then you can change your router to have page URLs like domain.com/132-my-page-title
When using slugs, you should canonicalize https://doc.nette.org/…n/presenters#… request in your PagePresenter

Last edited by Infanticide0 (2024-01-14 00:32)

Cupara
Member | 90
+
0
-

@Infanticide0 thanks. That helps.

Cupara
Member | 90
+
0
-

@Infanticide0 so I'm trying to incorporate canonicalize in my files but I'm not sure what I should be doing.

It's reporting that 'Cannot read an undeclared property App\Presenters\NewsPresenter::$facade.'

I have this in my NewsPresenter.php

	public function actionShow(int $id, string $slug = null): void
	{
		$realSlug = $this->facade->getSlugForId($id);
		$this->canonicalize('News:show', [$id, $realSlug]);
	}

	public function renderShow(int $id): void
	{
		$new = $this->template->new = $this->database
			->table('news')
			->get($id);
		if (!$new) {
			$this->error('Article not found');
		}

		$this->template->new = $new;
		$this->template->comments = $this->database->table('comments')->where('news_id', $id)->order('created_at');
	}

Last edited by Cupara (2024-01-16 05:52)

mskocik
Member | 61
+
+1
-

Cupara wrote:

It's reporting that 'Cannot read an undeclared property App\Presenters\NewsPresenter::$facade.'

Do you even have $facade property in given presenter?

Cupara
Member | 90
+
0
-

mskocik wrote:

Cupara wrote:

It's reporting that 'Cannot read an undeclared property App\Presenters\NewsPresenter::$facade.'

Do you even have $facade property in given presenter?

No, I know where I went wrong. I need to create the facade file and then we'll be golden.

Cupara
Member | 90
+
0
-

@mskocik can't I just use $this->autoCanonicalize = false to get the result I want?

Cupara
Member | 90
+
0
-

Ok so I got it working but it includes ?slug=article-eleven in the URL. What is the rewrite condition to make it so the URL is just the slug and no post id?

mskocik
Member | 61
+
0
-

Your route definition in router should use only slug then. Like this:

// RouterFactory.php
$router->addRoute('/news/<slug .*>', 'News:show');

// NewsPresenter.php
public function actionShow(?string slug = null): {
	$new = $this->template->new = $this->facade->getNewsBySlug($slug);
	// etc.
}

Is it clear?

Last edited by mskocik (2024-01-16 13:01)