Ninja Editor

Ninja Editor
Это маленький, но удаленький текстовый редактор для Вашего блога

[rus]
Зачем:
1. Простота (несколько экранов кода)
2. Быстродействие (около килобайта)
3. Защита от спама (ссылки закрываются от индексирования, «обессмысливая» спам в комментах)
4. Автоматическая конвертация строк вида http:… в ссылки
5. Автоматическая конвертация ссылок вида http:… gif, png, jpg в картинки
6. Можно добавить сколько угодно тегов
7. Подсветка синаксиса (тег php)
8. Защита от XSS инъекций
9. Всякие бессмысленные символы, стили при копи-пасте из ворда, других сайтов и т.п. — просто не вставляются.
10. Легкость установки (скопировать 2 файла)

PlayGround

 (0) Написал recoilme, 2008-09-02 17:46:36  ответить

Оформил более менее площадку playground'а для редактора

(0)  Написал recoilme, 2008-09-23 19:59:18  ответить

привет! Во-первых, огромное спасибо за замечательный Editor!

Если не сложно, помоги пожалуйста. Дело в том, что никак не могу добиться вывода его на своем сайте комментов..



например есть poll.php





<?php
<?
$page "poll";
include 
"header.php";

// DISPLAY ERROR PAGE IF USER IS NOT LOGGED IN AND ADMIN SETTING REQUIRES REGISTRATION
if($user->user_exists == &amp$setting[setting_permission_poll] == 0) {
  
$page "error";
  
$smarty->assign('error_header'$poll[13]);
  
$smarty->assign('error_message'$poll[23]);
  
$smarty->assign('error_submit'$poll[22]);
  include 
"footer.php";
}

// DISPLAY ERROR PAGE IF NO POLL OWNER
if($owner->user_exists == 0) {
  
$page "error";
  
$smarty->assign('error_header'$poll[13]);
  
$smarty->assign('error_message'$poll[12]);
  
$smarty->assign('error_submit'$poll[22]);
  include 
"footer.php";
}

// ENSURE POLLS ARE ENABLED FOR THIS USER
if($owner->level_info[level_poll_allow] == 0) { header("Location: ".$url->url_create('profile'$owner->user_info[user_username])); exit(); }

if(isset(
$_POST['task'])) { $task $_POST['task']; } elseif(isset($_GET['task'])) { $task $_GET['task']; } else { $task "main"; }
if(isset(
$_GET['poll_id'])) { $poll_id $_GET['poll_id']; } elseif(isset($_POST['poll_id'])) { $poll_id $_POST['poll_id']; } else { $poll_id 0; }

// INITIALIZE POLL OBJECT
$poll_object = new se_poll($user->user_info[user_id], $poll_id);
$poll_object->poll_info[poll_voted_array] = explode(","$poll_object->poll_info[poll_voted]);
if(
$poll_object->poll_info[poll_user_id] != $owner->user_info[user_id] || $poll_object->poll_exists == 0) { 
  
$page "error";
  
$smarty->assign('error_header'$poll[13]);
  
$smarty->assign('error_message'$poll[12]);
  
$smarty->assign('error_submit'$poll[22]);
  include 
"footer.php";
}

// GET PRIVACY LEVEL
$privacy_level $owner->user_privacy_max($user$owner->level_info[level_poll_privacy]);
if(
$privacy_level true_privacy($poll_object->poll_info[poll_privacy], $owner->level_info[level_poll_privacy])) {
  
$page "error";
  
$smarty->assign('error_header'$poll[13]);
  
$smarty->assign('error_message'$poll[1]);
  
$smarty->assign('error_submit'$poll[22]);
  include 
"footer.php";
}

// GET ENTRY COMMENT PRIVACY
$allowed_to_comment 1;
$comment_level $owner->user_privacy_max($user$owner->level_info[level_poll_comments]);
if(
$comment_level true_privacy($poll_object->poll_info[poll_comments], $owner->level_info[level_poll_comments])) { $allowed_to_comment 0; }

// IF A COMMENT IS BEING POSTED
if($task == "dopost" &amp$allowed_to_comment != 0) {

  
$comment_date time();
  
$comment_body $_POST['comment_body'];

  
// RETRIEVE AND CHECK SECURITY CODE IF NECESSARY
  
if($setting[setting_comment_code] != 0) {
    
session_start();
    
$code $_SESSION['code'];
    if(
$code == "") { $code randomcode(); }
    
$comment_secure $_POST['comment_secure'];

    if(
$comment_secure != $code) { $is_error 1; }
  }

  
// MAKE SURE COMMENT BODY IS NOT EMPTY
  
$comment_body censor(str_replace("\r\n""<br>"$comment_body));
  
$comment_body preg_replace('/(<br>){3,}/is''<br><br>'$comment_body);
  
$comment_body ChopText($comment_body);
$comment_body str_replace("\r\n"""html_entity_decode($_POST[comment_body]));
  if(
str_replace(" """$comment_body) == "") { $is_error 1$comment_body ""; }

  
// ADD COMMENT IF NO ERROR
  
if($is_error == 0) {
    
$database->database_query("INSERT INTO se_pollcomments (pollcomment_poll_id, pollcomment_authoruser_id, pollcomment_date, pollcomment_body) VALUES ('".$poll_object->poll_info[poll_id]."', '".$user->user_info[user_id]."', '$comment_date', '$comment_body')");

    
// INSERT ACTION IF USER EXISTS
    
if($user->user_exists != 0) {
      
$commenter $user->user_info[user_username];
      
$comment_body_encoded $comment_body;
      if(
strlen($comment_body_encoded) > 250) { 
        
$comment_body_encoded substr($comment_body_encoded0240);
        
$comment_body_encoded .= "...";
      }
      
$comment_body_encoded htmlspecialchars(str_replace("<br>"" "$comment_body_encoded));
      
$actions->actions_add($user"pollcomment", Array('[username1]''[username2]''[id]''[comment]'), Array($commenter$owner->user_info[user_username], $poll_id$comment_body_encoded));
    } else {
      
$commenter $poll[11];
    }

    
// SEND COMMENT NOTIFICATION IF NECESSARY
    
$owner->user_settings();
    if(
$owner->usersetting_info[usersetting_notify_pollcomment] == &amp$owner->user_info[user_id] != $user->user_info[user_id]) { 
      
send_generic($owner->user_info[user_email], "$setting[setting_email_fromname] <$setting[setting_email_fromemail]>"$setting[setting_email_pollcomment_subject], $setting[setting_email_pollcomment_message], Array('[username]''[commenter]''[link]'), Array($owner->user_info[user_username], $commenter"<a >url_create("poll", $owner->user_info[user_username], $poll_object->poll_info[poll_id])."">".$url->url_create("poll"$owner->user_info[user_username], $poll_object->poll_info[poll_id])."</a>")); 
    }

  }

  echo 
"<html><head><meta http-equiv='Content-Type' c>";
  echo 
"[removed]";
  echo 
"window.parent.addComment('$is_error', '$comment_body', '$comment_date');";
  echo 
"[removed]</head><body></body></html>";
  exit();
}


// GET POLL COMMENTS
$comment = new se_comment('poll''poll_id'$poll_object->poll_info[poll_id]);
$total_comments $comment->comment_total();
$comments $comment->comment_list(0$total_comments);

// UPDATE POLL VIEWS
$poll_views $poll_object->poll_info[poll_views]+1;
$database->database_query("UPDATE se_polls SET poll_views='$poll_views' WHERE poll_id='".$poll_object->poll_info[poll_id]."'");

// GET RESULTS
$poll_results implode("[!]"$poll_object->poll_info[poll_options]);
$poll_results .= "[!!]";
$poll_results .= implode("[!]"$poll_object->poll_info[poll_answers]);

$smarty->assign('comments'$comments);
$smarty->assign('total_comments'$total_comments);
$smarty->assign('allowed_to_comment'$allowed_to_comment);
$smarty->assign('poll_object'$poll_object);
$smarty->assign('poll_id'$poll_id);
$smarty->assign('poll_results'$poll_results);
include 
"footer.php";
?>?>






и есть poll.tpl





<?php
{include file='header.tpl'}
[
removed][removed]
<
div class='content_header'>
<
div class='page_header'><>url_create('profile'$owner->user_info.user_username)}'>{$owner->user_info.user_username}</a>{$poll31} <a >url_create('polls', $owner->user_info.user_username)}'>{$poll32}</a></div>
</
div>

<
div class='content'>

{* 
JAVASCRIPT FOR POLLS *}
{
literal}
[
removed]
function 
pollGetResults(poll_id) {
  
document.getElementById('poll'+poll_id+'_viewonly').value 1;
  
document.getElementById('poll'+poll_id+'_form').submit();
}
function 
pollVote(poll_idresultstotalvotes) {
  var 
results_array results.split("[!!]");
  var 
options_array results_array[0].split("[!]");
  var 
answers_array results_array[1].split("[!]");
  var 
results document.getElementById('poll'+poll_id+'_results');
  if(
document.getElementById('poll'+poll_id+'_viewonly').value == 0) {
    
document.getElementById('poll'+poll_id+'_totalvotes')[removed] = parseFloat(document.getElementById('poll'+poll_id+'_totalvotes')[removed]) + 1;
  }
  
results[removed] = "";
  for(
i=0;i<options_array.length;i++) {
    
class1 i+1;
    if(
totalvotes == 0) { totalvotes 0.01; }
    
width Math.round((answers_array[i] / totalvotes) * 400);
    
percentage Math.round((answers_array[i] / totalvotes) * 100);
    
results[removed] += "<div style='margin-bottom: 3px;'>"+options_array[i]+"</div>";
    
results[removed] += "<div class='poll_bar"+class1+"' id='poll"+poll_id+"_bar"+i+"' style='width: 3px;'>&amp;nbsp;</div>";
    
results[removed] += "<div style='color: #666666;'>";
    
results[removed] += ""+percentage+"%";
    
results[removed] += "&amp;nbsp;<span style='font-weight: normal;'>("+answers_array[i]+" {/literal}{$poll35}{literal})</span>";      
    
results[removed] += "</div><br><br>";
  }
  
results[removed] += "<div style='margin-top: 10px; font-weight: normal;'><a href='[removed]void(0);'>&amp;#171; {/literal}{$poll36}{literal}</a></div>";
  
pollView(poll_id);
  for(
i=0;i<options_array.length;i++) {
    
width Math.round((answers_array[i] / totalvotes) * 400);
    
percentage Math.round((answers_array[i] / totalvotes) * 100);
    var 
theElement "poll"+poll_id+"_bar"+i;
    var 
widthChange = new Fx.Style(theElement'width', {duration1000transitionFx.Transitions.Quad.easeOut});
    
widthChange.start(3width);
  }
}
function 
pollView(poll_id) {
  
document.getElementById('poll'+poll_id+'_results').style.display "block";
  
document.getElementById('poll'+poll_id+'_vote').style.display "none";
}
function 
pollReturn(poll_id) {
  
document.getElementById('poll'+poll_id+'_results').style.display "none";
  
document.getElementById('poll'+poll_id+'_vote').style.display "block";
  
document.getElementById('poll'+poll_id+'_viewonly').value 0;
}
//-->
[removed]
{/
literal}

{* 
JAVASCRIPT FOR ADDING COMMENT *}
{
literal}
[
removed]
<!--
var 
comment_changed 0;
var 
last_comment = {/literal}{$comments|@count}{literal};
var 
next_comment last_comment+1;
var 
total_comments = {/literal}{$total_comments}{literal};

function 
removeText(commentBody) {
  if(
comment_changed == 0) {
    
commentBody.value='';
    
commentBody.style.color='#000000';
    
comment_changed 1;
  }
}

function 
addText(commentBody) {
  if(
commentBody.value (0)  Написал viprus, 2009-07-29 19:39:02  ответить

Продолжение



{* JAVASCRIPT FOR ADDING COMMENT *}

{literal}

[removed]

&lt;!--

var comment_changed = 0;

var last_comment = {/literal}{$comments|@count}{literal};

var next_comment = last_comment+1;

var total_comments = {/literal}{$total_comments}{literal};



function removeText(commentBody) {

if(comment_changed == 0) {

commentBody.value='';

commentBody.style.color='#000000';

comment_changed = 1;

}

}



function addText(commentBody) {

if(commentBody.value == '') {

commentBody.value = '{/literal}{$poll14}{literal}';

commentBody.style.color = '#888888';

comment_changed = 0;

}

}



function checkText() {

if(comment_changed == 0) {

var commentBody = document.getElementById('comment_body');

commentBody.value='';

}

var commentSubmit = document.getElementById('comment_submit');

commentSubmit.value = '{/literal}{$poll15}{literal}';

commentSubmit.disabled = true;



}



function addComment(is_error, comment_body, comment_date) {

if(is_error == 1) {

var commentError = document.getElementById('comment_error');

commentError.style.display = 'block';

if(comment_body == '') {

commentError[removed] = '{/literal}{$poll16}{literal}';

} else {

commentError[removed] = '{/literal}{$poll17}{literal}';

}

var commentSubmit = document.getElementById('comment_submit');

commentSubmit.value = '{/literal}{$poll18}{literal}';

commentSubmit.disabled = false;

} else {

var commentError = document.getElementById('comment_error');

commentError.style.display = 'none';

commentError[removed] = '';



var commentBody = document.getElementById('comment_body');

commentBody.value = '';

addText(commentBody);



var commentSubmit = document.getElementById('comment_submit');

commentSubmit.value = '{/literal}{$poll18}{literal}';

commentSubmit.disabled = false;



if(document.getElementById('comment_secure')) {

var commentSecure = document.getElementById('comment_secure');

commentSecure.value=''

var secureImage = document.getElementById('secure_image');

secureImage.src = secureImage.src + '?' + (new Date()).getTime();

}



total_comments++;

var totalComments = document.getElementById('total_comments');

totalComments[removed] = total_comments;



var newComment = document.createElement('div');

var divIdName = 'comment_'+next_comment;

newComment.setAttribute('id',divIdName);

var newTable = "<table cellpadding='0' cellspacing='0' width='100%'><tr><td class='poll_item1' width='80'>";

{/literal}

{if $user->user_info.user_id != 0}

newTable += "<a >url_create('profile',$user->user_info.user_username)}'><img >user_photo('./images/nophoto.gif')}' class='photo' border='0' width='{$misc-&gt;photo_size($user-&gt;user_photo('./images/nophoto.gif'),'75','75','w')}'></a></td><td class='poll_item2'><table cellpadding='0' cellspacing='0' width='100%'><tr><td class='poll_comment_author'><b><a >url_create('profile',$user->user_info.user_username)}'>{$user->user_info.user_username}</a></b> - {$datetime->cdate("`$setting.setting_timeformat` `$poll21` `$setting.setting_dateformat`", $datetime->timezone($smarty.now, $global_timezone))}</td>";

{else}

newTable += "<img src='./images/nophoto.gif' class='photo' border='0' width='75'></td><td class='poll_item2'><table cellpadding='0' cellspacing='0' width='100%'><tr><td class='poll_comment_author'><b>{$poll11}</b> - {$datetime->cdate("`$setting.setting_timeformat` `$poll21` `$setting.setting_dateformat`", $datetime->timezone($smarty.now, $global_timezone))}</td>";

{/if}

newTable += "</tr><tr><td class='poll_comment_body'>"+comment_body+"</td></tr><tr><td class='poll_comment_author2' nowrap='nowrap'><a >user_info.user_username}'>{$poll20}</a></td></tr></table></td></tr></table>";

{literal}

newComment[removed] = newTable;

var pollComments = document.getElementById('poll_comments');

var prevComment = document.getElementById('comment_'+last_comment);

pollComments.insertBefore(newComment, prevComment);

next_comment++;

last_comment++;

}

}



{/literal}{if $user->user_info.user_id|in_array:$poll_object->poll_info.poll_voted_array}{literal}

window.addEvent('domready', function() {

{/literal}pollVote('{$poll_object->poll_info.poll_id}', '{$poll_results}', '{$poll_object->poll_info.poll_totalvotes}');{literal}

});

{/literal}{/if}{literal}



//--&gt;

[removed]

{/literal}



{* SHOW THIS POLL *}

<table cellpadding='0' cellspacing='0' width='100%'>

<tr>

<td valign='top' class='poll_view'>



{* TITLE AND DESCRIPTION *}

<div class='poll_view_title'>

{$poll_object->poll_info.poll_title|truncate:75:"...":true}

</div>

<div class='poll_view_stats'>

{$poll2} {$datetime->cdate("`$setting.setting_dateformat`", $datetime->timezone("`$poll_object->poll_info.poll_datecreated`", $global_timezone))}, <span id='poll{$poll_object->poll_info.poll_id}_totalvotes'>{$poll_object->poll_info.poll_totalvotes}</span> {$poll3} {$total_comments} {$poll4} {$poll_object->poll_info.poll_views} {$poll5}

</div>

<div style='padding: 5px;'>

{$poll_object->poll_info.poll_desc|choptext:120:"<br>"}

</div>



{* RESULTS *}

<div style='padding: 5px; font-weight: bold; display: none;' id='poll{$poll_object->poll_info.poll_id}_results'></div>



{* OPTIONS AND VOTE BUTTON *}

<div style='padding: 5px;' id='poll{$poll_object->poll_info.poll_id}_vote'>

&lt;form acti&gt;poll_info.poll_id}_iframe' id='poll{$poll_object-&gt;poll_info.poll_id}_form'>

{section name=options_loop loop=$poll_object->poll_info.poll_options}

<div style='padding: 3px 3px 3px 0px;'>

<table cellpadding='0' cellspacing='0'>

<tr>

<td>&lt;input type='radio' value='{$smarty.section.options_loop.iteration}' name='poll{$poll_object-&gt;poll_info.poll_id}_options' id='poll{$poll_object-&gt;poll_info.poll_id}_option{$smarty.section.options_loop.iteration}'></td>

<td style='font-weight: bold;'><label for='poll{$poll_object->poll_info.poll_id}_option{$smarty.section.options_loop.iteration}'>{$poll_object->poll_info.poll_options[options_loop]}</label></td>

</tr>

</table>

</div>

{/section}

<div style='margin-top: 10px;'>

&lt;input type='submit' class='button' value='{$poll24}'&gt;&nbsp;

{$poll25} <a href='[removed]void(0)'>poll_info.poll_id}');">{$poll7}</a>

&lt;input type='hidden' name='poll_id' value='{$poll_object-&gt;poll_info.poll_id}'>

&lt;input type='hidden' name='poll{$poll_object-&gt;poll_info.poll_id}_viewonly' id='poll{$poll_object-&gt;poll_info.poll_id}_viewonly' value='0'>

&lt;input type='hidden' name='task' value='dovote'&gt;

&lt;input type='hidden' name='user' value='{$owner-&gt;user_info.user_username}'>

&lt;/form&gt;

</div>

</div>



&lt;iframe src="about:blank" style='display: none; width: 1px; height: 1px;' frameborder='no' name='poll{$poll_object-&gt;poll_info.poll_id}_iframe' id='poll{$poll_object-&gt;poll_info.poll_id}_iframe'>&lt;/iframe&gt;

</td>

</tr>

</table>



<br>



<div>

<a >url_create('polls', $owner->user_info.user_username)}'><img src='./images/icons/back16.gif' border='0' class='icon'>{$poll26} {$owner->user_info.user_username}{$poll30}</a>

&nbsp;&nbsp;&nbsp;



</div>



<br>





{* BEGIN COMMENTS *}

<table cellpadding='0' cellspacing='0' width='100%'>

<tr>

<td class='home_header'>

{$poll8} (<span id='total_comments'>{$total_comments}</span>)

</td>

</tr>

{if $allowed_to_comment != 0}

<tr id='poll_postcomment'>

<td class='poll_postcomment'>

&lt;form action='poll.php' method='post' target='AddCommentWindow' &gt;



{include_php file='example.php'}





&lt;textarea name='comment_body' id='comment_body' rows='7' cols='65' onfocus='removeText(this)' &gt;{$poll14}&lt;/textarea&gt;



<table cellpadding='0' cellspacing='0' width='100%'>

<tr>

{if $setting.setting_comment_code == 1}

<td width='75' valign='top'><img src='./images/secure.php' id='secure_image' border='0' height='20' width='67' class='signup_code'></td>

<td width='68' style='padding-top: 4px;'>&lt;input type='text' name='comment_secure' id='comment_secure' class='text' size='6' maxlength='10'&gt;&lt;/td>

<td width='10'><img src='./images/icons/tip.gif' border='0' class='icon' ></td>

{/if}

<td align='right' style='padding-top: 5px;'>

&lt;input type='submit' id='comment_submit' class='button' value='{$poll18}'&gt;

&lt;input type='hidden' name='user' value='{$owner-&gt;user_info.user_username}'>

&lt;input type='hidden' name='poll_id' value='{$poll_object-&gt;poll_info.poll_id}'>

&lt;input type='hidden' name='task' value='dopost'&gt;

&lt;/form&gt;

</td>

</tr>

</table>

<div id='comment_error' style='color: #FF0000; display: none;'></div>

&lt;iframe name='AddCommentWindow' style='display: none' src=''&gt;&lt;/iframe>

</td>

</tr>

{/if}

<tr>

<td class='poll' id='poll_comments'>



{* LOOP THROUGH POLL COMMENTS *}

{section name=comment_loop loop=$comments}

<div id='comment_{math equati>

<table cellpadding='0' cellspacing='0' width='100%'>

<tr>

<td class='poll_item1' width='80'>

{if $comments[comment_loop].comment_author->user_info.user_id != 0}

<a >url_create('profile',$comments[comment_loop].comment_author->user_info.user_username)}'><img >user_thumb('./images/nophoto.gif')}' class='photo' border='0' width='{$misc-&gt;photo_size($comments[comment_loop].comment_author-&gt;user_photo('./images/nophoto.gif'),'55','55','w')}'></a>

{else}

<img src='./images/nophoto.gif' class='photo' border='0' width='55'>

{/if}

</td>

<td class='poll_item2'>

<table cellpadding='0' cellspacing='0' width='100%'>

<tr>

<td class='poll_comment_author'><b>{if $comments[comment_loop].comment_author->user_info.user_id != 0}<a >url_create('profile',$comments[comment_loop].comment_author->user_info.user_username)}'>{$comments[comment_loop].comment_author->user_info.user_username}</a>{else}{$poll11}{/if}</b> - {$datetime->cdate("`$setting.setting_timeformat` `$poll21` `$setting.setting_dateformat`", $datetime->timezone($comments[comment_loop].comment_date, $global_timezone))}</td>

</tr>

<tr>

<td class='poll_comment_body'>{$comments[comment_loop].comment_body}</td>

</tr>

<tr>



</tr>

</table>

</td>

</tr>

</table>

</div>

{/section}



</td>

</tr>

</table>

{* END COMMENTS *}





{include file='footer.tpl'}

[/php]



в poll.tpl подключаю {include_php file='example.php'}, который выглядит так:



<?php<html>
<
head>
<
title></title>
<
meta http-equiv="Content-Type" c>
<?
php include('ninja_helper.php'?>
<?php 
echo js_insert_ninja(); ?>
<?php 
echo css_insert_ninja('500px'); ?>
</head>
<body>
<form name="blog" method="POST">
<?php echo html_insert_ninja('comments'); ?>



</form>
<?php
if(isset($_POST['comment_submit']))
{
 echo 
bb_parse($_POST['comments']);
}

?>
</body>
</html>?>






но загрузки комментов не происходит.. как будто данные отсылаются и не выводятся... два дня промаялся никак.. Огромное спасибо, recoilme!

(0)  Написал viprus, 2009-07-29 19:41:46  ответить

2viprus: Привет.. Ты бы ещё исходники zenda сюда запостил..

1. У тебя должна быть форма textarea c именем comments, например

2. Пишешь это имя в html_insert_ninja(имя)



<?php
echo html_insert_ninja('comments');
$body nl2br(text_process($this->input->post("comments")));
?>





Всё.

(0)  Написал recoilme, 2009-08-05 11:53:23  ответить

2recoilme: спасибо огромное!!!

(0)  Написал viprus, 2009-09-10 09:40:28  ответить



Маслобензостойкие уплотнительные кольца . компьютерная помощь . В нашем каталоге подарочные: карта памяти, флеш-память, флешка, карта флешь-памяти в Москве . Хочу порекомендовать всем компанию Аптека ТРиКА - лекарства на дом для детей . Действуют скидки! . ремонт квартир в Измайлово