Welcome Guest, Not a member yet? Register   Sign In
CXTags v1.0 - An awesome (but simple) taxonomy system
#1

[eluser]Xeoncross[/eluser]
Well, I finally finished the tagging system that was discussed around here.

CXTags is a simple single file Model that is only 18Kb in size (freetag is 48Kb). Every line is commented so you can follow along (there are more comments than code). Plus it does more than other libraries like freetag.

This class allows tagging of rows from different DB tables and different users.


Most tagging systems only work for one table - which is fine if you only need to use tags on your blog posts - but what if you add a "Image Gallery" to your site and want to tag pictures now along with blog posts?

CXTags solves this problem.

CXTags allows an infinite number of users (or none at all), to tag an infinite number of objects (table rows), from an infinite number of tables. Try to beat that Wink

Get a copy at: http://code.google.com/p/cxtags/downloads/list

UPDATE: March 29, 2009. The new version 2.0 is out!
#2

[eluser]JulianM[/eluser]
Hi,
I'm trying to run this class. However, please check the default DB prefix because following the exact steps specified in README.TXT I got this error:

Code:
A Database Error Occurred
Error Number: 1146
Table 'xxx.tags_ref' doesn't exist
SELECT DISTINCT `tag`, `safe_tag`, `id`, `date` FROM (`tags_ref`) INNER JOIN `tags` ON tags_ref.tag_id = tags.id WHERE `table` = 'posts' AND `row_id` = '1'

The default table has ci_ prefix.

Thanks,

Julian
#3

[eluser]Colin Williams[/eluser]
Be sure to use the dbprefix() method when utilizing table names outside of an AR method

Code:
$this->db->dbprefix('tablename');
#4

[eluser]Xeoncross[/eluser]
Thank you for the info. I built it using the default "ci_" table prefix - so I forgot to make amends in the JOIN queries for tables with a different prefix ;P

Version 1.1.0

I just updated the class so that it will now work with any table prefix Wink
Also, you can now call "tags" and "tags_ref" whatever you want as long as you update the Model with the right name.

Code:
class CXTags extends Model {

    //The names of the tables
    var $tags_ref    = 'tags_ref';
    var $tags    = 'tags';

No other things were changed as they all still work fine ;D
Just replace the CXTags Model v1.0.0 with v1.1.0
#5

[eluser]JulianM[/eluser]
Hi, I used this tagging system successfully. Great work.

Please notice that the filename CXTags.php might cause problems when using codeigniter in a linux system. I suggest you to rename it lowercase.

Julian
#6

[eluser]Xeoncross[/eluser]
Thanks for the update Julian!

It did everything I could think of for Tags while being much smaller in size than any other Tagging system on the web - no thanks to the power of CI!

Also, if someone has that problem I will be sure to tell them to re-name the file to "cxtags.php"
#7

[eluser]giannis[/eluser]
Hello,

Thanks for the library... It is indeed very handy.

I noticed that there was no function for generating a tag cloud so ...


Here is a function that generates a tagcloud.




Code:
/*
     * Get tag cloud.
     *
     * $data = array(
     *         'table' => 'posts',    //Name of the table row_id is from
     *        'user_id' => null,    //Optional ID of a single user
     *    );
     *
     * @param    array    data about the tag cloud
     * @return    string
     */

    function tag_cloud($data) {

        //If no tag is given
        if(!$data) { return; }

        $this->db->select('r.tag_id, count(tag_id) as tag_count, t.safe_tag, t.tag, r.table, r.user_id');

        $this->db->from('tags_ref as r, tags as t');

        $this->db->where('t.id = r.tag_id');

        $this->db->group_by('r.tag_id');

        $query = $this->db->get();

        $rows_returned = $query->num_rows;

        if($rows_returned > 0){

        $tagclouds = '';

        $baseurl = base_url();

          foreach ($query->result() as $row){

            if(($row->tag_count/$rows_returned) > 0.85){

                $styleclass="tag-x-large";

            }

            else if(($row->tag_count/$rows_returned) > 0.60){

                $styleclass="tag-large";
            }

            else if(($row->tag_count/$rows_returned) > 0.40){

                $styleclass="tag-medium";
            }

            else if(($row->tag_count/$rows_returned) > 0.20){

                $styleclass="tag-small";
            }

            else {

                $styleclass="tag-x-small";
            }



            $tagclouds .= " <a class='tagcloudlinks {$styleclass}'>safe_tag}' title='tag name is {$row->tag}'>{$row->tag}</a> ";

          }
        }
        else{

            $tagclouds = "no tags entered yet";

        }

        return $tagclouds;

    }
#8

[eluser]redwiz[/eluser]
hi Xeoncross

you're right, your model is awesome!!
maybe the where_tags function should be private
#9

[eluser]Xeoncross[/eluser]
Thanks for the function giannis!

I planned on leaving tag clouds to users so they could place them in views the way they wanted - but having a general function like that (for those of us to lazy to make them ourselves) is great too! I'll put it in the next release!
#10

[eluser]deadelvis[/eluser]
Thanks so much for the library... been meaning to replace freetag for a while.

I noticed however that the library removes international characters (accented characters like á è ç etc...) making it unusable for sites in languages other than english.

To solve it I have done the following...
Added function:
Code:
function remove_accents($string, $german=false) {
        // Single letters
        $single_fr = explode(" ", "À Á Â Ã Ä Å Ą Ă Ç Ć Č Ď Đ Ð È É Ê Ë Ę Ě Ğ Ì Í Î Ï İ Ł Ľ Ĺ Ñ Ń Ň Ò Ó Ô Õ Ö Ø Ő Ŕ Ř Š Ś Ş Ť Ţ Ù Ú Û Ü Ů Ű Ý Ž Ź Ż à á â ã ä å ą ă ç ć č ď đ è é ê ë ę ě ğ ì í î ï ı ł ľ ĺ ñ ń ň ð ò ó ô õ ö ø ő ŕ ř ś š ş ť ţ ù ú û ü ů ű ý ÿ ž ź ż");
        $single_to = explode(" ", "A A A A A A A A C C C D D D E E E E E E G I I I I I L L L N N N O O O O O O O R R S S S T T U U U U U U Y Z Z Z a a a a a a a a c c c d d e e e e e e g i i i i i l l l n n n o o o o o o o o r r s s s t t u u u u u u y y z z z");
        $single = array();
        for ($i=0; $i<count($single_fr); $i++) {
            $single[$single_fr[$i]] = $single_to[$i];
        }
        // Ligatures
        $ligatures = array("Æ"=>"Ae", "æ"=>"ae", "Œ"=>"Oe", "œ"=>"oe", "ß"=>"ss");
        // German umlauts
        $umlauts = array("Ä"=>"Ae", "ä"=>"ae", "Ö"=>"Oe", "ö"=>"oe", "Ü"=>"Ue", "ü"=>"ue");
        // Replace
        $replacements = array_merge($single, $ligatures);
        if ($german) $replacements = array_merge($replacements, $umlauts);
        $string = strtr($string, $replacements);
        return $string;
    }


Which gets called first thing in make_safe_tag()...
Code:
function make_safe_tag($tag='') {
    $tag = $this->remove_accents($tag); // remove accents from tag
...
}



In comma_to_array() function, replaced the following bit...
Code:
//Replace anything that isn't a letter, comma, space, quote, or number!
$string = preg_replace("/[^a-z0-9, \"']/", '', $string);
by...
Code:
//Replace anything that isn't a letter, comma, space, quote, or number... but KEEP INTERNATIONAL CHARACTERS
$string = preg_replace("/[^a-z0-9à-ü, \"']/", '', $string);

I am not good at all with regex but that seemed to do the trick.

Just a suggestion.




Theme © iAndrew 2016 - Forum software by © MyBB