Advertisement
  1. Code
  2. Yii

Programando con Yii2: Construyendo Comunidad con Votaciones, Comentarios y Compartir

Scroll to top
Read Time: 9 min
This post is part of a series called How to Program With Yii2.
Programming With Yii2: Building a RESTful API
Programming With Yii: Generating Documentation

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

Final product imageFinal product imageFinal product image
What You'll Be Creating

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:

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).

Programming With Yii - Voting Plugin Default ExampleProgramming With Yii - Voting Plugin Default ExampleProgramming With Yii - Voting Plugin Default Example

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:

Programming With Yii - Voting WidgetProgramming With Yii - Voting WidgetProgramming With Yii - Voting Widget

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:

Programming With Yii - Item Page with voting sharing and comments boardProgramming With Yii - Item Page with voting sharing and comments boardProgramming With Yii - Item Page with voting sharing and comments board

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:

Programming With Yii - Index page of with voting and social comments and sharingProgramming With Yii - Index page of with voting and social comments and sharingProgramming With Yii - Index page of with voting and social comments and sharing

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.

Links Relacionados

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.