package MT::Plugin::CloudNine; use CloudCreator; use Data::Dumper; use POSIX qw(strftime); use MT::Entry; use MT::ObjectTag; use MT::Request; use MT::Tag; use MT::Template::Context; use vars qw( $VERSION ); $VERSION = 3.3; my $plugin = MT::Plugin->new( { name => 'CloudNine', description => 'Create weighted tag clouds for your blog.', doc_link => 'http://blog.socklabs.com/cloudnine/', author_name => 'Nick Gerakines', author_link => 'http://www.socklabs.com/', config_template => \&configuration_template, settings => new MT::PluginSettings( [ ['smallest'], ['largest'], ['start'], ['last'], ['variation'], ['scheme'], ['minentries'], ['reverse'], ['unit'], ['enabgrad'], ] ) }); MT->add_plugin($plugin); MT::Template::Context->add_container_tag('CloudNine' => \&cloudnine); MT::Template::Context->add_tag('CloudWeight' => \&_catcloud_weight); MT::Template::Context->add_tag('CloudLabel' => \&_catcloud_label); MT::Template::Context->add_tag('CloudStub' => \&_catcloud_stub); MT::Template::Context->add_tag('CloudCSS' => \&_catcloud_css); sub instance { $plugin; } sub configuration_template { my ($plugin, $param, $scope) = @_; $param->{'smallest'} ||= 8; $param->{'scheme'} ||= 'mono'; $param->{'variation'} ||= 'default'; $param->{'reverse'} ||= 0; $param->{'largest'} ||= 16; $param->{'unit'} ||= 'pt'; $param->{'start'} ||= '#C8C8FF'; $param->{'last'} ||= ''; $param->{'minentries'} ||= 0; $param->{'enabgrad'} ||= 'enable'; return qq{

A quick note about this plugin: This plugin will attempt to create nice looking tag clouds based on a number of things. It does this pretty well, however there are some caveats. The colors you expect from the gradients you put in, may not be what you think. Because of this, getting what you want may take some tweaking and adjusting here and there. Just try not to get real frustrated.

 

This field represents the minimum entry count that category must have to show up in the cloud.

Set the font unit: Defaults to 'pt'.

Set the smallest size unit of the cloud. Defaults to 8

Set the largest size unit of the cloud. Defaults to 16

 

Select this option if you would like to enable color gradients in the cloud.

Enable Gradients:

 

Set the color value for the smallest entries in the cloud. Note that this is the starting point of the gradient creaetor and by default the cloud creator will automatically find a contrasting color to swing to. This must be a full 6 character hex value. aka 006400

 

Set the color value for the largest entries in the cloud. If you would like CloudNine to find a contrasting color and do its own voodoo, leave this blank.

Set the color scheme to use when finding contrasting and gradiant colors.

Currently set to

Scheme:

 

Set the color scheme variation to use when finding contrasting and gradiant colors.

Currently set to

Variation:

 

Select this option if you would like to reverse the color scheme that CloudNine finds for you. This is experimental and may not work the way you want it to.

Reverse:
}; } sub config { my $config = {}; if ($plugin) { my ($scope) = (@_); $config = MT::Request->instance->cache('catcloud_config_'.$scope); if (!$config) { $config = $plugin->get_config_hash($scope); MT::Request->instance->cache('catcloud_config_'.$scope, $config); } } $config; } sub cloudnine { my ($ctx, $args, $cond) = @_; my $blog_id = $ctx->stash('blog_id'); my $config = config('blog:' . $blog_id); my $cloud = CloudCreator->new( 'smallest' => $config->{'smallest'}, 'largest' => $config->{'largest'}, 'start' => $config->{'start'}, 'last' => $config->{'last'}, 'variation' => $config->{'variation'}, 'scheme' => $config->{'scheme'}, 'reverse' => $config->{'reverse'}, 'unit' => $config->{'unit'}, 'enabgrad' => $config->{'enabgrad'}, ); my $builder = $ctx->stash('builder'); my $tokens = $ctx->stash('tokens'); my $parts; if ( ! $args->{'type'} ) { $parts = blog_tags($blog_id); } if ( $args->{'type'} eq 'blog_tags' ) { $parts = blog_tags($blog_id); } if ( $args->{'type'} eq 'blog_categories' ) { $parts = blog_categories($blog_id); } if ( $args->{'type'} eq 'top_tags' ) { $parts = top_tags($blog_id); } if ( $args->{'type'} eq 'recent_tags' ) { $parts = recent_tags($blog_id); } if ( $args->{'type'} eq 'css' ) { my $span_one = $config->{'smallest'}; my $span_two = $config->{'largest'}; my @span = ($span_one .. $span_two); $parts = [ map { [$_, $_, $_] } @span ]; } for my $part (@{ $parts }) { $cloud->add( $part->[0], $part->[1], $part->[2] ); } my @tags = $cloud->gencloud; undef $cloud; for my $tag ( @tags ) { local $ctx->{__stash}{'CloudLabel'} = $tag->[0]; local $ctx->{__stash}{'CloudWeight'} = $tag->[4]; local $ctx->{__stash}{'CloudCSS'} = $tag->[2]; local $ctx->{__stash}{'CloudStub'} = $tag->[3]; defined(my $out = $builder->build( $ctx, $tokens )) or return $ctx->error( $ctx->errstr ); push @res, $out; } my $glue = $args->{'glue'} || ''; join $glue, @res; } sub blog_tags { my ($blog_id) = @_; my $type = MT::Entry->datasource; my @tags = MT::Tag->load_by_datasource( $type, { 'is_private' => 0, 'blog_id' => $blog_id }, ); my @out; for my $tag (@tags) { my $count = MT::Entry->count( { 'blog_id' => $blog_id, 'status' => MT::Entry::RELEASE() }, { 'join' => [ 'MT::ObjectTag', 'object_id', { 'tag_id' => $tag->id, 'object_datasource' => $type }], 'unique' => 1 } ); push @out, [ $tag->name, $count, $tag->name ]; } return \@out } sub blog_categories { my ($blog_id) = @_; my @blog_categories = MT::Category->load( { 'blog_id' => $blog_id } ); my @out; for my $cat ( @blog_categories ) { my $count = MT::Entry->count( { 'blog_id' => $blog_id, 'status' => MT::Entry::RELEASE() }, { 'join' => [ 'MT::Placement', 'entry_id', { 'category_id' => $cat->id }, { 'unique' => 1 } ],} ); push @out, [ $cat->label, $count, $cat->basename ]; } return \@out; } sub top_tags { my ($blog_id) = @_; my $type = MT::Entry->datasource; my @tags = MT::Tag->load_by_datasource( $type, { 'is_private' => 0, 'blog_id' => $blog_id }, ); my (@out, @top); for my $tag (@tags) { my $count = MT::Entry->count( { 'blog_id' => $blog_id, 'status' => MT::Entry::RELEASE() }, { 'join' => [ 'MT::ObjectTag', 'object_id', { 'tag_id' => $tag->id, 'object_datasource' => $type }], 'unique' => 1 } ); push @top, [ $tag->name, $count, $tag->name ]; } @top = sort { $b->[1] <=> $a->[1] } @top; return [ @top[ 0 .. 25 ] ]; } sub recent_tags { my ($blog_id) = @_; my @entries = MT::Entry->load( { 'blog_id' => $blog_id, 'status' => MT::Entry::RELEASE(), }, { 'sort' => 'created_on', 'direction' => 'descend', 'limit' => 10 } ); my %entry_tags = map { $_ => 1 } map { $_->tags } @entries; my $type = MT::Entry->datasource; my @tags = MT::Tag->load_by_datasource( $type, { 'name' => [ keys %entry_tags ], 'blog_id' => $blog_id } ); my @out; for my $tag (@tags) { my $count = MT::Entry->count( { 'blog_id' => $blog_id, 'status' => MT::Entry::RELEASE() }, { 'join' => [ 'MT::ObjectTag', 'object_id', { 'tag_id' => $tag->id, 'object_datasource' => $type }], 'unique' => 1 } ); push @out, [ $tag->name, $count, $tag->name ]; } return \@out; } sub _catcloud_weight { $_[0]->stash('CloudWeight') || 0; } sub _catcloud_label { $_[0]->stash('CloudLabel') || ''; } sub _catcloud_stub { $_[0]->stash('CloudStub') || ''; } sub _catcloud_css { $_[0]->stash('CloudCSS') || ''; } 1;