Welcome, Guest. Please login or register.
Did you miss your activation email?
Aug. 08, 2008, 08:26:23 PM
46283 Posts in 10122 Topics by 5106 Members
Latest Member: Muthukumar
News: PRADO community toolbar eases your interaction with the PRADO community.
 
The PRADO Community » Prado v3.x » Component Repository » Content from the Database with PRADO tags/expansion « previous next »
Pages: [1] Print
Author Topic: Content from the Database with PRADO tags/expansion  (Read 2251 times)
javalizard
Junior Member
**

Karma: 9
Offline Offline

Posts: 20



View Profile
« on: Jul. 16, 2007, 03:10:18 PM »

I ran into the problem where I wanted to allow for <%~ 'resource' %> and <%[Hello World]%> in content that was coming from the database.  In this way, the content wasn't just being dropped into place with something like TLabel->Text=$content but passed through the prado parser and rendered the prado way.  In other words i wanted a full wepage to be able to come from the database.

So, here is the class to implement that functionality...

Code:
class TDBContent extends TControl
{
  var $dbid = null;
  var $contentid = null;
 
  // if before pre-render then the content id may be blank if it's dynamic
  public function onPreRender($config) {
parent::onPreRender($config);
if($this->dbid == null)
throw new Exception("The DatabaseID of the database was not specified");
if($this->contentid == null)
throw new Exception("The ContentID was not specified");
if(empty($this->Application->Modules[$this->dbid]))
throw new Exception("There was no database at the id '{$this->dbid}'");
  }
 
  public function render($writer) {

$db = $this->Application->Modules[$this->dbid]->Database;
$cmd = $db->createCommand("SELECT content FROM page_content WHERE content_key=:key");
$cmd->bindParameter(":key",$this->contentid,PDO::PARAM_STR);
$pageText = $cmd->queryScalar();

$page = new TPage();
$tpl = new TTemplate($pageText, $this->Page->Template->ContextPath);
$page->setPage($this->getPage());
$page->setTemplate($tpl);
$page->setPagePath($this->contentid);
$page->run($writer);
  }
  public function getDatabaseId() {return $this->dbid;}
  public function setDatabaseId($v) {$this->dbid = $v; }

  public function getContentId() {return $this->contentid;}
  public function setContentId($v) {$this->contentid = $v;}
}

The table I have for this class is about as simple as it gets
Code:
CREATE TABLE `page_content` (
`id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`content_key` VARCHAR( 128 ) NOT NULL ,
`content` LONGTEXT NOT NULL
) ENGINE = MYISAM ;

The explanation.
This control doesn't have a template associated with it so it's not a subclass of TTemplateControl.  This class is the short form of how prado generates a page.  The TTemplate parses the content and the TPage renders it.  The ContextPath is important so that assets from the correct directory get published.  Run is how the page is actually created.  Clearly you can't have any OnClick attributes, active control, or dynamic content beyond what's in that page in the database.  Still, it is good for basic editable static pages.

I'm sure there are a number of improvements that can be made, such as I18N, caching, or an option for SafeHTML, but the class above is just a starting point.  If you ever want prado to parse any of your content then you can use this example.  If you make any improvements to this class I'd love to see them uploaded here.

I'm using it with FCKEditor.  Users may create and edit a page with FCKEditor (and upload files) and still have some of the cool features of prado.  This works particularly well when you have a set of TTemplateControls that your users can put in the html to create the page.  Some may be:  WebsiteLoginPanel, SearchBox, MainNavigationWithTopLevelPages and the like.

Enjoy!
« Last Edit: Jul. 17, 2007, 08:33:00 PM by javalizard » Logged
rojaro
Senior Member
***

Karma: 14
Offline Offline

Posts: 354


PRADO aint no voodoo ...


View Profile WWW
« Reply #1 on: Jul. 16, 2007, 03:21:10 PM »

Hi javalizard,

this is pretty much the same method as it is used in Phundament, but it's really nice to see it here in this simplified form. I am sure this will come handy one day or another. Thanks Smiley

Greetings from Hamburg / Germany
- rojaro -
Logged

A mathematician is a machine for turning coffee into theorems. ~ Alfred Renyi (*1921 - †1970)
javalizard
Junior Member
**

Karma: 9
Offline Offline

Posts: 20



View Profile
« Reply #2 on: Jul. 30, 2007, 05:30:54 PM »

If you are going to use FCKeditor to edit html that becomes the content then you'll have trouble with case sensitivity.  FCKeditor will make all your tags lowercase.  Prado needs to have the tag classes uppercase.  In otherwords, FCKeditor complies with xhtml (all tags as lowercase) and will kill any attempts at using prado tags in this dynamic content.

This is pain if you have custom tags that the user can use in their html.

In order to fix this you can pass the content through this filter before saving the content in the database:

Code:
// this gets all the classes that are in the include paths
  function getUsingClasses() {
$paths = explode( PATH_SEPARATOR, get_include_path() );

$classes = array();
foreach($paths as $path) {
if(!is_dir($path)) continue;

if ($dh = opendir($path)) {
while (($file = readdir($dh)) !== false) {
if(!is_dir($path.'/'.$file)) {
preg_match('/^(.*)\.php$/', $file, $match);
if($match[1])
$classes[] = $match[1];
}
}
closedir($dh);
}
}
return $classes;
  }
  function upperClasses($text) {
$classes = array_merge(get_declared_classes(), getUsingClasses());
function addCom($str) {
return 'com:'. $str;
}
$classes = array_map('addCom', $classes);
$lowerclasses = array_map('strtolower', $classes);

return str_replace($lowerclasses, $classes, $text);
  }

//use this to filter the lowercase tag-classes back into prado usable tag-classes

$content = upperClasses($content);



This works by getting all the classes in the include path and all classes that have been defined to the point of the call.  It then adds "com:" to the classes, and makes a list of classes that are all lower case.  Lastly, it replaces all the lower case instances of the tag with what it should be to functional.
Logged
rojaro
Senior Member
***

Karma: 14
Offline Offline

Posts: 354


PRADO aint no voodoo ...


View Profile WWW
« Reply #3 on: Jul. 31, 2007, 09:46:52 AM »

Hi javalizard,

great tip, you should post it in the "Tips, Snippets and Tutorials" forum. I am sure there are many other people trying to use the FCKeditor as well and have to cope with the same problem.

Greetings from Hamburg / Germany
- rojaro -
« Last Edit: Jul. 31, 2007, 09:52:07 AM by rojaro » Logged

A mathematician is a machine for turning coffee into theorems. ~ Alfred Renyi (*1921 - †1970)
Shoeb
Senior Member
***

Karma: 2
Offline Offline

Posts: 75


Njoy


View Profile
« Reply #4 on: May. 16, 2008, 09:22:08 PM »

Hi,

In this case, how will the form post be captured?

I need to use $this->XXXComponentId->TTextboxID->Text

Regards,
Shoeb
Logged

No one can be told what the "Matrix" is !
Shoeb
Senior Member
***

Karma: 2
Offline Offline

Posts: 75


Njoy


View Profile
« Reply #5 on: May. 17, 2008, 01:16:03 AM »

Hello Everyone,

After finding out more on myself, i figured it out that there is no need to extend from TControl and you can do this by extending TTemplateControl since you initialize the template in the code as give below
Code:
$tpl = new TTemplate($pageText, $this->Page->Template->ContextPath);

which will anyways ignore the template finding process and also give you the extensive functionality of TTemplateControl.

Lemme know your thought.



Hi,

In this case, how will the form post be captured?

I need to use $this->XXXComponentId->TTextboxID->Text

Regards,
Shoeb
Logged

No one can be told what the "Matrix" is !
Pages: [1] Print 
« previous next »
Jump to: