功能說明
使用最簡便的方式,為你的資料模型提供強大「打標籤」功能。
:gift: 項目地址: https://github.com/summerblue/laravel-taggable
本項目修改於 rtconner/laravel-tagging項目,增加了一下功能:
- 標籤名唯一;
- 增加 etrepat/baum依賴,讓標籤支援無限層級標籤嵌套;
- 中文 slug 拼音自動產生支援,感謝超哥的 overtrue/pinyin;
- 提供完整的測試案例,保證代碼品質。
注意: 本項目只支援 5.1 LTS
:heart: 此項目由 The EST Group團隊的 @Summer維護。
無限層級標籤嵌套
整合 etrepat/baum讓標籤具備從屬關係。
$root = Tag::create(['name' => 'Root']);// 建立子標籤$child1 = $root->children()->create(['name' => 'Child1']);$child = Tag::create(['name' => 'Child2']);$child->makeChildOf($root);// 批量構建樹$tagTree = [ 'name' => 'RootTag', 'children' => [ ['name' => 'L1Child1', 'children' => [ ['name' => 'L2Child1'], ['name' => 'L2Child1'], ['name' => 'L2Child1'], ] ], ['name' => 'L1Child2'], ['name' => 'L1Child3'], ]];Tag::buildTree($tagTree);
更多關聯操作請查看: etrepat/baum。
標籤名稱規則說明
- 標籤名裡的特殊符號和空格會被 -替代;
- 智能標籤 slug 產生,會產生 name 對應的中文拼音 slug ,如: 標籤-> biao-qian,拼音一樣的時候會被加上隨機值;
標籤名清理使用: $normalize_string = EstGroupe\Taggable\Util::tagName($name)。
Tag::create(['標籤名']);// name: 標籤名// slug: biao-qian-mingTag::create(['表簽名']);// name: 表簽名// slug: biao-qian-ming-3243 (後面 3243 為隨機,解決拼音衝突)Tag::create(['標籤 名']);// name: 標籤-名// slug: biao-qian-mingTag::create(['標籤!名']);// name: 標籤-名// slug: biao-qian-ming
安裝說明:
安裝
composer require estgroupe/laravel-taggable "5.1.*"
安裝和執行遷移
在 config/app.php的 providers數組中加入:
'providers' => array( \EstGroupe\Taggable\Providers\TaggingServiceProvider::class,);
php artisan vendor:publish --provider="EstGroupe\Taggable\Providers\TaggingServiceProvider"php artisan migrate
請仔細閱讀 config/tagging.php檔案。
建立 Tag.php
不是必須的,不過建議你建立自己項目專屬的 Tag.php 檔案。
修改 config/tagging.php檔案中:
'tag_model'=>'\App\Models\Tag',
加入 Taggable Trait
「標籤狀態」標示
Taggable能跟蹤模型是否打過標籤的狀態:
// `no`$article->is_tagged// `yes`$article->tag('Tag1');$article->is_tagged;// `no`$article->unTag();$article->is_tagged// This is fast$taggedArticles = Article::where('is_tagged', 'yes')->get() 首先你需要修改 config/tagging.php檔案中:
'is_tagged_label_enable' => true,
然後在你的模型的資料庫建立指令碼裡加上:
increments('id'); ... // Add this line $table->enum('is_tagged', array('yes', 'no'))->default('no'); ... $table->timestamps(); }); }} 「推薦標籤」標示
方便你實現「推薦標籤」功能,只需要把 suggest欄位標示為 true:
$tag = EstGroupe\Taggable\Model\Tag::where('slug', '=', 'blog')->first();$tag->suggest = true;$tag->save(); 即可以用以下方法讀取:
$suggestedTags = EstGroupe\Taggable\Model\Tag::suggested()->get();
重寫 Util 類?
大部分的通用操作都發生在 Util 類,你想擷取更多的定製權力,請建立自己的 Util 類,並註冊服務提供者:
namespace My\Project\Providers;use EstGroupe\Taggable\Providers\TaggingServiceProvider as ServiceProvider;use EstGroupe\Taggable\Contracts\TaggingUtility;class TaggingServiceProvider extends ServiceProvider { /** * Register the service provider. * * @return void */ public function register() { $this->app->singleton(TaggingUtility::class, function () { return new MyNewUtilClass; }); }} 然後在
注意 MyNewUtilClass必須實現 EstGroupe\Taggable\Contracts\TaggingUtility介面。
使用範例
$article = Article::with('tags')->first(); // eager load// 擷取所有標籤foreach($article->tags as $tag) { echo $tag->name . ' with url slug of ' . $tag->slug;}// 打標籤$article->tag('Gardening'); // attach the tag$article->tag('Gardening, Floral'); // attach the tag$article->tag(['Gardening', 'Floral']); // attach the tag$article->tag('Gardening', 'Floral'); // attach the tag// 批量通過 tag ids 打標籤$article->tagWithTagIds([1,2,3]);// 去掉標籤$article->untag('Cooking'); // remove Cooking tag$article->untag(); // remove all tags// 重打標籤$article->retag(['Fruit', 'Fish']); // delete current tags and save new tags$article->retag('Fruit', 'Fish');$article->retag('Fruit, Fish');$tagged = $article->tagged; // return Collection of rows tagged to article$tags = $article->tags; // return Collection the actual tags (is slower than using tagged)// 擷取綁定的標籤名稱數組$article->tagNames(); // get array of related tag names// 擷取打了「任意」標籤的 Article 對象Article::withAnyTag('Gardening, Cooking')->get(); // fetch articles with any tag listedArticle::withAnyTag(['Gardening','Cooking'])->get(); // different syntax, same result as aboveArticle::withAnyTag('Gardening','Cooking')->get(); // different syntax, same result as above// 擷取打了「全包含」標籤的 Article 對象Article::withAllTags('Gardening, Cooking')->get(); // only fetch articles with all the tagsArticle::withAllTags(['Gardening', 'Cooking'])->get();Article::withAllTags('Gardening', 'Cooking')->get();EstGroupe\Taggable\Model\Tag::where('count', '>', 2)->get(); // return all tags used more than twiceArticle::existingTags(); // return collection of all existing tags on any articles 如果你,即可使用以下標籤讀取功能:
// 通過 slug 擷取標籤Tag::byTagSlug('biao-qian-ming')->first();// 通過名字擷取標籤Tag::byTagName('標籤名')->first();// 通過名字數組擷取標籤數組Tag::byTagNames(['標籤名', '標籤2', '標籤3'])->first();// 通過 Tag ids 數組擷取標籤數組Tag::byTagIds([1,2,3])->first();// 通過名字數組擷取 ID 數組$ids = Tag::idsByNames(['標籤名', '標籤2', '標籤3'])->all();// [1,2,3] 標籤事件
Taggabletrait 提供以下兩個事件:
EstGroupe\Taggable\Events\TagAdded;EstGroupe\Taggable\Events\TagRemoved;
監聽標籤事件:
\Event::listen(EstGroupe\Taggable\Events\TagAdded::class, function($article){ \Log::debug($article->title . ' was tagged');}); 單元測試
基本用例測試請見: tests/CommonUsageTest.php。
運行測試:
composer installvendor/bin/phpunit --verbose
Thanks
- Special Thanks to: Robert Conner - http://smartersoftware.net
- overtrue/pinyin
- etrepat/baum
- Made with love by The EST Group - http://estgroupe.com/