diff --git a/Changes b/Changes index 66269d97..81345217 100644 --- a/Changes +++ b/Changes @@ -1,38 +1,40 @@ New features: - Google search formatter (bayashi) + - Utility scripts to import/export raw page markup from file/to STDOUT (dandv) + - Add wikipedia link generator. (bayashi) - Bug fixes: + Bug fixes: - Minor CSS fix (tcaine) - Restrict page deletion to admin users only - + - default uri_for_static to use uri_for to make it work correctly for non-root-mounted wikis. + Improvements: - - All Methods/subs now documented - - POD Coverage test on by default + - All method must be documented from now on - POD coverage test is on by default 1.00 2010-05-09 00:04:20 New Features: - Create a default page for new users. - Replaced shrunken-head image with a sane "Stop" sign (dandv) - + Bug fixes: - Fix WantedLink to use normalize_page to match links - Removed File::Slurp dependency after removing it from Text::(Multi)Markdown because it fails installation under Strawberry Perl (dandv) - - IRC Formatter auto-color nicknames (GitHub issue #27) (linio) + - IRC Formatter auto-color nicknames (GitHub issue #27) (linio) - Attachments size in Page info is now correctly displayed (GitHub issue #53) (linio) - Remove 'Alerts' from Syntax Highlight list - it's Kate's hidden module (Github issue #52) (linio) - Fixed formatter_all_textile tests to work without Syntax plugin - + Improvements: - Refine POD so lintian is happy (debian build tool) - - Add unicode code option to DB connect string. This allows us to remove - the use of UTF8Columns which is deprecated. Hook in CHARTSET=utf8 for MySQL deploy - + - Forced SQLite, MySQL and PostgreSQL database connections to use Unicode, + eliminating dependency on DBIx::Class::UTF8Columns, which is now strongly deprecated. (mateu) + Misc: - Test::Notabs is now optional - HTML::Toc is now required - + 0.999042 2009-12-01 21:42:00 @@ -48,16 +50,16 @@ Bug fixes: - fixed inserting images via the toolbar after markdown="1" support (dandv) - + 0.999041 2009-10-26 11:55:00 New features: - add markdown="1" to block-level HTML elements to interpret Markdown (dandv) - + Translation: - Italian. MojoMojo ora parla italiano (enrico) - + Bug fixes: - Exports now export the entire subtree (dandv) - Sub pages do not show pages without view permission (linio) @@ -70,30 +72,30 @@ Documentation: - improved and centralized installation docs into lib/MojoMojo/Installation.pod - + 0.999040 2009-09-04 19:53:00 - + - Format content body and store in content.precompile Use this precompiled body when available for page delivery (see page/view.tt). /.precompile_pages action for precompiling all page versions. This action can take a few minutes for the Catalyst wiki (~2000 page versions). - + - Fixed [[child]] and [[../sibling]] display bug when first creating a page. Adjust tests to reflect that [[../sibling]] formats to parent/sibling instead of ../sibling. (mateu) - + - Simplified and improved sub-pages. Speed and layout enhanced. (mateu) - Made subtree KinoSearch work (mateu) - Added paging for .list (dandv) - + - Catapulse theme (dab) - Madrid.pm theme (diegok) - More español (diegok) - + - Updated jQuery inplace editor and related code; fixed '&'-encoding bug which caused any text after the '&' to be lost when editing in-place (dandv) - + - Simplified 404 page handling in suggest.tt (mateu) - No cookie for anonymous user requests, and cookie test (mateu) - Removed PageCache (mateu) @@ -102,7 +104,7 @@ - Main formatter now guaranteed to end the content with *one* newline (dandv) - Remove some obsolete crud (dandv/marcus) - + 0.999033 2009-08-14 12:40:00 UTC @@ -419,9 +421,9 @@ 0.999013 2008-02-06 00:08:00 - - renovated skin (arne) - - syntax fixes, registration/login (jshirley) - - fix email validation template (jshirley) + - Renovated skin (arne) + - Syntax fixes, registration/login (jshirley) + - Fix email validation template (jshirley) 0.999012 2008-02-06 00:08:00 diff --git a/lib/MojoMojo.pm b/lib/MojoMojo.pm index 9026176b..70b5bd45 100644 --- a/lib/MojoMojo.pm +++ b/lib/MojoMojo.pm @@ -98,22 +98,6 @@ if ($@ ) { MojoMojo->model('DBIC')->schema->attachment_dir( MojoMojo->config->{attachment_dir} || MojoMojo->path_to('uploads') . '' ); -=head2 prepare - -Accomdate a forcing of SSL if needed in a reverse proxing setup - -=cut - -sub prepare { - my $self = shift->next::method(@_); - if ( $self->config->{force_ssl} ) { - my $request = $self->request; - $request->base->scheme('https'); - $request->uri->scheme('https'); - } - return $self; -} - =head1 NAME MojoMojo - A Catalyst & DBIx::Class powered Wiki. @@ -148,10 +132,31 @@ To find out more about how you can use MojoMojo, please visit http://mojomojo.org or read the installation instructions in L to try it out yourself. +=head1 METHODS + +=head2 prepare + +Accomodate a forcing of SSL if needed in a reverse proxy setup. + +=cut + +sub prepare { + my $self = shift->next::method(@_); + if ( $self->config->{force_ssl} ) { + my $request = $self->request; + $request->base->scheme('https'); + $request->uri->scheme('https'); + } + return $self; +} + + =head2 ajax -ajax request header +Return whether the request is an AJAX one (used by the live preview, +for example), as opposed to a rgular request (such as one used to view +a page). =cut @@ -184,8 +189,8 @@ sub wikiword { =head2 pref -Find or create a preference key, update it if you pass a value then return the -current setting. +Find or create a preference key. Update it if a value is passed, then +return the current setting. =cut @@ -305,12 +310,12 @@ sub prepare_action { We override this method to work around some of Catalyst's assumptions about dispatching. Since MojoMojo supports page namespaces -(e.g. '/parent_page/child_page'), with page paths that always start with '/', -we strip the trailing slash from $c->req->base. Also, since MojoMojo indicates -actions by appending a '.$action' to the path -(e.g. '/parent_page/child_page.edit'), we remove the page path and save it in -$c->stash->{path} and reset $c->req->path to $action. We save the original URI -in $c->stash->{pre_hacked_uri}. +(e.g. C), with page paths that always start with C, +we strip the trailing slash from C<< $c->req->base >>. Also, since MojoMojo +indicates actions by appending a C<.$action> to the path +(e.g. C), we remove the page path and save it in +C<< $c->stash->{path} >> and reset C<< $c->req->path >> to C<< $action >>. +We save the original URI in C<< $c->stash->{pre_hacked_uri} >>. =cut @@ -348,7 +353,7 @@ sub prepare_path { =head2 base_uri -Return $c->req->base as an URI object. +Return C<< $c->req->base >> as an URI object. =cut @@ -359,7 +364,7 @@ sub base_uri { =head2 uri_for -Override $c->uri_for to append path, if a relative path is used. +Override C<< $c->uri_for >> to append path, if a relative path is used. =cut @@ -383,19 +388,27 @@ sub uri_for { =head2 uri_for_static -static has been remapped to .static +C has been remapped to C. =cut sub uri_for_static { my ( $self, $asset ) = @_; - return ( $self->config->{static_path} || '/.static/' ) . $asset; + return ( defined($self->config->{static_path}) ? + $self->config->{static_path} . $asset : + $self->uri_for('/.static', $asset) ); } +=head2 _cleanup_path + +Lowercase the path and remove any double-slashes. + +=cut + sub _cleanup_path { my ( $c, $path ) = @_; - ## make some changes to the path - We have to do this - ## because path is not always cleaned up before we get it. + ## Make some changes to the path - we have to do this + ## because path is not always cleaned up before we get it: ## sometimes we get caps, other times we don't. Permissions are ## set using lowercase paths. @@ -408,6 +421,19 @@ sub _cleanup_path { return $searchpath; } +=head2 _expand_path_elements + +Generate all the intermediary paths to C, starting from C +and ending with the complete path: + + / + /path + /path/to + /path/to/a + /path/to/a/page + +=cut + sub _expand_path_elements { my ( $c, $path ) = @_; my $searchpath = $c->_cleanup_path( $path ); @@ -420,7 +446,7 @@ sub _expand_path_elements { my @paths_to_check = ('/'); - my $current_path; + my $current_path = ''; foreach my $pathitem (@pathelements) { $current_path .= "/" . $pathitem; @@ -432,36 +458,53 @@ sub _expand_path_elements { =head2 get_permissions_data - Permissions are checked prior to most actions, including view if that is - turned on in the configuration. The permission system works as follows. - 1. There is a base set of rules which may be defined in the application - config, these are: - $c->config->{permissions}{view_allowed} = 1; # or 0 - similar entries exist for delete, edit, create and attachment. - if these config variables are not defined, default is to allow - anyone to do anything. - - 2. Global rules that apply to everyone may be specified by creating a - record with a role-id of 0. - - 3. Rules are defined using a combination of path, and role and may be - applied to subpages or not. - - 4. All rules matching a given user's roles and the current path are used to - determine the final yes/no on each permission. Rules are evaluated from - least-specific path to most specific. This means that when checking - permissions on /foo/bar/baz, permission rules set for /foo will be - overridden by rules set on /foo/bar when editing /foo/bar/baz. When two - rules (from different roles) are found for the same path prefix, explicit - allows override denys. Null entries for a given permission are always - ignored and do not effect the permissions defined at earlier level. This - allows you to change certain permissions (such as create) only while not - affecting previously determined permissions for the other actions. Finally - - apply_to_subpages yes/no is exclusive. Meaning that a rule for /foo with - apply_to_subpages set to yes will apply to /foo/bar but not to /foo alone. - The endpoint in the path is always checked for a rule explicitly for that - page - meaning apply_to_subpages = no. - +Permissions are checked prior to most actions, including C if that is +turned on in the configuration. The permission system works as follows: + +=over + +=item 1. + +There is a base set of rules which may be defined in the application +config. These are: + + $c->config->{permissions}{view_allowed} = 1; # or 0 + +Similar entries exist for C, C, C and C. +If these config variables are not defined, the default is to allow anyone +to do anything. + +=item 2. + +Global rules that apply to everyone may be specified by creating a +record with a role id of 0. + +=item 3. + +Rules are defined using a combination of path(s)?, and role and may be +applied to subpages or not. + +TODO: clarify. + +=item 4. + +All rules matching a given user's roles and the current path are used to +determine the final yes/no on each permission. Rules are evaluated from +least-specific path to most specific. This means that when checking +permissions on C, permission rules set for C will be +overridden by rules set on C when editing C. When two +rules (from different roles) are found for the same path prefix, explicit +Cs override Cs. Null entries for a given permission are always +ignored and do not affect the permissions defined at earlier level. This +allows you to change certain permissions (such as C) only while not +affecting previously determined permissions for the other actions. Finally - +C C/C is exclusive, meaning that a rule for C with +C set to C will apply to C but not to C +alone. The endpoint in the path is always checked for a rule explicitly for that +page - meaning C. + +=back + =cut sub get_permissions_data { @@ -474,26 +517,26 @@ sub get_permissions_data { ## Now that we have our path elements to check, we have to figure out how we are accessing them. ## If we have caching turned on, we load the perms from the cache and walk the tree. - ## otherwise we pull what we need out of the db. - # structure: $permdata{$pagepath} = { - # admin => { - # page => { - # create => 'yes', - # delete => 'yes', - # view => 'yes', - # edit => 'yes', - # attachment => 'yes', - # }, - # subpages => { - # create => 'yes', - # delete => 'yes', - # view => 'yes', - # edit => 'yes', - # attachment => 'yes', - # }, - # }, - # users => ..... - # } + ## Otherwise we pull what we need out of the DB. The structure is: + # $permdata{$pagepath} = { + # admin => { + # page => { + # create => 'yes', + # delete => 'yes', + # view => 'yes', + # edit => 'yes', + # attachment => 'yes', + # }, + # subpages => { + # create => 'yes', + # delete => 'yes', + # view => 'yes', + # edit => 'yes', + # attachment => 'yes', + # }, + # }, + # users => ..... + # } if ( $c->pref('cache_permission_data') ){ $permdata = $c->cache->get('page_permission_data'); } @@ -507,13 +550,13 @@ sub get_permissions_data { # Can't use string ("") as a HASH ref while "strict refs" $permdata = {}; - ## either the data hasn't been loaded, or it's expired since we used it last. + ## Either the data hasn't been loaded, or it's expired since we used it last, ## so we need to reload it. my $rs = $c->model('DBIC::PathPermissions') ->search( undef, { order_by => 'length(path),role,apply_to_subpages' } ); - # if we are not caching, we don't return the whole enchilada. + # If we are not caching, we don't return the whole enchilada. if ( ! $c->pref('cache_permission_data') ) { ## this seems odd to me - but that's what the DBIx::Class says to do. $rs = $rs->search( { role => $role_ids } ) if $role_ids; @@ -558,7 +601,7 @@ sub get_permissions_data { =head2 user_role_ids -Get the list of role ids for a user +Get the list of role ids for a user. =cut @@ -577,7 +620,7 @@ sub user_role_ids { =head2 check_permissions -Check user permissions for a path +Check user permissions for a path. =cut @@ -636,8 +679,8 @@ sub check_permissions { }, ); - ## the outcome of this loop is a combined permission set. - ## The rule orders are basically based on how specific the path + ## The outcome of this loop is a combined permission set. + ## The rule orders are essentially based on how specific the path ## match is. More specific paths override less specific paths. ## When conflicting rules at the same level of path hierarchy ## (with different roles) are discovered, the grant is given precedence @@ -691,7 +734,7 @@ sub check_permissions { =head2 check_view_permission -Check if a user can view a path +Check if a user can view a path. =cut @@ -747,10 +790,27 @@ die 'Require write access to attachment_dir: <'.MojoMojo->config->{attachment_di =head1 SUPPORT -If you want to talk about MojoMojo, there's an IRC channel, L. +=over + +=item * + +L + +=item * + +IRC: L. + +=item * + +Mailing list: L + +=item * + Commercial support and customization for MojoMojo is also provided by Nordaaker Ltd. Contact C for details. +=back + =head1 AUTHORS Marcus Ramberg C diff --git a/lib/MojoMojo/Formatter/GoogleSearch.pm b/lib/MojoMojo/Formatter/GoogleSearch.pm index 4ddc97e9..eb75fa8f 100644 --- a/lib/MojoMojo/Formatter/GoogleSearch.pm +++ b/lib/MojoMojo/Formatter/GoogleSearch.pm @@ -59,8 +59,6 @@ Calls the formatter. Takes a ref to the content as well as the context object. sub format_content { my ( $class, $content, $c ) = @_; - return unless $class->module_loaded; - my @lines = split /\n/, $$content; $$content = ''; diff --git a/lib/MojoMojo/Formatter/WikipediaLink.pm b/lib/MojoMojo/Formatter/WikipediaLink.pm new file mode 100644 index 00000000..7cfac003 --- /dev/null +++ b/lib/MojoMojo/Formatter/WikipediaLink.pm @@ -0,0 +1,103 @@ +package MojoMojo::Formatter::WikipediaLink; +use strict; +use warnings; +use parent qw/MojoMojo::Formatter/; + +=head1 NAME + +MojoMojo::Formatter::WikipediaLink - Linked Wikipedia by writing {{wikipedia: }} + +=head1 DESCRIPTION + +Normally, to hyperlink to the Wikipedia, you'd write: + + [wikipedia Hello](http://en.wikipedia.org/wiki/Hello) + +This plugin lets you write just + + {{wikipedia Hello}} + +not just Link to Wikipedia in English page, you can use many languages + + {{wikipedia:ja こんにちは}} + {{wikipedia:fr Salut}} + +Actually, if you wrote this without a language ex.{{wikipedia Foo}}, +select location of Wikipedia Link +is getting default-language setting of MojoMojo. + +=head1 METHODS + +=head2 format_content_order + +The WikipediaLink formatter has no special requirements +in terms of the order it gets run in, so it has a priority of 17. + +=cut + +sub format_content_order { 17 } + +=head2 format_content + +Calls the formatter. Takes a ref to the content as well as the context object. + +=cut + +sub format_content { + my ( $class, $content, $c ) = @_; + + my @lines = split /\n/, $$content; + $$content = ''; + + my $re = $class->gen_re( qr/[wW]ikipedia(?::([^\s]+))?\s+(.+)/ ); + my $lang = $c->sessionid + ? $c->session->{lang} : $c->pref('default_lang') || 'en'; + + for my $line (@lines) { + if ( $line =~ m/$re/ ) { + $line = $class->process($c, $line, $re, $lang); + } + $$content .= $line . "\n"; + } + +} + +=head2 process + +Here the actual formatting is done. + +=cut +sub process { + my $class = shift; + my ($c, $line, $re, $lang) = @_; + + $line =~ m/$re/; + my $wikipedia_lang = $1 || $c->pref('default_lang') || 'en'; + my $keyword = $2; + + my $uri = URI->new("http://$wikipedia_lang.wikipedia.org/"); + $uri->path("/wiki/$keyword"); + + $line =~ s!$re!$keyword!; + $c->stash->{precompile_off} = 1; + + return $line; +} + + +=head1 SEE ALSO + +L and L. + +=head1 AUTHORS + +Dai Okabayashi, L + +=head1 LICENSE + +This library is free software. You can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + +1; diff --git a/mojomojo.conf b/mojomojo.conf index 03784f23..af06dcd7 100644 --- a/mojomojo.conf +++ b/mojomojo.conf @@ -43,7 +43,7 @@ system_mail Default Installation root __path_to(root)__ -static_path /.static/ +# static_path /.static/ attachment_dir __path_to(uploads)__ index_dir __path_to(index)__ diff --git a/script/mojomojo_fastcgi_manage.pl b/script/mojomojo_fastcgi_manage.pl index 247b2ffd..7b05155a 100755 --- a/script/mojomojo_fastcgi_manage.pl +++ b/script/mojomojo_fastcgi_manage.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl =head1 NAME @@ -6,8 +6,10 @@ =head1 NAME =cut -eval { use FCGI::Engine::Manager }; -if ($@) { die "You need to install FCGI::Engine to run this script\n"; } +BEGIN { + eval { require FCGI::Engine::Manager }; + if ($@) { die "\n NOTICE: You need to install FCGI::Engine to run this script\n\n"; } +} my $m = FCGI::Engine::Manager->new( conf => 'script/mojomojo_fastcgi_manage.yml' ); diff --git a/script/util/dump_content.pl b/script/util/dump_content.pl new file mode 100755 index 00000000..f9ab139e --- /dev/null +++ b/script/util/dump_content.pl @@ -0,0 +1,81 @@ +#!/usr/bin/env perl +=head1 NAME + +dump_content.pl - Dump the raw (markup) content of a page. + +=head1 SYNOPSIS + + script/util/dump_content.pl /path/to/page > page.markdown + +=head1 AUTHORS + +Dan Dascalescu (dandv), http://dandascalescu.com + +=head1 LICENSE + +You may distribute this code under the same terms as Perl itself. + +=head1 COPYRIGHT + +Copyright (C) 2010, Dan Dascalescu. + +=cut + +use strict; +use warnings; +use FindBin; +use lib "$FindBin::Bin/../../lib"; +use MojoMojo::Schema; + +my ($page_path, $filename_content, $dsn, $user, $pass) = @ARGV; + +if (!$page_path) { + die "USAGE: $0 /path/to/page +Dump the raw (markup) contents of the last version of a page. +\n"; +} + +if (!$dsn) { + # no DSN passed via the command line; attempting to read one from the config file + require Config::JFDI; + + my $config = Config::JFDI->new(name => "MojoMojo")->get; + die "Couldn't read config file" if not keys %{$config}; + + eval { + if (ref $config->{'Model::DBIC'}->{'connect_info'}) { + $dsn = $config->{'Model::DBIC'}->{'connect_info'}->{dsn}; + $user = $config->{'Model::DBIC'}->{'connect_info'}->{user}; + $pass = $config->{'Model::DBIC'}->{'connect_info'}->{password}; + } else { + ($dsn, $user, $pass) = @{$config->{'Model::DBIC'}->{connect_info}}; + } + }; + die "Your DSN settings in mojomojo.conf seem invalid\n" if $@; +} +die "Couldn't find a valid Data Source Name (DSN).\n" if !$dsn; + +$dsn =~ s/__HOME__/$FindBin::Bin\/\.\./g; + +my $schema = MojoMojo::Schema->connect($dsn, $user, $pass) or + die "Failed to connect to database"; + +my ( $path_pages, $proto_pages ) = $schema->resultset('Page')->path_pages( $page_path ) + or die "Can't find page $page_path\n"; + +if (scalar @$proto_pages) { + die "One or more pages at the end do(es) not exist: ", + (join ", ", map { $_->{name_orig} } @$proto_pages), + "\n"; +} + +# Get the lastest content version of the page +my $page = $path_pages->[-1]; +my $page_content = $schema->resultset('Content')->single( + { + page => $page->id, + version => $page->content_version, + } +); + +print $page_content->body; diff --git a/script/util/import_content.pl b/script/util/import_content.pl new file mode 100755 index 00000000..2688bbd9 --- /dev/null +++ b/script/util/import_content.pl @@ -0,0 +1,149 @@ +#!/usr/bin/env perl +=head1 NAME + +import_content.pl - import content from a file into a MojoMojo page + +=head1 SYNOPSIS + + script/util/import_content.pl /path/to/page page.markdown + +Since this operation is undoable, the script will prompt you to confirm that +you really want to replace the contents of the last version of /path/to/page +with what's in F. + +=head1 DESCRIPTION + +Replace the contents of the last version of a page with the content from a +file. Useful if you want to fix a typo in a page without bumping the version +and creating yet another revision in the database. Of course, can be used for +evil, but then so could be a series of SQL commands. + +=head1 AUTHORS + +Dan Dascalescu (dandv), http://dandascalescu.com + +=head1 LICENSE + +You may distribute this code under the same terms as Perl itself. + +=head1 COPYRIGHT + +Copyright (C) 2010, Dan Dascalescu. + +=cut + +use strict; +use warnings; +use FindBin; +use lib "$FindBin::Bin/../../lib"; +use MojoMojo::Schema; + +=head2 preview + +Return the middle of a string. Examples: + + preview('abcdefghijk', 10) + 'ab [...] k' + + preview('abcdefghijkl', 10), "\n"; + 'ab [...] l' + + preview('abcdefghijkl', 11), "\n"; + 'ab [...] kl' + + preview('abcdefghijklm', 10), "\n"; + 'ab [...] m' + + preview('abcdef0000000000ghijklm', 10), "\n"; + 'ab [...] m' + +=cut + +sub preview { + my ($string, $limit) = @_; + my $length = length $string; + return $string if $length <= $limit; + my $middle = ' [...] '; + return + substr( $string, 0, ($limit+1 - length $middle)/2 ) + . $middle + . substr( $string, $length - ($limit-1 - length $middle)/2 ) + ; +} + + +my ($page_path, $filename_content, $dsn, $user, $pass) = @ARGV; + +if (!$page_path) { + die "USAGE: $0 /path/to/page filename [dsn user pass] +Replace the contents of the last version of a page with the content from a file +\n"; +} + +if (!$dsn) { + # no DSN passed via the command line; attempting to read one from the config file + require Config::JFDI; + + my $config = Config::JFDI->new(name => "MojoMojo")->get; + die "Couldn't read config file" if not keys %{$config}; + + eval { + if (ref $config->{'Model::DBIC'}->{'connect_info'}) { + $dsn = $config->{'Model::DBIC'}->{'connect_info'}->{dsn}; + $user = $config->{'Model::DBIC'}->{'connect_info'}->{user}; + $pass = $config->{'Model::DBIC'}->{'connect_info'}->{password}; + } else { + ($dsn, $user, $pass) = @{$config->{'Model::DBIC'}->{connect_info}}; + } + }; + die "Your DSN settings in mojomojo.conf seem invalid\n" if $@; +} +die "Couldn't find a valid Data Source Name (DSN).\n" if !$dsn; + +$dsn =~ s/__HOME__/$FindBin::Bin\/\.\./g; + +my $schema = MojoMojo::Schema->connect($dsn, $user, $pass) or + die "Failed to connect to database"; + +my ( $path_pages, $proto_pages ) = $schema->resultset('Page')->path_pages( $page_path ) + or die "Can't find page $page_path\n"; + +if (scalar @$proto_pages) { + die "One or more pages at the end do(es) not exist: ", + (join ", ", map { $_->{name_orig} } @$proto_pages), + "\n"; +} + +# Get the lastest content version of the page +my $page = $path_pages->[-1]; +my $page_content_rs = $schema->resultset('Content')->search( + { + page => $page->id, + version => $page->content_version, + } +); +die "More than one 'last version' for page <$page_path>. The database may be corrupt.\n" + if $page_content_rs->count > 1; +my $page_content = $page_content_rs->first; + +open my $file_content, '<:utf8', $filename_content or die $!; +my $content; {local $/; $content = <$file_content>}; + +print "Are you sure you want to replace\n", + preview($page_content->body, 300), + "\nwith\n", + preview($content, 300), + "\n? ('yes'/anything else): "; +my $answer = ; chomp $answer; +if ($answer eq 'yes') { + $page_content->update( + { + body => $content, + precompiled => '', # this needs to be blanked so that MojoMojo will re-compile it + } + ); + print "Done.\n"; +} else { + print "Aborted.\n"; + exit 1; +} diff --git a/t/formatter_wikipedialink.t b/t/formatter_wikipedialink.t new file mode 100644 index 00000000..012d5381 --- /dev/null +++ b/t/formatter_wikipedialink.t @@ -0,0 +1,59 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use Test::More tests => 6; +use lib 't/lib'; +use FakeCatalystObject; + +BEGIN { + use_ok 'MojoMojo::Formatter::WikipediaLink'; + use_ok 'Catalyst::Test', 'MojoMojo'; +} + +my $fake_c; +( undef, $fake_c ) = ctx_request('/'); +my $lang = $fake_c->pref('default_lang'); + +#----- ASCII +{ + my $content = 'see {{wikipedia Perl}}'; + MojoMojo::Formatter::WikipediaLink->format_content(\$content, $fake_c); + is( + $content, + qq|see Perl\n|, + 'default link', + ); +} + +{ + my $content = 'see {{wikipedia:ja Perl}}'; + MojoMojo::Formatter::WikipediaLink->format_content(\$content, $fake_c); + is( + $content, + qq|see Perl\n|, + 'specified language', + ); +} + +{ + my $content = 'see {{wikipedia:ja こんにちは}}'; + MojoMojo::Formatter::WikipediaLink->format_content(\$content, $fake_c); + is( + $content, + qq|see こんにちは\n|, + 'unicode keyword', + ); +} + +{ + my $content = 'see {{wikipedia Larry Wall}}'; + MojoMojo::Formatter::WikipediaLink->format_content(\$content, $fake_c); + is( + $content, + qq|see Larry Wall\n|, + 'Larry Wall ;-P', + ); +} + + +