Zakomponování a zprovoznění TinyMCE

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
milde
Člen | 52
+
0
-

Zdravím všechny,
rád bych se zeptal, zda neví někdo, kde bych našel podrobný návod na zakomponovaní a zprovoznění TinyMCE? Přiznám se, že z toturiálu nejsem moc moudrý, lépe řečeno jsem jej vůbec nepochopil a při hlubším hledání se mi nepodařilo takový návod najít. Za každou radu Vám předem všem moc děkuji.

ViPEr*CZ*
Člen | 813
+
0
-

Nevím co jste kde četl… ale jen tak z hlavy. Připojíte TinyMCE javascript třeba v @layoutu a poté už jen podle návodu nahradíte (podle IDéčka) nějakou textareu. Odeslaný obsah už pak získáte z requestu.

ViPEr*CZ*
Člen | 813
+
0
-

iguana007 napsal(a):

https://pla.nette.org/…neni-tinymce

Díky, toto je samozřejmě nejideálnější. ;-)

milde
Člen | 52
+
0
-

ViPErCZ napsal(a):

iguana007 napsal(a):

https://pla.nette.org/…neni-tinymce

Díky, toto je samozřejmě nejideálnější. ;-)

rád bych Vás požádal o konkrétní nápovědu jak to zprovoznit … už skoro měsíc si s tím lámu hlavu a fakt jsem v koncích … z tohoto tutoriálu jsem to nepochopil … jsem asi totální lama. Pomůže mi prosím někdo?? Všem předem moc děkuji.

Ot@s
Backer | 476
+
0
-

milde napsal(a):

rád bych Vás požádal o konkrétní nápovědu jak to zprovoznit … už skoro měsíc si s tím lámu hlavu a fakt jsem v koncích … z tohoto tutoriálu jsem to nepochopil

  1. Stáhni si TinyMCE a rozbalené nakopíruj na FTP/lokální documnet root projektu (třeba do adresáře /js)
  2. Přilinkuj si do (pravděpodobně @layout.latte) šablony – cestu k tiny_mce.js uprav dle bodu 1
<script type="text/javascript" src="{$basePath}js/tiny_mce/tiny_mce.js" ></script >
<script type="text/javascript" >
tinyMCE.init({
	mode: "specific_textareas",
	editor_selector: "mceEditor",
        theme : "simple"
});
</script >
  1. Do presenteru (třeba Homepage) přidej:
	protected function createComponentTestWysiwyg() {
		$form = new Nette\Application\UI\Form();
		$form->addTextArea('text', 'Text')
		    ->getControlPrototype()->class('mceEditor');
		return $form;
	}
  1. Do šablony presenteru přidej (třeba Homepage/default.latte)
{control testWysiwyg}

Psáno z hlavy (+/-). Pak kdyžtak napiš, kde v tomto postupu máš problém.

milde
Člen | 52
+
0
-

Ot@s napsal(a):

Pak kdyžtak napiš, kde v tomto postupu máš problém.

Děkuji za radu, ale hlásí mi to že Component with name ‚testWysiwyg‘ does not exist – zkoušel jsem to i s TestWysiwyg ale ani to nepomohlo (nejsem si jist jestli nezáleží na velikosti písmen t/T). Tiny jsem si stáhl a uložil do ../www/js/ a dale jsem postupoval dle tvého řešení:

AdminPresenter:

<?php
class AdministracePresenter extends BasePresenter{

	public function beforeRender(){	}

protected function createComponentTestWysiwyg() {
        $form = new Nette\Application\UI\Form();
        $form->addTextArea('text', 'Text')
            ->getControlPrototype()->class('mceEditor');
        return $form;
}
}
?>

@layout.latte:

<?php
<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

	<meta name="description" content="Nette Framework web application skeleton">
	<meta name="robots" content="{$robots}" n:ifset="$robots">

	<title>{include #title}</title>

	<link rel="stylesheet" media="screen,projection,tv" href="{$basePath}/css/screen.css" type="text/css">
	<link rel="stylesheet" media="print" href="{$basePath}/css/print.css" type="text/css">
	<!--<link rel="shortcut icon" href="{$basePath}/favicon.ico" type="image/x-icon">-->

	<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script>
	<script type="text/javascript" src="{$basePath}/js/netteForms.js"></script>

	<script type="text/javascript" src="{$basePath}js/tiny_mce/tiny_mce.js" ></script >
<script type="text/javascript" >
tinyMCE.init({
        mode: "specific_textareas",
        editor_selector: "mceEditor",
        theme : "simple"
});
</script >

	{block head}{/block}
</head>
?>

a koncová šablona:

<?php
{block title} Pokus {/block}
		{block content}
			{control testWysiwyg}
?>

jsem začátečník s nette. Ještě jednou moc děkuji za pomoc

Ot@s
Backer | 476
+
0
-

Na velikosti názvů komponent opravdu záleží (ono createComponentTestWysiwyg vs. šablonové testWysiwyg). Předpokládám, že „koncovou šablonou“ nazýváš tu, která se váže k AdministracePresenter (třeba /apl/template/Administrace/default.latte). Protože se to tváří, jako bys zobrazoval presenter bez metody createComponentTestWysiwyg.

milde
Člen | 52
+
0
-

Ot@s napsal(a):

Na velikosti názvů komponent opravdu záleží (ono createComponentTestWysiwyg vs. šablonové testWysiwyg). Předpokládám, že „koncovou šablonou“ nazýváš tu, která se váže k AdministracePresenter (třeba /apl/template/Administrace/default.latte). Protože se to tváří, jako bys zobrazoval presenter bez metody createComponentTestWysiwyg.

Tak teď už jsem z toho jelen asi úplně. Moje „struktura“ je:

<?php
app/AdminModule
	+presenter
		-AdminPresenter
		-AdministracePresenter
	+template
		+Admin
			-@layout.latte
			-administrace.latte
			-admin.latte
			-default.latte
?>

admin.latte – šablona pro přihlašení, která dědí od @layout.latte a doplňuje jí o formulář pro přihlášení

administrace.latte – sem jsem vložil tvou nápovědu {control testWysiwyg}

A kompponentu vytvářím v AdministracePresenter – výše jsem to uvedl špatně.

fakt už nevím co s tím:-(

Editoval milde (16. 11. 2011 13:56)

milde
Člen | 52
+
0
-

JuniorJR napsal(a):

uprav si to na:

public function beforeRender()
{
    parent::beforeRender();
    // není podstatné, ale pokud v této metodě
    // nepřidáváš žádnou další funkcionalitu, vůbec ji neuváděj
    // (pokud ji tedy nepřepisuješ cíleně)
}

vyzkoušel jsem i tvé řešení – bohužel se stále stejným výsledkem :-(

milde
Člen | 52
+
0
-

JuniorJR napsal(a):

milde napsal(a):

JuniorJR napsal(a):

vyzkoušel jsem i tvé řešení – bohužel se stále stejným výsledkem :-(

však jsem psal, že pro řešení tvého problému to není podstatné, jen jsem se chtěl ujistit, jestli to tak máš schválně nebo ne (aby jsi na to pak nezapomněl ;))

s parent::beforeRender() jsem to pochopil … měl jsem na mysli tvé řešení, kdy jsem dal public místo protected …

JuniorJR
Člen | 181
+
0
-

@milde jj, to byla moje chyba, jen si zkontroluj, zda vytváříš komponentu v AdministracePresenter a šablonu máš app/AdminModule/templates/Administrace

mám pocit, že v tom máš trochu zmatek, jelikož máš vytvořenou složku s šablonami pouze pro AdminPresenter, nikoliv už pro AdministracePresenter a pokud se odkazuješ na tu komponentu v šabloně templates/Admin/…, tak to samozřejmě nemůže fungovat :) ledaže by si továrnu hodil do společného předka (tj. BasePresenter)

čili struktura by vypadala nějak takhle:

app/AdminModule
    +presenters
        -AdminPresenter
        -AdministracePresenter
    +templates
        +Admin
            -@layout.latte
            -administrace.latte	// tohle vezmi, přejmenuj na default.latte a hoď do +Administrace
            -admin.latte
            -default.latte
        +Administrace
            -@layout.latte
            -default.latte	// obsah původního souboru administrace.latte

Editoval JuniorJR (16. 11. 2011 14:24)

milde
Člen | 52
+
0
-

JuniorJR napsal(a):

@milde jj, to byla moje chyba, jen si zkontroluj, zda vytváříš komponentu v AdministracePresenter a šablonu máš Administrace/xxx.latte, mám pocit, že máš v tom trochu zmatek, jelikož máš vytvořenou složku s šablonami pouze pro AdminPresenter, nikoliv už pro AdministracePresenter

šablonu pro AdministracePresenter mám … a funguje do doby, kdy tam dám {control testWysiwyg}

JuniorJR
Člen | 181
+
0
-

@milde pošli aktuální strukturu aplikace, pořád si myslím, že komponentu vytváříš v AdministracePresenter, ale přitom se ji snažíš použít pro šablony AdminPresenter

Editoval JuniorJR (16. 11. 2011 14:25)

milde
Člen | 52
+
0
-

JuniorJR napsal(a):

@milde pošli aktuální strukturu aplikace, pořád si myslím, že komponentu vytváříš v AdministracePresenter, ale přitom se ji snažíš použít pro šablony AdminPresenter

jasně … díky za radu … už se mi tam textarea vykreslila ..... jsem já to lama ..... teď ještě ji nastavit aby se zobrazovala v plném formátu a nastavit ukládání do db :-( ale jinak díky za radu.....

milde
Člen | 52
+
0
-

Mám jestě jeden dotaz … rád bych Vás požádal ještě o pomoc s nastavením. Textarea se mi zobrazuje, tlačítko pro odeslaní mám rovněž, jen bych u editoru potřeboval jestě tlačítka pro editaci textu (např. bold, italic apod.). Všem moc děkuji za radu – učím se s Nette a moc mi to nejde :-(

JuniorJR
Člen | 181
+
0
-

To co hledáš, není záležitostí Nette, ale konfigurace TinyMCE.

Příklad toho, jak by to mohlo vypadat:

<script type="text/javascript">
    tinyMCE.init({
        mode: "specific_textareas",
        editor_selector: "mceEditor",
    	theme : "advanced",
    	theme_advanced_toolbar_location : "top",
    	theme_advanced_buttons1 : "bold,italic,underline,strikethrough,separator,"
    	+ "justifyleft,justifycenter,justifyright,justifyfull,formatselect,"
    	+ "bullist,numlist,outdent,indent",
    	theme_advanced_buttons2 : "link,unlink,anchor,image,separator,"
    	+"undo,redo,cleanup,code,separator,sub,sup,charmap"
    });
</script>

Převzato z wiki
theme buttons

Editoval JuniorJR (19. 11. 2011 10:29)

milde
Člen | 52
+
0
-

JuniorJR napsal(a):

To co hledáš, není záležitostí Nette, ale konfigurace TinyMCE.

Příklad toho, jak by to mohlo vypadat:

<script type="text/javascript">
    tinyMCE.init({
    	theme : "advanced",
    	theme_advanced_toolbar_location : "top",
    	theme_advanced_buttons1 : "bold,italic,underline,strikethrough,separator,"
    	+ "justifyleft,justifycenter,justifyright,justifyfull,formatselect,"
    	+ "bullist,numlist,outdent,indent",
    	theme_advanced_buttons2 : "link,unlink,anchor,image,separator,"
    	+"undo,redo,cleanup,code,separator,sub,sup,charmap"
    });
</script>

Převzato z wiki
theme buttons

no toto jsem zkoušel už předtím dát do @layout.latte a právě, že mi to nefunguje … jsem asi fakticky lama …

JuniorJR
Člen | 181
+
0
-

@milde A vykreslí se ti teď alespoň ten zákl. editor?

milde
Člen | 52
+
0
-

JuniorJR napsal(a):

@milde A vykreslí se ti teď alespoň ten zákl. editor?

ne … pouze textarea…

JuniorJR
Člen | 181
+
0
-

@milde A nezapoměl si do initu zahrnout i původní volby, které zajistí nabindování TinyMCE na konkrétní textareu:

<script type="text/javascript">
    mode: "specific_textareas",
    editor_selector: "mceEditor",
</script>

?

Nezapomeň si také zkontrolovat, že JS uvádíš vé správném layoutu (za předpokladu, že jich používáš více).

Editoval JuniorJR (19. 11. 2011 10:33)

milde
Člen | 52
+
0
-

JuniorJR napsal(a):

@milde A nezapoměl si tam dát:

<script type="text/javascript">
    mode: "specific_textareas",
    editor_selector: "mceEditor",
</script>

?

mám tam:

<?php
tinyMCE.init({
        mode: ""specific_textareas",
        editor_selector: "mceEditor",
        theme : "advanced",
		theme_advanced_toolbar_location : "top",
		theme_advanced_buttons1 : "separator,insertdate,inserttime,preview,zoom,separator,forecolor,backcolor",
        theme_advanced_buttons2 : "bullist,numlist,separator,outdent,indent,separator,undo,redo,separator",
        theme_advanced_buttons3 : "hr,removeformat,visualaid,separator,sub,sup,separator,charmap"
})
?>
JuniorJR
Člen | 181
+
0
-

@milde Oprav si překlep u prvního parametru (dvojité uvozovky).

milde
Člen | 52
+
0
-

JuniorJR napsal(a):

@milde Oprav si překlep u prvního parametru (dvojité uvozovky).

tech jsem si nevsiml, ale buhužel ani tak mi to nefunguje .....

JuniorJR
Člen | 181
+
0
-

@milde Předtím si psal, že už se ti editor zobrazuje, jakto, že najednou ne? Neměnil si něco, např. třídu pro textareu? Máš tam nalinkovaný JS soubor s TinyMCE?

Tady máš funkční ‚full featured příklad‘. Ale spoustu z těch parametrů není potřeba ani definovat. Minimálně ne do doby, dokud nerozběhneš alespoň zákl. rozhraní.

Editoval JuniorJR (19. 11. 2011 10:51)

milde
Člen | 52
+
0
-

JuniorJR napsal(a):

@milde Předtím si psal, že už se ti editor zobrazuje, jakto, že najednou ne? Neměnil si něco, např. třídu pro textareu? Máš tam nalinkovaný JS soubor s TinyMCE?

Tady máš funkční ‚full featured příklad‘. Ale spoustu z těch parametrů není potřeba ani definovat. Minimálně ne do doby, dokud nerozběhneš alespoň zákl. rozhraní.

špatně jsem se vyjádřil … zobrazila se mi jen textarea :-(

nic jsem neměnil a nalinkované bych to měl mít rovněž správně:

<?php
<script type="text/javascript" src="{$basePath}/js/tiny_mce/tiny_mce.js" ></script >
?>

Editoval milde (19. 11. 2011 11:19)

JuniorJR
Člen | 181
+
0
-

@milde Tak si ještě jednou zkontroluj, zda se ti správně nalinkuje zdroják pro TinyMCE, nejlépe takto:

  • zobraz si zdrojový kód stránky a ověř si, že adresa JS souboru odpovídá realitě
  • koukni se, zda máš pro danou textareu správně nadefinovou CSS třídu

Editoval JuniorJR (19. 11. 2011 13:18)

milde
Člen | 52
+
0
-

JuniorJR napsal(a):

@milde Tak si ještě jednou zkontroluj, zda se ti správně nalinkuje zdroják pro TinyMCE, nejlépe takto:

  • zobraz si zdrojový kód stránky a ověř si, že adresa JS souboru odpovídá realitě
  • koukni se, zda máš pro danou textareu správně nadefinovou CSS třídu

Ahoj, díky, už jsem se nedostal k tomu abych ti odpověděl…problém byl zřejmě s verzí tinyMCE … stahl jsem si jinou verzi podporující jQuery a už to běhá tak jak má, ale každopádně i tak ti moc děkuji za pomoc …

milde
Člen | 52
+
0
-

Mám ještě jednu prosbu … nevíte jak bych to uložil do databáze?

JuniorJR
Člen | 181
+
0
-

@milde: A co máš na mysli?
Zpracování formuláře uděláš zavěšením metody na událost onSuccess formuláře.

use Nette\Application\UI\Form;

class AdministracePresenter extends BasePresenter
{
    /**
     * Creates TestWysiwyg component.
     *
     * @return Nette\Application\UI\Form
     */
    protected function createComponentTestWysiwyg()
    {
        $form = new Form();
        // zavěšení handleru na událost onSuccess
        $form->onSuccess[] = callback($this, 'testWysiwyg_onSuccess');
        $form->addTextArea('text', 'Text')
            ->getControlPrototype()->class('mceEditor');
        return $form;
    }

    /**
     * Handles TestWysiwyg 'onSuccess' event.
     * Saves input text data.
     *
     * @param Nette\Application\UI\Form $form
     * @return void
     */
    public function testWysiwyg_onSuccess(Form $form)
    {
        $values = $form->getValues();

        // metoda modelu, která se stará o ukládání záznamů, konkrétní implementace je už na tobě
        $this->modelXxx->save(array('text' => $values['text']));
        $this->flashMessage('Text uložen ...');
        $this->redirect('...');
    }

Editoval JuniorJR (22. 11. 2011 13:34)

milde
Člen | 52
+
0
-

JuniorJR napsal(a):

@milde: A co máš na mysli?

no mám na mysli to, že když dám nějaký text do editoru, tak bych chtěl aby se mi to uložilo do db včetně html tagů aybch když to pak zavolám v nějakém prezenteru, tak aby se mi to vypsalo na stránce tak jak jsem to zadal do editoru. Snad jsem to napsal srozumitelně:-)

milan
Člen | 24
+
0
-

Zdravím, velmi zajímavé téma. Mě by zajímalo to ukládání do database. Nevím jestli jsem dobře pochopil MVP ( s tímto začínám a to stejně jako s celým Nette ). Znamená to, že za modelXxx dám název modelu např. TestModel a v něm si nadefinuji proces ukládání do database, s tím, že TEstModel dědí od BaseModel?

JuniorJR
Člen | 181
+
0
-

@milan: Ano, nejspíš si to pochopil správně. Podstatou je rozdělení odpovědností mezi 3 různé vrstvy. Jen je samozřejmě nutné, aby ten konkrétní model měl daný presenter k dispozici. To, že dědíš od BaseModel není podle mě dikce, ale spíš otázka good practice, jelikož ti to může podstatnou mírou usnadnit další vývoj.

Editoval JuniorJR (24. 11. 2011 10:32)

milan
Člen | 24
+
0
-

@JuniorJR rozumím, takže jinak řečeno bych teď v TestModel vytvořil class TestModel a podle toho co jste tu řešili definoval funkci save() a teď nevím, jestli syntaxe zápisu do database bude spravně – DiBi vidím prvně v životě. Osobně bych to napsal asi takto:

<?php
public function save(Nette\Application\UI\Form $form){
	return dibi::query("INSERT INTO [název tabulky], (array) $form );
}
?>

vytahuje se to tedy k tomu co jste tu řešili – jen nevím jestli je to správně.

JuniorJR
Člen | 181
+
0
-

@milan: Osobně mám metodu save definovanou takto:

/**
 * Saves the given data into DB.
 * It checks whether $data['id'] is set or if is not NULL to check whether
 * new record should be inserted or existed one updated.
 *
 * @param array $data
 * @return void
 */
public function save(array $data)
{
	if (!isset($data['id']) || $data['id'] == NULL) {
	    $this->insert($data);
	} else {
	    $this->update($data, array('id' => $data['id']));
	}
}

To tvé řešení bych nedoporučoval, neboť by se tak ukládání stalo závislé na existenci formuláře. Sice je to nejběžnější způsob ukládání dat, ale někdy přeci jen potřebuješ uložit data, která nepochází z formuláře.

EDIT: Samozřejmě by to šlo řešit tak, že by si místo pole předávál nějaký objekt obsahující daná data ve standardizované podobě.

Editoval JuniorJR (24. 11. 2011 11:04)

milan
Člen | 24
+
0
-

@JuniorJR tak jsem zkusil jak to své tak to tvé řešení a laděnka na mě štěkne Cannot read an undeclared property HoukusPresenter::$HokusModel – nevěděl bys v čem by mohl být problém – rozumím tomu, že nemůže přečíst nedeklarovanou vlastnost, ale nejsem si jist, ale mám za to, že ji deklarovanou mám.

Editoval milan (24. 11. 2011 11:15)

JuniorJR
Člen | 181
+
0
-

@milan:

V presenteru:

class HokusPresenter extends BasePresenter
{
    private static $hokusModel;

    protected function getHokusModel()
    {
        if (self::$hokusModel === NULL) {
            self::$hokusModel = new HokusModel(...);
        }
        return self::$hokusModel;
    }

    public function hokusForm_OnSuccess(Nette\Application\UI\Form $form)
    {
        $values = $form->getValues();
        $this->getHokusModel()->save(array(
            'text' => $values['text'],
        ));
        $this->redirect('this');
    }
}

A máš to pěkně v singletonu :D

Editoval JuniorJR (24. 11. 2011 11:52)

milan
Člen | 24
+
0
-

JuniorJR Myslíš, že bych tě mohl poprosit o doplnění i těch teček – abych se v tom zcela zorientoval? Rozkoukávám se a toto by mo dost helflo abych se orientoval. Děkuji moc za kontruktivní rady.

tatyalien
Člen | 239
+
0
-

Nemohl jsem rozjet pravidla pro textareu s tinyMce, fungovalo mě to sice ve firefoxu, ale opera prohlížeč nebral nějak v potaz triggerSave(), rozjelo se mě to, až když jsem dodal do tinyMCE.init({, třeba to někomu pomůže a neztratí pár hodin hledáním ;)

/* v opeře mě nefungovalo addRule, neukládalo (triggerSave()), s tímto funguje */
setup : function(ed) {
      ed.onKeyUp.add(function(ed, e) {
    tinyMCE.triggerSave();

      });
   },

Editoval tatyalien (6. 8. 2012 22:56)