Spanish (Español) translation by David Castrillón (you can also view the original English article)



En esta serie de Programación con Yii2, estoy guiando a los lectores en el uso del Framework Yii2 para PHP. Quizás también estés interesado en mi Introducción al Framework Yii, el cual revisa los beneficios de Yii e incluye un resumen de lo que es nuevo en Yii 2.x.
Introducción
En el tutorial de hoy, voy a mostrarte cómo extender Yii para imitar fácilmente un sitio como Reddit con votaciones, comentarios y compartir.
Recientemente, he estado trabajando en la creación de mi propia extensión personal de la gran plantilla avanzada de Yii. La plantilla proporciona el registro de usuarios integrado y autenticación y varios sitios para el front-end de sitios web y para sitios administrativos.
Construí algunos de mis últimos episodios de la API de Twitter en la primera versión de esta plataforma, seguir amigos en nombre de los usuarios y análisis de nuestros seguidores. El sitio que se describe en los, Twixxr, forma la base de mi trabajo de personalización de Yii.
Así que agregarle funcionalidades como votaciones, comentarios y compartir tiene mucho sentido. A medida que expandes tu código base de Yii con este tipo de características, construir nuevos sitios se vuelve más rápido, más fácil y cada vez más potentes.
Para Empezar
Voy a guiarte en el uso de tres plugins de Yii2:
- Extensión de votación Chiliec de Yii2
- Extensión de Comentarios 2Amigos Yii2 Disqus
- Extensión Social Kartik de Yii2
Hacen relativamente rápido y fácil construir una poderosa comunidad social en Yii2.
He creado un modelo denominado Item
que representa un objeto sobre el que deseas que los usuarios voten, comenten y compartan.
Francamente, después de crear las páginas de artículos con estas características en mi plataforma, me sentí más impresionado que nunca con Yii... más impresionado de lo que he estado hasta la fecha incluso construyendo mi serie de emprendimiento. Se puede hacer tanto con este framework.
Profundicemos.
Instalando las Extensiones
En primer lugar, vamos a agregar las tres extensiones en composer.json a la vez:
1 |
{
|
2 |
"name": "yiisoft/yii2-app-advanced", |
3 |
"description": "Yii 2 Advanced Project Template", |
4 |
"keywords": ["yii2", "framework", "advanced", "project template"], |
5 |
"homepage": "https://www.yiiframework.com/", |
6 |
"type": "project", |
7 |
"license": "BSD-3-Clause", |
8 |
"support": { |
9 |
"issues": "https://github.com/yiisoft/yii2/issues?state=open", |
10 |
"forum": "http://www.yiiframework.com/forum/", |
11 |
"wiki": "http://www.yiiframework.com/wiki/", |
12 |
"irc": "irc://irc.freenode.net/yii", |
13 |
"source": "https://github.com/yiisoft/yii2" |
14 |
},
|
15 |
"minimum-stability": "stable", |
16 |
"require": { |
17 |
"php": ">=5.4.0", |
18 |
"yiisoft/yii2": ">=2.0.10", |
19 |
"yiisoft/yii2-bootstrap": "*", |
20 |
"yiisoft/yii2-swiftmailer": "*", |
21 |
"yiisoft/yii2-authclient": "~2.1.0", |
22 |
"google/apiclient": "1.0.*@beta", |
23 |
"machour/yii2-google-apiclient":"@dev", |
24 |
"machour/yii2-google-gmail": "@dev", |
25 |
"ruskid/yii2-stripe": "dev-master", |
26 |
"2amigos/yii2-disqus-widget":"~1.0", |
27 |
"abraham/twitteroauth":"*", |
28 |
"codeception/codeception":"*", |
29 |
"notamedia/yii2-sentry": "^1.1", |
30 |
"chiliec/yii2-vote": "^4.0", |
31 |
"yiidoc/yii2-redactor": "*", |
32 |
"kartik-v/yii2-social": "@dev" |
Luego ejecuta composer update
Agregando la Votación
Vladimir Babin es Chiliec, y me gusta mucho la manera que él y otros han colaborado para crear este plugin. Se incluyen todas las características básicas que quieres, y tú puedes personalizarlo fácilmente, específicamente al reemplazar la vista. Poseen una gran documentación y lo mantienen bien actualizado.
Aquí está un útil gif animado de las características por defecto del plugin que alojan en GitHub. Acabo de publicar una imagen estática abajo (Envato Tuts + no soporta gifs en nuestros tutoriales).



Por supuesto, me decidí a personalizar la vista y a eliminar los votos, y fue bastante fácil.
Configuración
A continuación, agregamos el plugin de votación a /active/config/main.php para que se cargue en todas partes dentro de bootstrap y lo hemos configurado para nuestra aplicación:
1 |
return [ |
2 |
'id' => 'app-active', |
3 |
'basePath' => dirname(__DIR__), |
4 |
'bootstrap' => ['chiliec\vote\components\VoteBootstrap', |
5 |
'log','\common\components\SiteHelper'], |
6 |
'modules' => [ |
7 |
... |
8 |
'vote' => [ |
9 |
'class' => 'chiliec\vote\Module', |
10 |
// show messages in popover |
11 |
'popOverEnabled' => true, |
12 |
// global values for all models |
13 |
// 'allowGuests' => true, |
14 |
// 'allowChangeVote' => true, |
15 |
'models' => [ |
16 |
1 => [ |
17 |
'modelName' => \active\models\Item::className(), |
18 |
'allowGuests' => false, |
19 |
], |
20 |
// example declaration of models |
21 |
// \common\models\Post::className(), |
22 |
// 'backend\models\Post', |
23 |
// 2 => 'frontend\models\Story', |
24 |
// 3 => [ |
25 |
// 'modelName' => \backend\models\Mail::className(), |
26 |
// you can rewrite global values for specific model |
27 |
// 'allowGuests' => false, |
28 |
// 'allowChangeVote' => false, |
29 |
// ], |
30 |
], |
31 |
], |
32 |
Puedes ver que apagué la votación de invitados por lo que se necesita que las personas se inscriban para votar en los artículos.
Integración de la Base de Datos
A continuación, tienes que ejecutar la migración de la base de datos para crear tablas de seguimiento de los votos.
1 |
$ php yii migrate/up --migrationPath=@vendor/chiliec/yii2-vote/migrations |
Es importante recordar realizar esta migración al instalar el servidor del producto. Es muy fácil olvidarlo.
Mostrando el Widget de Votación
Mi modelo es parte de un modelo de colección denominado Tema, para que puedas encontrar la vista parcial para mi widget de votacion en /views/topic/_item.php:
1 |
<?php
|
2 |
use yii\helpers\Html; |
3 |
use yii\helpers\HtmlPurifier; |
4 |
use dosamigos\disqus\CommentsCount; |
5 |
use kartik\social\TwitterPlugin; |
6 |
use kartik\social\FacebookPlugin; |
7 |
use yii\helpers\StringHelper; |
8 |
|
9 |
?>
|
10 |
<div class="item_row row"> |
11 |
<div class="col-xs-1 col-md-1 col-lg-1"> |
12 |
<?= \chiliec\vote\widgets\Vote::widget([ |
13 |
'model' => $model, |
14 |
// optional fields
|
15 |
'showAggregateRating' => false, |
16 |
]);?> |
17 |
</div>
|
El índice de las llamadas del Tema mostrará una cuadrícula que muestra _item.php
como una fila. No quería mostrar una calificación, sólo los totales de votos positivos, así que lo puse en false.
Para sobreescribir la vista, he creado /views/vote/vote.php:
1 |
<div class="vote-row text-center" id="vote-<?=$modelId?>-<?=$targetId?>" data-placement="top" data-container="body" data-toggle="popover"> |
2 |
<span class="glyphicon glyphicon-chevron-up" onclick="vote(<?=$modelId?>, <?=$targetId?>, 'like'); return false;" style="cursor: pointer;"></span><br /><span id="vote-up-<?=$modelId?>-<?=$targetId?>"><?=$likes?></span> |
3 |
<div id="vote-response-<?=$modelId?>-<?=$targetId?>"> |
4 |
<?php if ($showAggregateRating) { ?> |
5 |
<?=Yii::t('vote', 'Aggregate rating')?>: <?=$rating?> |
6 |
<?php } ?> |
7 |
</div>
|
8 |
</div>
|
9 |
<div itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating"> |
10 |
<meta itemprop="interactionCount" content="UserLikes:<?=$likes?>"/> |
11 |
<meta itemprop="interactionCount" content="UserDislikes:<?=$dislikes?>"/> |
12 |
<meta itemprop="ratingValue" content="<?=$rating?>"/> |
13 |
<meta itemprop="ratingCount" content="<?=$likes+$dislikes?>"/> |
14 |
<meta itemprop="bestRating" content="10"/> |
15 |
<meta itemprop="worstRating" content="0"/> |
16 |
</div>
|
No una gran cantidad de plugins hacen la sobreescritura tan fácil.
He quitado el icono de votación hacia abajo y cambié el ícono de los votos hacia arriba a un chevron. Aquí está como se ve ahora:



Sé que esto parece un montón de capas, pero realmente no toma mucho tiempo para hacer que funcione.
Agregando Comentarios de Disqus
A continuación, he creado un sitio web de Disqus para el próximo sitio, ActiveTogether.org, que estará disponible para que veas estas características en acción en el momento en que leas esto. Así, que el nombre corto del sitio de Disqus 'active-together'.
Comencé a usar el widget 2Amigos antes de integrar la extensión social de Kartik (discutido abajo), que también ofrece comentarios de Disqus.
Creando un Identificador Único para Cada Tarjeta de Comentario
Cuando se crea un nuevo elemento, la acción item:: beforeSave()
crea un identificador único de Disqus para enlazar también los comentarios. También puedes confiar en la dirección URL de una página, pero esto suele ser más predecible.
En otras palabras, Disqus recopila todos los comentarios de cada artículo por separado, y ayuda a formar el tablero de cada elemento.
1 |
public function beforeSave($insert) |
2 |
{
|
3 |
if (parent::beforeSave($insert)) { |
4 |
if ($insert) { |
5 |
$this->identifier = Yii::$app->security->generateRandomString(8); |
6 |
$this->site_id = Yii::$app->params['site']['id']; |
7 |
}
|
8 |
}
|
9 |
return true; |
10 |
}
|
Viendo los Comentarios
Luego, el tablero de comentarios se visualiza fácilmente en la parte inferior de la vista del artículo en /active/views/Item.php:
1 |
<?php
|
2 |
|
3 |
use yii\helpers\Html; |
4 |
use yii\helpers\HtmlPurifier; |
5 |
use yii\helpers\Url; |
6 |
use dosamigos\disqus\Comments; |
7 |
...
|
8 |
<?= Comments::widget([ |
9 |
'shortname' => 'active-together', |
10 |
'identifier'=>$model->identifier, |
11 |
]); ?> |
Observa cómo el widget necesita el nombre corto
y el identificador
para proporcionar Disqus para los comentarios.
Aquí hay un ejemplo de como se ve el tablero de comentarios:



La Vista de Índice con la Cuenta de Comentarios
2Amigos también aprovecha las bibliotecas de Disqus en JavaScript para exhibir la cuenta de los comentarios. Pero hay unas pocas piezas que armar para que esto suceda.
En primer lugar, he creado un script de jQuery para solicitar la cuenta de los comentarios en un artículo. Cuando hay un montón de elementos en una página, es necesario solicitarlos con reset: true
1 |
$(document).ready(function(){ |
2 |
DISQUSWIDGETS.getCount({reset: true}); |
3 |
});
|
Luego he creado un archivo TopicAsset.php para cargar el archivo .js:
1 |
<?php
|
2 |
namespace active\assets; |
3 |
use yii\web\AssetBundle; |
4 |
|
5 |
class TopicAsset extends AssetBundle |
6 |
{
|
7 |
public $basePath = '@webroot'; |
8 |
public $baseUrl = '@active'; |
9 |
public $css = [ |
10 |
|
11 |
];
|
12 |
public $js = [ |
13 |
'js/topic.js', |
14 |
];
|
15 |
public $depends = [ |
16 |
'yii\web\YiiAsset', |
17 |
'yii\bootstrap\BootstrapAsset', |
18 |
];
|
A continuación, el archivo /active/views/Topic.php registra el paquete TopicAsset
:
1 |
<?php
|
2 |
|
3 |
use yii\helpers\Html; |
4 |
use yii\grid\GridView; |
5 |
use yii\widgets\Breadcrumbs; |
6 |
use common\widgets\Alert; |
7 |
use active\assets\TopicAsset; |
8 |
TopicAsset::register($this); |
A continuación, cada _item.php parcial incluye un número de comentarios:
1 |
<p><?= $this->render('_social', ['model' => $model, |
2 |
'includeCommentCount'=>true]);?></p> |
Y el parcial _social
muestra como está utilizando cada elemento-> identificador:
1 |
<li class="share_adjust_vert"><?= Html::a(Yii::t('active','Comments') |
2 |
,['/item/'.$model->slug.'#disqus_thread'], |
3 |
['data-disqus-identifier'=>$model->identifier]) ?> |
4 |
<?= CommentsCount::widget([ |
5 |
'shortname' => 'active-together', |
6 |
'identifier' => $model->identifier, |
7 |
]);
|
8 |
?>
|
A fin de que Disqus actualice los elementos con la cuenta de los comentarios, cada link debe terminar con #disqus_thread
.
Aquí está como se ve esa página. Cada elemento tiene un conteo distinto de comentarios cargado mediante una referencia a su identificador:



Pasemos a los botones sociales de compartir que has estado viendo.
Agregando los Botones Sociales de Compartir
Kartik ha hecho un gran trabajo con su widget social construyendo una configuración básica para la conexión a un número de redes sociales como Twitter, Disqus, Facebook. Por ahora, sólo estoy utilizando el botón compartir de Facebook. El botón de compartir de Twitter no tiene muy buena estética, así que lo reemplacé con un enlace HTML web.
Aquí está mi código para el par de botones al lado del conteo de comentarios en /active/views/topic/_social.php:
1 |
</li>
|
2 |
<li class="share_adjust_vert"><a class="twitter-share" |
3 |
href="https://twitter.com/intent/tweet? |
4 |
text=<?= urlencode($model->title); ?> |
5 |
&url=<?= urlencode(Url::canonical());?> |
6 |
&via=<?= Yii::$app->params['site']['twitter_account']?> |
7 |
"><img src="<?= Url::to(Url::home(true).'/images/social/twitter_icon.png'); |
8 |
?>"> Tweet</a></li> |
9 |
<li><?= FacebookPlugin::widget |
10 |
(['type'=>FacebookPlugin::SHARE, |
11 |
'settings' => ['dataSize'=>'small', |
12 |
'class'=>"fb_iframe_widget"]]); ?></li> |
13 |
</ul>
|
Parece simple, excepto que alinear verticalmente el widget de Facebook requiere algunos ajustes en el CSS. En /active/views/topic/_grid.php, coloqué este ajuste:
1 |
<style media="screen" type="text/css"> |
2 |
.fb_iframe_widget span |
3 |
{
|
4 |
vertical-align: baseline !important; |
5 |
}
|
6 |
</style>
|
Tiene que salir después de cargar otros archivos CSS.
Y, en el archivo site.css, puse esto para obtener el aspecto exacto que quería:
1 |
.share_adjust_vert { |
2 |
margin-top:-1px; |
3 |
font-size:90%; |
4 |
vertical-align: top; |
5 |
} |
Terminando
Sinceramente, estoy muy emocionado de lo fácil que es usar Yii y especialmente para crear un mini clon social. Estos son grandes plugins para un gran framework, y generalmente los desarrolladores de Yii y la comunidad de desarrolladores de los plugins responden en GitHub a las preguntas e interrogantes.
Espero que quieras echarle un vistazo a ActiveTogether y probar este framework por ti mismo.
Si tienes alguna pregunta o sugerencia, por favor publícala en los comentarios. Si deseas mantenerte al día sobre mis tutoriales futuros en Envato Tuts + y otras series, por favor visita mi página de instructor o sígueme en @lookahead_io. Definitivamente revisa mi serie de emprendimiento y el Meeting Planner.