?
Solved

Modifying content of web page on the fly

Posted on 2004-11-11
7
Medium Priority
?
361 Views
Last Modified: 2008-02-20
Scenario:
Users enter content which goes on a web site using Movable Type. Users are non-technical, but I need to enable a couple of things without requiring users to enter html, code etc. Specifically:
(1) catch any email addresses entered and print them in a format not readable by spambots
(2) allow easy insertion of images within the text

Planned solution:
Movable Type will output a static file for each entry based on a predefined template. This template will contain PHP code to provide the functionality I require. Use ob_start to route all output to a function which
(1) routes any email addresses found to a function (already written and working, uses javascript to 'mangle' addresses in a non machine readable format)
(2) looks for any instances of {image=file.jpg} and replaces with the relevant IMG html

The code I have so far is as follows:-
<?
//load email() function
require("dev/inc/email.inc");

function image($command) {
      //convert {image=[image filename] align=[left|right|center] caption=[caption in quotes]} to correct html
      preg_match("/image=([^\s}]*)/i",$command,$image);
      preg_match("/align=([^\s}]*)/i",$command,$align);
      preg_match('/caption.*"([^"]*)"/i',$command,$caption);
      $caption=stripslashes($caption[1]);
      //output correct html for IMG (or dummy text for testing)
      echo("IMAGE=$image[1] ALIGN=$align[1] CAPTION=$caption");
}

function callback($buffer) {
      //regexp for replacing emails with email() function
      $search[0]="/[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]{2,})+/ie";
      $replace[0]="email('\\0','\\0');";

      //regexp for replacing {image} with IMG html code by calling image() function
      $search[1]="/{image[^}]*}/ie";
      $replace[1]="image('\\0');";

      $buffer = preg_replace($search,$replace,$buffer);

      return($buffer);
}
?>

<html>
<body>
<p><b>Callback function called directly</b></p>
<?echo(callback('<p>An image might go here {image=img.jpg caption="hello there" align=right}</p><p>Just email me at email@somewhere.com</p>'));?>

<p><b>Callback function called through ob_start</b></p>
<?ob_start("callback");?>
<p>Just email me at email@somewhere.com</p>
<p>An image might go here {image=img.jpg align=right caption=hello there}</p>
<? ob_end_flush();?>
</body>
</html>

Problems:
(1) when calling the callback function directly (ie not through ob_start), the results of the replacements are output first, then the rest of the text.
(2) when calling through ob_start, no replacement results are output, just the buffer less the bits that matched.

Requirement:
Either help me to get this code working correctly, or suggest a better way to achieve the same. Note that over time I will probably add more replacements, so it needs to be flexible enough to accept an arbitrary number of replacements.

Thanks

mark.
0
Comment
Question by:markauk
7 Comments
 

Expert Comment

by:abuzzuz
ID: 12555271
What the hell is Moveable Type?
0
 

Expert Comment

by:abuzzuz
ID: 12555329
I'd like to help you but, as I said before, cant figure out exaclty what you are trying to achieve with this movable type and static html stuff.
0
 

Author Comment

by:markauk
ID: 12556345
MovableType is a blog/content management system (www.movabletype.org). The fact that I am using Movable Type doesn't really matter except to explain why I have individual pages which have content in them which needs modified on the fly (rather than having the pages done correctly when originally authored). As far as I know, I can't achieve what I want directly within Movable Type, hence needing separate php code to do it.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 9

Expert Comment

by:waygood
ID: 12561033
why dont you use BBcode (bulletin board)

eg [b]bold text[/b] [img=pic.jpg] some other normal text then [email=email@domain.com]email me[/email] the < character doesnt interfere with bbcode.

you then convert the code to html and store it for when you display the page. pointless converting on the fly. forums like phpBB use it.
You can also convert email addresses to code values, which bot dont pick up.

$encoded_email="";
for ($i = 0; $i < strlen($email); $i++) {
   $encoded_email.='&#'.ord(substr($email,$i,1));
}
0
 

Author Comment

by:markauk
ID: 12561615
Not sure I follow. BBcode is just html, but with [] instead of <>, right? I'd still have to parse through and convert [] to <>. phpBB presumably does this every time it outputs a page, and its pages are always generated dynamically on the fly. Also, the image insertion will be more complex than just inserting <img=pic.jpg> as I will also be inserting styles and other stuff I need to hide from the user.

I need to convert on the fly, because otherwise how do I change something that is sitting in a php file generated by moveable type to the code I want? (assuming movable type can't do the conversion itself, and I don't think it can)
0
 
LVL 2

Accepted Solution

by:
Fenric earned 2000 total points
ID: 12562992
Hi, markauk.

I don't know enough about PHP and I know next to nothing about Movable Type (I know what it is) and BBCode, but I used this question as an opportunity to learn a couple of new PHP functions. So thanks for the inspiration. :-)

The simplest answer to your question appears to be your echo statement at the end of the "image()" function. If you replace this with a return(), it appears to work fine, as far as I can tell without access to your email() function.

Without making this change, I was able to at least get some output from the buffered stream by using an ob_get_contents() call. I added the following two lines:

$buffer=ob_get_contents();
callback($buffer);

before the ob_end_flush(). It worked, except that the replaced strings were at the end of the buffer rather than in place. (Interesting, as the direct call output the replacements first, before the rest of the buffer string.) Again, replacing the echo with a return fixed the problem and allowed me to remove the extra two lines.

My final code read as follows:

[CODE]

<?
//load email() function
//require("dev/inc/email.inc");

function imgo($command) {
     //convert {image=[image filename] align=[left|right|center] caption=[caption in quotes]} to correct html
     preg_match("/image=([^\s}]*)/i",$command,$image);
     preg_match("/align=([^\s}]*)/i",$command,$align);
     preg_match('/caption.*"([^"]*)"/i',$command,$caption);
     $caption=stripslashes($caption[1]);
     //output correct html for IMG (or dummy text for testing)
     return("IMAGE=$image[1] ALIGN=$align[1] CAPTION=$caption");
}

function callback($buffer) {
     //regexp for replacing emails with email() function
     $search[0]="/[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]{2,})+/ie";
     $replace[0]="email";

     //regexp for replacing {image} with IMG html code by calling image() function
     $search[1]="/{image[^}]*}/ie";
     $replace[1]="imgo('\\0');";

     $buffer = preg_replace($search,$replace,$buffer);
     return($buffer);
}

?>

<html>
<body>
<p><b>Callback function called directly</b></p>
<?echo(callback('<p>An image might go here {image=img.jpg caption="hello there" align=right}</p><p>Just email me at email@somewhere.com</p><p>And another image goes here. {image=img2.jpg align=right caption="hello again"}'));?>

<p><b>Callback function called through ob_start</b></p>
<?ob_start("callback");?>
<p>Just email me at email@somewhere.com</p>
<p>An image might go here {image=img.jpg align=right caption="hello there"}
<p>And another image goes here. {image=img2.jpg align=right caption="hello again"}
<?

ob_end_flush();?>
</p></body>
</html>

[/CODE]


Thanks for the opportunity to stretch my knowledge of PHP... now I just have to start using a few of these functions in my own code. :-)

Cheers
Fenric!
0
 

Author Comment

by:markauk
ID: 12565143
Thanks Fenric. That does the trick perfectly.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

These days socially coordinated efforts have turned into a critical requirement for enterprises.
This article discusses four methods for overlaying images in a container on a web page
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
The viewer will learn how to dynamically set the form action using jQuery.
Suggested Courses
Course of the Month16 days, 11 hours left to enroll

864 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question