Ninja Editor
Это маленький, но удаленький текстовый редактор для Вашего блога
[rus]
Зачем:
1. Простота (несколько экранов кода)
2. Быстродействие (около килобайта)
3. Защита от спама (ссылки закрываются от индексирования, «обессмысливая» спам в комментах)
4. Автоматическая конвертация строк вида http:… в ссылки
5. Автоматическая конвертация ссылок вида http:… gif, png, jpg в картинки
6. Можно добавить сколько угодно тегов
7. Подсветка синаксиса (тег php)
8. Защита от XSS инъекций
9. Всякие бессмысленные символы, стили при копи-пасте из ворда, других сайтов и т.п. — просто не вставляются.
10. Легкость установки (скопировать 2 файла)
PlayGround
Оформил более менее площадку 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 == 0 & $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" & $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_encoded, 0, 240);
$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] == 1 & $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'><a >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_id, results, totalvotes) {
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 = 3 + 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;'>&nbsp;</div>";
results[removed] += "<div style='color: #666666;'>";
results[removed] += ""+percentage+"%";
results[removed] += "&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);'>&#171; {/literal}{$poll36}{literal}</a></div>";
pollView(poll_id);
for(i=0;i<options_array.length;i++) {
width = 3 + 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', {duration: 1000, transition: Fx.Transitions.Quad.easeOut});
widthChange.start(3, width);
}
}
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]
<!--
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->photo_size($user->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}
//-->
[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'>
<form acti>poll_info.poll_id}_iframe' id='poll{$poll_object->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><input type='radio' value='{$smarty.section.options_loop.iteration}' name='poll{$poll_object->poll_info.poll_id}_options' id='poll{$poll_object->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;'>
<input type='submit' class='button' value='{$poll24}'>
{$poll25} <a href='[removed]void(0)'>poll_info.poll_id}');">{$poll7}</a>
<input type='hidden' name='poll_id' value='{$poll_object->poll_info.poll_id}'>
<input type='hidden' name='poll{$poll_object->poll_info.poll_id}_viewonly' id='poll{$poll_object->poll_info.poll_id}_viewonly' value='0'>
<input type='hidden' name='task' value='dovote'>
<input type='hidden' name='user' value='{$owner->user_info.user_username}'>
</form>
</div>
</div>
<iframe src="about:blank" style='display: none; width: 1px; height: 1px;' frameborder='no' name='poll{$poll_object->poll_info.poll_id}_iframe' id='poll{$poll_object->poll_info.poll_id}_iframe'></iframe>
</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>
</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'>
<form action='poll.php' method='post' target='AddCommentWindow' >
{include_php file='example.php'}
<textarea name='comment_body' id='comment_body' rows='7' cols='65' onfocus='removeText(this)' >{$poll14}</textarea>
<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;'><input type='text' name='comment_secure' id='comment_secure' class='text' size='6' maxlength='10'></td>
<td width='10'><img src='./images/icons/tip.gif' border='0' class='icon' ></td>
{/if}
<td align='right' style='padding-top: 5px;'>
<input type='submit' id='comment_submit' class='button' value='{$poll18}'>
<input type='hidden' name='user' value='{$owner->user_info.user_username}'>
<input type='hidden' name='poll_id' value='{$poll_object->poll_info.poll_id}'>
<input type='hidden' name='task' value='dopost'>
</form>
</td>
</tr>
</table>
<div id='comment_error' style='color: #FF0000; display: none;'></div>
<iframe name='AddCommentWindow' style='display: none' src=''></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->photo_size($comments[comment_loop].comment_author->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!
2viprus: Привет.. Ты бы ещё исходники zenda сюда запостил..
1. У тебя должна быть форма textarea c именем comments, например
2. Пишешь это имя в html_insert_ninja(имя)
<?php
echo html_insert_ninja('comments');
$body = nl2br(text_process($this->input->post("comments")));
?>
Всё.