神刀安全网

教你成为全栈工程师(Full Stack Developer) 四十二-利用n-n表关联实现文章标签

教你成为全栈工程师(Full Stack Developer) 四十二-利用n-n表关联实现文章标签

当文章积累了比较多时,总是希望能够从某一个方面把整理到一起,但一篇文章可能同时属于大数据类和机器学习类,所以这会是一个多对多的关系,那么如何实现这种关系呢?本节我们通过一种标签功能来说明

请尊重原创,转载请注明来源网站www.shareditor.com以及原始链接地址

创建标签Entity

首先我们要创建标签实体类,创建src/AppBundle/Entity/Tag.php文件,内容为:

<?php  namespace AppBundle/Entity;  use Doctrine/ORM/Mapping as ORM; use Doctrine/Common/Collections/ArrayCollection;  /**  * Tag  *  * @ORM/Table()  * @ORM/Entity  */ class Tag {     /**      * @ORM/ManyToMany(targetEntity="BlogPost", mappedBy="tag")      */     private $blogPosts;      public function __construct()     {         $this->blogPosts = new ArrayCollection();     }      public function getBlogPosts()     {         return $this->blogPosts;     }       /**      * @var integer      *      * @ORM/Column(name="id", type="integer")      * @ORM/Id      * @ORM/GeneratedValue(strategy="AUTO")      */     private $id;      /**      * @var string      *      * @ORM/Column(name="name", type="string", length=255)      */     private $name;      /**      * Get id      *      * @return integer      */     public function getId()     {         return $this->id;     }      /**      * Set name      *      * @param string $name      * @return Tag      */     public function setName($name)     {         $this->name = $name;          return $this;     }      /**      * Get name      *      * @return string      */     public function getName()     {         return $this->name;     } }

创建关联关系

有了标签实体Tag,我们要把BlogPost和Tag关联起来,这是一个多对多的关系,因此在src/AppBundle/Entity/BlogPost.php中添加:

/**  * @ORM/ManyToMany(targetEntity="Tag")  * @ORM/JoinTable(name="blogpost_tag",  *   joinColumns={@ORM/JoinColumn(name="blogpost_id", referencedColumnName="id")},  *   inverseJoinColumns={@ORM/JoinColumn(name="tag_id", referencedColumnName="id")}  * )  */ private $tags;

同时生成它的get和set方法

/**  * @return mixed  */ public function getTags() {     return $this->tags; }  /**  * @param mixed $tags  */ public function setTags($tags) {     $this->tags = $tags; }  

创建mysql表

执行

php app/console doctrine:schema:update --force

会自动生成两个表:

Tag(id, name) blogpost_tag(blogpost_id, tag_id)

增加Tag的Admin类

为了能在sonataadmin管理后台对Tag进行管理,我们创建src/AppBundle/Admin/TagAdmin.php内容如下:

<?php  namespace AppBundle/Admin;  use Sonata/AdminBundle/Admin/Admin; use Sonata/AdminBundle/Datagrid/ListMapper; use Sonata/AdminBundle/Datagrid/DatagridMapper; use Sonata/AdminBundle/Form/FormMapper;  class TagAdmin extends Admin {     protected function configureFormFields(FormMapper $formMapper)     {         $formMapper->add('name', 'text');     }      protected function configureDatagridFilters(DatagridMapper $datagridMapper)     {         $datagridMapper->add('name');     }      protected function configureListFields(ListMapper $listMapper)     {         $listMapper->addIdentifier('name');     } }  

增加tag的service配置

修改app/config/services.yml,增加:

admin.tag:     class: AppBundle/Admin/TagAdmin     arguments: [~, AppBundle/Entity/Tag, ~]     tags:         - { name: sonata.admin, manager_type: orm, label: Tag }  

增加BlogPost的tag管理控件

修改src/AppBundle/Admin/BlogPostAdmin.php,在configureFormFields中增加

->with('Meta data', array('class' => 'col-md-3')) ->add('tags', null, array(     'class' => 'AppBundle/Entity/Tag',     'property' => 'name', )) ->end()

请尊重原创,转载请注明来源网站www.shareditor.com以及原始链接地址

好,现在看一下效果,打开后台管理页面,我们看到多了Tag的一组管理:

教你成为全栈工程师(Full Stack Developer) 四十二-利用n-n表关联实现文章标签

点开List可以看到我刚刚添加的两个标签

教你成为全栈工程师(Full Stack Developer) 四十二-利用n-n表关联实现文章标签

新建一个BlogPost,也会发现在右侧多了Tag的填写框:

教你成为全栈工程师(Full Stack Developer) 四十二-利用n-n表关联实现文章标签

因为BlogPost和Tag是多对多的关系,所以这里是可以填写多个值的:

教你成为全栈工程师(Full Stack Developer) 四十二-利用n-n表关联实现文章标签

Tag的展示

Tag的管理功能已经完成了,那么怎么才能把tag展示出来呢?我们希望有两处展示,一处是单独一个页面,列出指定tag的所有文章列表,另一处是在文章展示页面展示出它的所有标签,同时链接到tag文章列表

为BlogPost创建listbytagAction,修改src/AppBundle/Controller/BlogController.php,在适当位置增加如下内容(如果你看了前面的文章,你就知道放到什么位置了):

use Doctrine/ORM/EntityManager; use Doctrine/ORM/QueryBuilder;    /**  * @var EntityManager  */ protected $em; /**  * @var QueryBuilder  */ protected $builder;      public function listbytagAction(Request $request) {     $tagName = $request->get('tagname');     $this->em = $this->get('doctrine.orm.entity_manager');     $this->builder = $this->em->createQueryBuilder();     $query = $this->builder->select('b')         ->add('from', 'AppBundle:BlogPost b INNER JOIN b.tags t')         ->where('t.name=:tag_name')         ->setParameter('tag_name', $tagName)         ->getQuery();      $paginator = $this->get('knp_paginator');     $pagination = $paginator->paginate(         $query,         $request->query->get('page', 1)/*page number*/,         100/*limit per page*/     );      return $this->render('blog/listbytag.html.twig', array('pagination' => $pagination,         'tagname' => $tagName,         'latestblogs' => BlogController::getLatestBlogs($this),         'tophotblogs' => BlogController::getTopHotBlogs($this))); }    

创建app/Resources/views/blog/listbytag.html.twig,内容如下:

{% extends "base.html.twig" %}  {% block title %}{{ tagname }} - SharEDITor - 关注大数据技术{% endblock title %}  {% block body %}  <div class="row">     <div class="col-sm-3 col-xs-1"></div>     <div class="col-sm-6 col-xs-10">         <h1>{{ tagname }}</h1>     </div>     <div class="col-sm-3 col-xs-1"></div> </div> <div class="row">     <div class="col-sm-3 col-xs-1"></div>     <div class="col-sm-6 col-xs-10">         <br />         {% for article in pagination %}             <h4><a href="{{ path('blog_show', {'blogId':article.id}) }}">{{ article.title }}</a>({{ article.createDate }})</h4>         {% endfor %}         <div class="navigation">             {{ knp_pagination_render(pagination) }}         </div>      </div>     <div class="col-sm-3 col-xs-1"></div> </div>  {% endblock body %}

为这个action创建路由,修改app/config/routing.yml,增加如下内容:

blog_listbytag:     path:     /bloglistbytag/     defaults: { _controller: AppBundle:Blog:listbytag }

修改app/Resources/views/blog/show.html.twig,在展示subject和category两个标签的后面添加:

{% for tag in blogpost.tags %} <a class="btn btn-warning btn-xs" href="{{ path('blog_listbytag', {'tagname':tag.name}) }}">     {{ tag.name }} </a> {% endfor %}

在app/Resources/views/blog/list.html.twig也同样加入如下内容:

{% for tag in article.tags %}     <a class="btn btn-warning btn-xs" href="{{ path('blog_listbytag', {'tagname':tag.name}) }}">         {{ tag.name }}     </a> {% endfor %}  

下面欣赏一下最终效果:

教你成为全栈工程师(Full Stack Developer) 四十二-利用n-n表关联实现文章标签

教你成为全栈工程师(Full Stack Developer) 四十二-利用n-n表关联实现文章标签

教你成为全栈工程师(Full Stack Developer) 四十二-利用n-n表关联实现文章标签

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » 教你成为全栈工程师(Full Stack Developer) 四十二-利用n-n表关联实现文章标签

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址