How to create Pinterest-like script – step 4 Welcome our friends and sorry for the delay, I had to do a lot of things in real life. But in any case, I am glad to give you our fourth lesson where we create our own Pinterest like script. Today I added the ajaxy comment system and profile pages here. We can now write our own comments (this is available for logged users) directly on our pins, or on larger versions (popups)of images as well. Today I will publish all updated files of our script, in case if you want to investigate it at your local computer – you always can download full package with sources.
如何创建类似Pinterest的脚本-步骤4欢迎我们的朋友们,对不起您的延迟,我不得不在现实生活中做很多事情。 但是无论如何,我很高兴为您提供第四课,我们将创建自己的Pinterest脚本。 今天,我在这里添加了ajaxy评论系统和个人资料页面。 现在,我们可以直接在图钉上或在较大版本的图像(弹出窗口)上写下我们自己的注释(登录的用户可用)。 今天,我将发布脚本的所有更新文件,以防万一您想在本地计算机上进行调查–您始终可以下载带有源代码的完整软件包。
Now you are welcome to try our demo and download the source package here:
现在,欢迎您尝试我们的演示并在此处下载源代码包:
现场演示
[sociallocker]
[社交储物柜]
打包下载
[/sociallocker]
[/ sociallocker]
步骤1. HTML (Step 1. HTML)
As I told, I added profile pages. As usual, I’m going to push whole html layout into single template file (so, you will be able to modify it easily):
就像我说的,我添加了个人资料页面。 和往常一样,我将把整个html布局推送到单个模板文件中(因此,您将能够轻松地对其进行修改):
templates / profile.html (templates/profile.html)
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="utf-8" />
<meta name="author" content="Script Tutorials" />
<title>How to create Pinterest-like script - step 4 | Script Tutorials</title>
<!-- add styles -->
<link href="css/main.css" rel="stylesheet" type="text/css" />
<link href="css/colorbox.css" rel="stylesheet" type="text/css" />
<!-- add scripts -->
<script src="js/jquery.min.js"></script>
<script src="js/jquery.colorbox-min.js"></script>
<script src="js/jquery.masonry.min.js"></script>
<script src="js/script.js"></script>
</head>
<body>
<!-- header panel -->
<div class="header_panel">
<!-- logo -->
<a href="index.php" class="logo"></a>
<!-- search form -->
<form action="" method="get" class="search">
<input autocomplete="off" name="q" size="27" placeholder="Search" type="text" />
<input name="search" type="submit" />
</form>
<!-- navigation menu -->
<ul class="nav">
<li>
<a href="#">About<span></span></a>
<ul>
<li><a href="#">Help</a></li>
<li><a href="#">Pin It Button</a></li>
<li><a href="#" target="_blank">For Businesses</a></li>
<li class="div"><a href="#">Careers</a></li>
<li><a href="#">Team</a></li>
<li><a href="#">Blog</a></li>
<li class="div"><a href="#">Terms of Service</a></li>
<li><a href="#">Privacy Policy</a></li>
<li><a href="#">Copyright</a></li>
<li><a href="#">Trademark</a></li>
</ul>
</li>
{menu_elements}
<li>
<a href="https://www.script-tutorials.com/pinterest-like-script-step-4/">Back to tutorial</a>
</li>
</ul>
</div>
{extra_data}
<h2 class="pname">Profile {profile_name}</h2>
<!-- main container -->
<div class="main_container">
{images_set}
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="utf-8" />
<meta name="author" content="Script Tutorials" />
<title>How to create Pinterest-like script - step 4 | Script Tutorials</title>
<!-- add styles -->
<link href="css/main.css" rel="stylesheet" type="text/css" />
<link href="css/colorbox.css" rel="stylesheet" type="text/css" />
<!-- add scripts -->
<script src="js/jquery.min.js"></script>
<script src="js/jquery.colorbox-min.js"></script>
<script src="js/jquery.masonry.min.js"></script>
<script src="js/script.js"></script>
</head>
<body>
<!-- header panel -->
<div class="header_panel">
<!-- logo -->
<a href="index.php" class="logo"></a>
<!-- search form -->
<form action="" method="get" class="search">
<input autocomplete="off" name="q" size="27" placeholder="Search" type="text" />
<input name="search" type="submit" />
</form>
<!-- navigation menu -->
<ul class="nav">
<li>
<a href="#">About<span></span></a>
<ul>
<li><a href="#">Help</a></li>
<li><a href="#">Pin It Button</a></li>
<li><a href="#" target="_blank">For Businesses</a></li>
<li class="div"><a href="#">Careers</a></li>
<li><a href="#">Team</a></li>
<li><a href="#">Blog</a></li>
<li class="div"><a href="#">Terms of Service</a></li>
<li><a href="#">Privacy Policy</a></li>
<li><a href="#">Copyright</a></li>
<li><a href="#">Trademark</a></li>
</ul>
</li>
{menu_elements}
<li>
<a href="https://www.script-tutorials.com/pinterest-like-script-step-4/">Back to tutorial</a>
</li>
</ul>
</div>
{extra_data}
<h2 class="pname">Profile {profile_name}</h2>
<!-- main container -->
<div class="main_container">
{images_set}
</div>
</body>
</html>
步骤2. PHP (Step 2. PHP)
Now, please check PHP code of our profile page:
现在,请检查我们的个人资料页面PHP代码:
profile.php (profile.php)
// set warning level
if (version_compare(phpversion(), '5.3.0', '>=') == 1)
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
else
error_reporting(E_ALL & ~E_NOTICE);
require_once('classes/CMySQL.php');
require_once('classes/CMembers.php');
require_once('classes/CPhotos.php');
// get login data
list ($sLoginMenu, $sExtra) = $GLOBALS['CMembers']->getLoginData();
// profile id
$i = (int)$_GET['id'];
if ($i) {
$aMemberInfo = $GLOBALS['CMembers']->getProfileInfo($_SESSION['member_id']);
if ($aMemberInfo) {
// get all photos by profile
$sPhotos = $GLOBALS['CPhotos']->getAllPhotos($i);
// draw profile page
$aKeys = array(
'{menu_elements}' => $sLoginMenu,
'{extra_data}' => $sExtra,
'{images_set}' => $sPhotos,
'{profile_name}' => $aMemberInfo['first_name'],
);
echo strtr(file_get_contents('templates/profile.html'), $aKeys);
exit;
}
}
header('Location: error.php');
// set warning level
if (version_compare(phpversion(), '5.3.0', '>=') == 1)
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
else
error_reporting(E_ALL & ~E_NOTICE);
require_once('classes/CMySQL.php');
require_once('classes/CMembers.php');
require_once('classes/CPhotos.php');
// get login data
list ($sLoginMenu, $sExtra) = $GLOBALS['CMembers']->getLoginData();
// profile id
$i = (int)$_GET['id'];
if ($i) {
$aMemberInfo = $GLOBALS['CMembers']->getProfileInfo($_SESSION['member_id']);
if ($aMemberInfo) {
// get all photos by profile
$sPhotos = $GLOBALS['CPhotos']->getAllPhotos($i);
// draw profile page
$aKeys = array(
'{menu_elements}' => $sLoginMenu,
'{extra_data}' => $sExtra,
'{images_set}' => $sPhotos,
'{profile_name}' => $aMemberInfo['first_name'],
);
echo strtr(file_get_contents('templates/profile.html'), $aKeys);
exit;
}
}
header('Location: error.php');
This is very easy file as you see, it is similar as our index page, except for one – this page displays a profile name and his photos only. Now, in order to display his photos only, I had to modify CPhotos::getAllPhotos function. There is updated version:
如您所见,这是一个非常简单的文件,与我们的索引页面类似,除了一个页面-此页面仅显示个人资料名称和他的照片。 现在,为了只显示他的照片,我不得不修改CPhotos :: getAllPhotos函数。 有更新的版本:
function getAllPhotos($iPid = 0) {
$sFilter = ($iPid) ? "WHERE `owner` = '{$iPid}'" : '';
$sSQL = "
SELECT *
FROM `pd_photos`
{$sFilter}
ORDER BY `when` DESC
";
$aPhotos = $GLOBALS['MySQL']->getAll($sSQL);
$sPhotos = '';
$sFolder = 'photos/';
foreach ($aPhotos as $i => $aPhoto) {
$iPhotoId = (int)$aPhoto['id'];
$sFile = $aPhoto['filename'];
$sTitle = $aPhoto['title'];
$iCmts = (int)$aPhoto['comments_count'];
$aPathInfo = pathinfo($sFolder . $sFile);
$sExt = strtolower($aPathInfo['extension']);
$sImages .= <<<EOL
<!-- pin element {$iPhotoId} -->
<div class="pin" pin_id="{$iPhotoId}">
<div class="holder">
<div class="actions">
<a href="#" class="button">Repin</a>
<a href="#" class="button">Like</a>
<a href="#" class="button comment_tr">Comment</a>
</div>
<a class="image ajax" href="service.php?id={$iPhotoId}" title="{$sTitle}">
<img alt="{$sTitle}" src="{$sFolder}{$sFile}">
</a>
</div>
<p class="desc">{$sTitle}</p>
<p class="info">
<span>XX likes</span>
<span>XX repins</span>
<span>{$iCmts} comments</span>
</p>
<form class="comment" method="post" action="" style="display: none" onsubmit="return submitComment(this, {$iPhotoId})">
<textarea placeholder="Add a comment..." maxlength="255" name="comment"></textarea>
<input type="submit" class="button" value="Comment" />
</form>
</div>
EOL;
}
return $sImages;
}
function getAllPhotos($iPid = 0) {
$sFilter = ($iPid) ? "WHERE `owner` = '{$iPid}'" : '';
$sSQL = "
SELECT *
FROM `pd_photos`
{$sFilter}
ORDER BY `when` DESC
";
$aPhotos = $GLOBALS['MySQL']->getAll($sSQL);
$sPhotos = '';
$sFolder = 'photos/';
foreach ($aPhotos as $i => $aPhoto) {
$iPhotoId = (int)$aPhoto['id'];
$sFile = $aPhoto['filename'];
$sTitle = $aPhoto['title'];
$iCmts = (int)$aPhoto['comments_count'];
$aPathInfo = pathinfo($sFolder . $sFile);
$sExt = strtolower($aPathInfo['extension']);
$sImages .= <<<EOL
<!-- pin element {$iPhotoId} -->
<div class="pin" pin_id="{$iPhotoId}">
<div class="holder">
<div class="actions">
<a href="#" class="button">Repin</a>
<a href="#" class="button">Like</a>
<a href="#" class="button comment_tr">Comment</a>
</div>
<a class="image ajax" href="service.php?id={$iPhotoId}" title="{$sTitle}">
<img alt="{$sTitle}" src="{$sFolder}{$sFile}">
</a>
</div>
<p class="desc">{$sTitle}</p>
<p class="info">
<span>XX likes</span>
<span>XX repins</span>
<span>{$iCmts} comments</span>
</p>
<form class="comment" method="post" action="" style="display: none" onsubmit="return submitComment(this, {$iPhotoId})">
<textarea placeholder="Add a comment..." maxlength="255" name="comment"></textarea>
<input type="submit" class="button" value="Comment" />
</form>
</div>
EOL;
}
return $sImages;
}
Basically – I only added profile filter here, nothing more. Then, I prepared a new class for Comments:
基本上–我仅在此处添加了配置文件过滤器,仅此而已。 然后,我准备了一个新课来评论:
classes / CComments.php (classes/CComments.php)
/*
* Comments class
*/
class CComments {
// constructor
function CComments() {
}
// return comments block
function getComments($i) {
// draw last 5 comments
$sComments = '';
$aComments = $GLOBALS['MySQL']->getAll("SELECT * FROM `pd_items_cmts` WHERE `c_item_id` = '{$i}' ORDER BY `c_when` DESC LIMIT 5");
foreach ($aComments as $iCmtId => $aCmtsInfo) {
$sWhen = date('F j, Y H:i', $aCmtsInfo['c_when']);
$sComments .= <<<EOF
<div class="comment" id="{$aCmtsInfo['c_id']}">
<p>Comment from {$aCmtsInfo['c_name']} <span>({$sWhen})</span>:</p>
<p>{$aCmtsInfo['c_text']}</p>
</div>
EOF;
}
return $sComments;
}
function acceptComment() {
$iItemId = (int)$_POST['id']; // prepare necessary information
$sIp = $this->getVisitorIP();
$aMemberInfo = $GLOBALS['CMembers']->getProfileInfo($_SESSION['member_id']);
$sName = $GLOBALS['MySQL']->escape(strip_tags($aMemberInfo['first_name']));
$sText = $GLOBALS['MySQL']->escape(strip_tags($_POST['comment']));
if ($iItemId && $sName && strlen($sText) > 2) {
// check - if there is any recent comment from the same person (IP) or not (for last 5 mins)
$iOldId = $GLOBALS['MySQL']->getOne("SELECT `c_item_id` FROM `pd_items_cmts` WHERE `c_item_id` = '{$iItemId}' AND `c_ip` = '{$sIp}' AND `c_when` >= UNIX_TIMESTAMP() - 300 LIMIT 1");
if (! $iOldId) {
// if everything is fine - allow to add comment
$GLOBALS['MySQL']->res("INSERT INTO `pd_items_cmts` SET `c_item_id` = '{$iItemId}', `c_ip` = '{$sIp}', `c_when` = UNIX_TIMESTAMP(), `c_name` = '{$sName}', `c_text` = '{$sText}'");
$GLOBALS['MySQL']->res("UPDATE `pd_photos` SET `comments_count` = `comments_count` + 1 WHERE `id` = '{$iItemId}'");
// and print out last 5 comments
$sOut = '';
$aComments = $GLOBALS['MySQL']->getAll("SELECT * FROM `pd_items_cmts` WHERE `c_item_id` = '{$iItemId}' ORDER BY `c_when` DESC LIMIT 5");
foreach ($aComments as $i => $aCmtsInfo) {
$sWhen = date('F j, Y H:i', $aCmtsInfo['c_when']);
$sOut .= <<<EOF
<div class="comment" id="{$aCmtsInfo['c_id']}">
<p>Comment from {$aCmtsInfo['c_name']} <span>({$sWhen})</span>:</p>
<p>{$aCmtsInfo['c_text']}</p>
</div>
EOF;
}
return $sOut;
}
}
}
// get visitor IP
function getVisitorIP() {
$ip = "0.0.0.0";
if( ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) && ( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) ) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} elseif( ( isset( $_SERVER['HTTP_CLIENT_IP'])) && (!empty($_SERVER['HTTP_CLIENT_IP'] ) ) ) {
$ip = explode(".",$_SERVER['HTTP_CLIENT_IP']);
$ip = $ip[3].".".$ip[2].".".$ip[1].".".$ip[0];
} elseif((!isset( $_SERVER['HTTP_X_FORWARDED_FOR'])) || (empty($_SERVER['HTTP_X_FORWARDED_FOR']))) {
if ((!isset( $_SERVER['HTTP_CLIENT_IP'])) && (empty($_SERVER['HTTP_CLIENT_IP']))) {
$ip = $_SERVER['REMOTE_ADDR'];
}
}
return $ip;
}
}
$GLOBALS['Comments'] = new CComments();
/*
* Comments class
*/
class CComments {
// constructor
function CComments() {
}
// return comments block
function getComments($i) {
// draw last 5 comments
$sComments = '';
$aComments = $GLOBALS['MySQL']->getAll("SELECT * FROM `pd_items_cmts` WHERE `c_item_id` = '{$i}' ORDER BY `c_when` DESC LIMIT 5");
foreach ($aComments as $iCmtId => $aCmtsInfo) {
$sWhen = date('F j, Y H:i', $aCmtsInfo['c_when']);
$sComments .= <<<EOF
<div class="comment" id="{$aCmtsInfo['c_id']}">
<p>Comment from {$aCmtsInfo['c_name']} <span>({$sWhen})</span>:</p>
<p>{$aCmtsInfo['c_text']}</p>
</div>
EOF;
}
return $sComments;
}
function acceptComment() {
$iItemId = (int)$_POST['id']; // prepare necessary information
$sIp = $this->getVisitorIP();
$aMemberInfo = $GLOBALS['CMembers']->getProfileInfo($_SESSION['member_id']);
$sName = $GLOBALS['MySQL']->escape(strip_tags($aMemberInfo['first_name']));
$sText = $GLOBALS['MySQL']->escape(strip_tags($_POST['comment']));
if ($iItemId && $sName && strlen($sText) > 2) {
// check - if there is any recent comment from the same person (IP) or not (for last 5 mins)
$iOldId = $GLOBALS['MySQL']->getOne("SELECT `c_item_id` FROM `pd_items_cmts` WHERE `c_item_id` = '{$iItemId}' AND `c_ip` = '{$sIp}' AND `c_when` >= UNIX_TIMESTAMP() - 300 LIMIT 1");
if (! $iOldId) {
// if everything is fine - allow to add comment
$GLOBALS['MySQL']->res("INSERT INTO `pd_items_cmts` SET `c_item_id` = '{$iItemId}', `c_ip` = '{$sIp}', `c_when` = UNIX_TIMESTAMP(), `c_name` = '{$sName}', `c_text` = '{$sText}'");
$GLOBALS['MySQL']->res("UPDATE `pd_photos` SET `comments_count` = `comments_count` + 1 WHERE `id` = '{$iItemId}'");
// and print out last 5 comments
$sOut = '';
$aComments = $GLOBALS['MySQL']->getAll("SELECT * FROM `pd_items_cmts` WHERE `c_item_id` = '{$iItemId}' ORDER BY `c_when` DESC LIMIT 5");
foreach ($aComments as $i => $aCmtsInfo) {
$sWhen = date('F j, Y H:i', $aCmtsInfo['c_when']);
$sOut .= <<<EOF
<div class="comment" id="{$aCmtsInfo['c_id']}">
<p>Comment from {$aCmtsInfo['c_name']} <span>({$sWhen})</span>:</p>
<p>{$aCmtsInfo['c_text']}</p>
</div>
EOF;
}
return $sOut;
}
}
}
// get visitor IP
function getVisitorIP() {
$ip = "0.0.0.0";
if( ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) && ( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) ) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} elseif( ( isset( $_SERVER['HTTP_CLIENT_IP'])) && (!empty($_SERVER['HTTP_CLIENT_IP'] ) ) ) {
$ip = explode(".",$_SERVER['HTTP_CLIENT_IP']);
$ip = $ip[3].".".$ip[2].".".$ip[1].".".$ip[0];
} elseif((!isset( $_SERVER['HTTP_X_FORWARDED_FOR'])) || (empty($_SERVER['HTTP_X_FORWARDED_FOR']))) {
if ((!isset( $_SERVER['HTTP_CLIENT_IP'])) && (empty($_SERVER['HTTP_CLIENT_IP']))) {
$ip = $_SERVER['REMOTE_ADDR'];
}
}
return $ip;
}
}
$GLOBALS['Comments'] = new CComments();
There are only three functions now: getVisitorIP (to determinate IP of visitors), getComments (to return comments, by default – we display 5 last comments) and acceptComment (to accept comments and add them into database). Finally, I had to modify our service file:
现在只有三个功能:getVisitorIP(用于确定访问者的IP),getComments(用于返回评论,默认情况下-我们显示5条最后评论)和acceptComment(用于接受评论并将其添加到数据库中)。 最后,我不得不修改我们的服务文件:
service.php (service.php)
// set warning level
if (version_compare(phpversion(), '5.3.0', '>=') == 1)
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
else
error_reporting(E_ALL & ~E_NOTICE);
require_once('classes/CMySQL.php');
require_once('classes/CMembers.php');
require_once('classes/CPhotos.php');
require_once('classes/CComments.php');
if (! isset($_SESSION['member_id']) && $_POST['Join'] == 'Join') {
$GLOBALS['CMembers']->registerProfile();
}
$i = (int)$_GET['id'];
if ($_GET && $_GET['get'] == 'comments') {
header('Content-Type: text/html; charset=utf-8');
echo $GLOBALS['Comments']->getComments($i);
exit;
}
if ($_POST && $_POST['add'] == 'comment') {
if ($_SESSION['member_id'] && $_SESSION['member_status'] == 'active' && $_SESSION['member_role']) {
header('Content-Type: text/html; charset=utf-8');
echo $GLOBALS['Comments']->acceptComment();
exit;
}
header('Content-Type: text/html; charset=utf-8');
echo '<h3>Please login first</h3>';
exit;
}
if (! $i) { // if something is wrong - relocate to error page
header('Location: error.php');
exit;
}
$aPhotoInfo = $GLOBALS['CPhotos']->getPhotoInfo($i);
$aOwnerInfo = $GLOBALS['CMembers']->getProfileInfo($aPhotoInfo['owner']);
$sOwnerName = ($aOwnerInfo['first_name']) ? $aOwnerInfo['first_name'] : $aOwnerInfo['email'];
$sPhotoTitle = $aPhotoInfo['title'];
$sPhotoDate = $GLOBALS['CPhotos']->formatTime($aPhotoInfo['when']);
$sFolder = 'photos/';
$sFullImgPath = $sFolder . 'f_' . $aPhotoInfo['filename'];
$aSize = getimagesize($sFullImgPath); // get image info
$iWidth = $aSize[0];
$iHeight = $aSize[1];
?>
<div class="pin bigpin">
<div class="owner">
<a href="#" class="button follow_button">Follow</a>
<a class="owner_img" href="profile.php?id=<?= $aOwnerInfo['id'] ?>">
<img alt="<?= $sOwnerName ?>" src="images/avatar.jpg" />
</a>
<p class="owner_name"><a href="profile.php?id=<?= $aOwnerInfo['id'] ?>"><?= $sOwnerName ?></a></p>
<p class="owner_when">Uploaded on <?= $sPhotoDate ?></p>
</div>
<div class="holder">
<div class="actions">
<a href="#" class="button">Repin</a>
<a href="#" class="button">Like</a>
</div>
<a class="image" href="#" title="<?= $sPhotoTitle ?>">
<img alt="<?= $sPhotoTitle ?>" src="<?= $sFullImgPath ?>" style="width:<?= $iWidth ?>px;height:<?= $iHeight ?>px;" />
</a>
</div>
<p class="desc"><?= $sPhotoTitle ?></p>
<div class="comments"></div>
<script>
function submitCommentAjx() {
$.ajax({
type: 'POST',
url: 'service.php',
data: 'add=comment&id=' + <?= $i ?> + '&comment=' + $('#pcomment').val(),
cache: false,
success: function(html){
if (html) {
$('.comments').html(html);
$(this).colorbox.resize();
}
}
});
}
</script>
<form class="comment" method="post" action="#">
<textarea placeholder="Add a comment..." maxlength="255" id="pcomment"></textarea>
<button type="button" class="button" onclick="return submitCommentAjx()">Comment</button>
</form>
</div>
// set warning level
if (version_compare(phpversion(), '5.3.0', '>=') == 1)
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
else
error_reporting(E_ALL & ~E_NOTICE);
require_once('classes/CMySQL.php');
require_once('classes/CMembers.php');
require_once('classes/CPhotos.php');
require_once('classes/CComments.php');
if (! isset($_SESSION['member_id']) && $_POST['Join'] == 'Join') {
$GLOBALS['CMembers']->registerProfile();
}
$i = (int)$_GET['id'];
if ($_GET && $_GET['get'] == 'comments') {
header('Content-Type: text/html; charset=utf-8');
echo $GLOBALS['Comments']->getComments($i);
exit;
}
if ($_POST && $_POST['add'] == 'comment') {
if ($_SESSION['member_id'] && $_SESSION['member_status'] == 'active' && $_SESSION['member_role']) {
header('Content-Type: text/html; charset=utf-8');
echo $GLOBALS['Comments']->acceptComment();
exit;
}
header('Content-Type: text/html; charset=utf-8');
echo '<h3>Please login first</h3>';
exit;
}
if (! $i) { // if something is wrong - relocate to error page
header('Location: error.php');
exit;
}
$aPhotoInfo = $GLOBALS['CPhotos']->getPhotoInfo($i);
$aOwnerInfo = $GLOBALS['CMembers']->getProfileInfo($aPhotoInfo['owner']);
$sOwnerName = ($aOwnerInfo['first_name']) ? $aOwnerInfo['first_name'] : $aOwnerInfo['email'];
$sPhotoTitle = $aPhotoInfo['title'];
$sPhotoDate = $GLOBALS['CPhotos']->formatTime($aPhotoInfo['when']);
$sFolder = 'photos/';
$sFullImgPath = $sFolder . 'f_' . $aPhotoInfo['filename'];
$aSize = getimagesize($sFullImgPath); // get image info
$iWidth = $aSize[0];
$iHeight = $aSize[1];
?>
<div class="pin bigpin">
<div class="owner">
<a href="#" class="button follow_button">Follow</a>
<a class="owner_img" href="profile.php?id=<?= $aOwnerInfo['id'] ?>">
<img alt="<?= $sOwnerName ?>" src="images/avatar.jpg" />
</a>
<p class="owner_name"><a href="profile.php?id=<?= $aOwnerInfo['id'] ?>"><?= $sOwnerName ?></a></p>
<p class="owner_when">Uploaded on <?= $sPhotoDate ?></p>
</div>
<div class="holder">
<div class="actions">
<a href="#" class="button">Repin</a>
<a href="#" class="button">Like</a>
</div>
<a class="image" href="#" title="<?= $sPhotoTitle ?>">
<img alt="<?= $sPhotoTitle ?>" src="<?= $sFullImgPath ?>" style="width:<?= $iWidth ?>px;height:<?= $iHeight ?>px;" />
</a>
</div>
<p class="desc"><?= $sPhotoTitle ?></p>
<div class="comments"></div>
<script>
function submitCommentAjx() {
$.ajax({
type: 'POST',
url: 'service.php',
data: 'add=comment&id=' + <?= $i ?> + '&comment=' + $('#pcomment').val(),
cache: false,
success: function(html){
if (html) {
$('.comments').html(html);
$(this).colorbox.resize();
}
}
});
}
</script>
<form class="comment" method="post" action="#">
<textarea placeholder="Add a comment..." maxlength="255" id="pcomment"></textarea>
<button type="button" class="button" onclick="return submitCommentAjx()">Comment</button>
</form>
</div>
Now we can handle with comments! We use $.ajax function to POST comments to server. As soon as we post a new comment – server returns us (in response) 5 last comments, so we can update a list of last comments for an object (pin). Also, please pay attention, that our profiles have own links now (profile.php).
现在我们可以处理评论了! 我们使用$ .ajax函数将注释发布到服务器。 一旦我们发布了新评论,服务器就会向我们返回5条最新评论(作为响应),因此我们可以更新对象的最新评论列表(固定)。 另外,请注意,我们的配置文件现在具有自己的链接(profile.php)。
步骤3. CSS (Step 3. CSS)
I added only one little CSS property to our profile page (add this in the end of our styles file):
我仅向我们的个人资料页面添加了一个小CSS属性(将其添加到样式文件的末尾):
css / main.css (css/main.css)
/* profile page */
.pname {
font-size: 24px;
margin-bottom: 10px;
margin-top: 20px;
text-align: center;
}
/* profile page */
.pname {
font-size: 24px;
margin-bottom: 10px;
margin-top: 20px;
text-align: center;
}
步骤4. Javascript (Step 4. Javascript)
I updated our main script file. There are few changes: a new function to submit comments to the server, and, – to load comments (ajaxy) once we have opened a bigger photo using Colorbox.
我更新了主脚本文件。 变化不大:有一个新功能可将评论提交到服务器,以及–使用Colorbox打开更大的照片后即可加载评论(ajaxy)。
js / script.js (js/script.js)
function fileSelectHandler() {
// get selected file
var oFile = $('#image_file')[0].files[0];
// html5 file upload
var formData = new FormData($('#upload_form')[0]);
$.ajax({
url: 'upload.php', //server script to process data
type: 'POST',
// ajax events
beforeSend: function() {
},
success: function(e) {
$('#upload_result').html('Thank you for your photo').show();
setTimeout(function() {
$("#upload_result").hide().empty();
location.reload();
}, 4000);
},
error: function(e) {
$('#upload_result').html('Error while processing uploaded image');
},
// form data
data: formData,
// options to tell JQuery not to process data or worry about content-type
cache: false,
contentType: false,
processData: false
});
}
function submitComment(form, id) {
$.ajax({
type: 'POST',
url: 'service.php',
data: 'add=comment&id=' + id + '&comment=' + $(form).find('textarea').val(),
cache: false,
success: function(html){
if (html) {
location.reload();
}
}
});
return false;
}
$(document).ready(function(){
// file field change handler
$('#image_file').change(function(){
var file = this.files[0];
name = file.name;
size = file.size;
type = file.type;
// extra validation
if (name && size) {
if (! file.type.match('image.*')) {
alert("Select image please");
} else {
fileSelectHandler();
}
}
});
// masonry initialization
$('.main_container').masonry({
// options
itemSelector : '.pin',
isAnimated: true,
isFitWidth: true
});
// onclick event handler (for comments)
$('.comment_tr').click(function () {
$(this).toggleClass('disabled');
$(this).parent().parent().parent().find('form.comment').slideToggle(400, function () {
$('.main_container').masonry();
});
});
$('.ajax').colorbox({
onOpen:function(){
},
onLoad:function(){
},
onComplete:function(){
$(this).colorbox.resize();
var iPinId = $(this).parent().parent().attr('pin_id');
$.ajax({
url: 'service.php',
data: 'get=comments&id=' + iPinId,
cache: false,
success: function(html){
$('.comments').append(html);
$(this).colorbox.resize();
}
});
},
onCleanup:function(){
},
onClosed:function(){
}
});
});
function fileSelectHandler() {
// get selected file
var oFile = $('#image_file')[0].files[0];
// html5 file upload
var formData = new FormData($('#upload_form')[0]);
$.ajax({
url: 'upload.php', //server script to process data
type: 'POST',
// ajax events
beforeSend: function() {
},
success: function(e) {
$('#upload_result').html('Thank you for your photo').show();
setTimeout(function() {
$("#upload_result").hide().empty();
location.reload();
}, 4000);
},
error: function(e) {
$('#upload_result').html('Error while processing uploaded image');
},
// form data
data: formData,
// options to tell JQuery not to process data or worry about content-type
cache: false,
contentType: false,
processData: false
});
}
function submitComment(form, id) {
$.ajax({
type: 'POST',
url: 'service.php',
data: 'add=comment&id=' + id + '&comment=' + $(form).find('textarea').val(),
cache: false,
success: function(html){
if (html) {
location.reload();
}
}
});
return false;
}
$(document).ready(function(){
// file field change handler
$('#image_file').change(function(){
var file = this.files[0];
name = file.name;
size = file.size;
type = file.type;
// extra validation
if (name && size) {
if (! file.type.match('image.*')) {
alert("Select image please");
} else {
fileSelectHandler();
}
}
});
// masonry initialization
$('.main_container').masonry({
// options
itemSelector : '.pin',
isAnimated: true,
isFitWidth: true
});
// onclick event handler (for comments)
$('.comment_tr').click(function () {
$(this).toggleClass('disabled');
$(this).parent().parent().parent().find('form.comment').slideToggle(400, function () {
$('.main_container').masonry();
});
});
$('.ajax').colorbox({
onOpen:function(){
},
onLoad:function(){
},
onComplete:function(){
$(this).colorbox.resize();
var iPinId = $(this).parent().parent().attr('pin_id');
$.ajax({
url: 'service.php',
data: 'get=comments&id=' + iPinId,
cache: false,
success: function(html){
$('.comments').append(html);
$(this).colorbox.resize();
}
});
},
onCleanup:function(){
},
onClosed:function(){
}
});
});
现场演示
结论 (Conclusion)
We have just finished our fourth lesson where we writing our own Pinterest-like script. I hope you enjoy this series. It would be kind of you to share our materials with your friends. Good luck and welcome back!
我们刚刚完成了第四课,我们在其中编写了自己的类似Pinterest的脚本。 希望您喜欢这个系列。 您希望与朋友分享我们的资料。 祝你好运,欢迎回来!
翻译自: https://www.script-tutorials.com/pinterest-like-script-step-4/