File Coverage

blib/lib/Giblog.pm
Criterion Covered Total %
statement 29 88 32.9
branch 0 22 0.0
condition 0 3 0.0
subroutine 11 18 61.1
pod 6 6 100.0
total 46 137 33.5


line stmt bran cond sub pod time code
1             package Giblog;
2              
3 2     2   73922 use strict;
  2         6  
  2         67  
4 2     2   12 use warnings;
  2         3  
  2         62  
5              
6 2     2   1585 use Getopt::Long 'GetOptions';
  2         24733  
  2         45  
7 2     2   1014 use Giblog::API;
  2         9  
  2         76  
8 2     2   16 use Carp 'confess';
  2         4  
  2         123  
9 2     2   1354 use Pod::Usage 'pod2usage';
  2         83520  
  2         307  
10 2     2   23 use List::Util 'min';
  2         5  
  2         236  
11 2     2   16 use File::Spec;
  2         5  
  2         2150  
12              
13             our $VERSION = '2.01_02';
14              
15             sub new {
16 59     59 1 112895 my $class = shift;
17              
18 59         172 my $self = {
19             @_
20             };
21              
22 59         175 return bless $self, $class;
23             }
24              
25             sub _extract_usage {
26 0 0   0   0 my $file = @_ ? "$_[0]" : (caller 1)[1];
27              
28 0         0 open my $handle, '>', \my $output;
29 0         0 pod2usage -exitval => 'noexit', -input => $file, -output => $handle;
30 0         0 $output =~ s/^.*\n|\n$//;
31 0         0 $output =~ s/\n$//;
32              
33 0         0 return _unindent($output);
34             }
35              
36             sub _unindent {
37 0     0   0 my $str = shift;
38 0 0       0 my $min = min map { m/^([ \t]*)/; length $1 || () } split "\n", $str;
  0         0  
  0         0  
39 0 0       0 $str =~ s/^[ \t]{0,$min}//gm if $min;
40 0         0 return $str;
41             }
42              
43             sub run_command {
44 0     0 1 0 my ($class, @argv) = @_;
45              
46             # Command line option
47 0         0 local @ARGV = @argv;
48 0         0 my $getopt_option_save = Getopt::Long::Configure(qw(default no_auto_abbrev no_ignore_case pass_through));
49 0         0 GetOptions(
50             "h|help" => \my $help,
51             "H|C|home=s" => \my $home_dir,
52             );
53 0         0 Getopt::Long::Configure($getopt_option_save);
54              
55             # Command name
56 0         0 my $command_name = shift @ARGV;
57              
58             # Show help
59 0 0 0     0 die _extract_usage if $help || !$command_name;
60              
61             # Giblog
62 0         0 my $giblog = Giblog->new(home_dir => $home_dir);
63              
64             # API
65 0         0 my $api = Giblog::API->new(giblog => $giblog);
66              
67             # Add "lib" in home directory to include path
68 0         0 local @INC = @INC;
69 0 0       0 if (defined $home_dir) {
70 0         0 unshift @INC, "$home_dir/lib";
71             }
72             else {
73 0         0 unshift @INC, "lib";
74             }
75              
76             # Command is implemented in command
77 0         0 my $command_class = "Giblog::Command::$command_name";
78 0         0 eval "use $command_class;";
79 0 0       0 if ($@) {
80 0         0 confess "Can't load command $command_class:\n$!\n$@";
81             }
82 0         0 my $command = $command_class->new(api => $api);
83              
84 0         0 @argv = @ARGV;
85 0         0 $command->run(@argv);
86             }
87              
88 53     53 1 161 sub home_dir { shift->{'home_dir'} }
89 10     10 1 41 sub config { shift->{config} }
90              
91             sub build {
92 0     0 1   my ($class) = @_;
93              
94             # Build
95 0           my $cmd = 'giblog build';
96 0 0         system($cmd) == 0
97             or die "Can't execute $cmd: $!";
98             }
99              
100             sub serve {
101 0     0 1   my ($class, $app) = @_;
102              
103             # Read config file
104 0           my $config_file = "$FindBin::Bin/giblog.conf";
105 0           my $config;
106 0 0         $config = do $config_file
107             or die "Can't read config file $config_file";
108              
109             # Remove base path before dispatch
110 0           my $base_path = $config->{base_path};
111 0 0         if (defined $base_path) {
112              
113             # Subdir depth
114 0           my @parts = File::Spec->splitdir($base_path);
115 0           my $subdir_depth = @parts - 1;
116              
117             $app->hook(before_dispatch => sub {
118 0     0     my $c = shift;
119              
120             # Root is redirect
121 0 0         unless (@{$c->req->url->path->parts}) {
  0            
122 0           $c->stash(is_redirect => 1);
123             }
124              
125             # Remove base path
126 0           for (my $i = 0; $i < $subdir_depth; $i++) {
127 0           shift @{$c->req->url->path->parts};
  0            
128             }
129 0           });
130             }
131              
132 0           my $r = $app->routes;
133              
134             $r->get('/' => sub {
135 0     0     my $c = shift;
136              
137 0           my $is_redirect = $c->stash('is_redirect');
138 0 0         if ($is_redirect) {
139 0           $c->redirect_to($base_path);
140             }
141             else {
142 0           $c->reply->static('index.html');
143             }
144 0           });
145              
146 0           $app->start;
147             }
148              
149             =encoding utf8
150              
151             =head1 NAME
152              
153             Giblog - Web site and Blog builders you can manage with Git
154              
155             =begin html
156              
157            

158             Website
159            

160            

161            
162            

163            

164             Website Example
165            

166            

167             Blog
168            

169            

170            
171            

172            

173             Blog Example
174            

175              
176             =end html
177              
178             =head1 DESCRIPTION
179              
180             Giblog is a utility to create your web site or blog.
181             You can create your web site or blog using C command.
182             All created files is static files, so you can manage them using B.
183             You can freely customize your website by editting the C command.
184              
185             =head1 SYNOPSYS
186            
187             # New empty web site
188             $ giblog new mysite
189              
190             # New web site
191             $ giblog new_website mysite
192              
193             # New blog
194             $ giblog new_blog mysite
195              
196             # Change directory
197             $ cd mysite
198              
199             # Add new entry
200             $ giblog add
201              
202             # Build web site
203             $ giblog build
204            
205             # Serve a web site
206             $ giblog serve
207              
208             # Publish web site
209             $ giblog publish origin main
210              
211             # Add new entry with home directory
212             $ giblog add --home /home/kimoto/mysite
213              
214             # Build web site with home directory
215             $ giblog build --home /home/kimoto/mysite
216              
217             =head1 FEATURES
218              
219             Giblog have the following features.
220              
221             =over 4
222              
223             =item * Build Website and Blog.
224              
225             =item * Git mangement. All created files is Static. you can manage files by git.
226              
227             =item * Linux, macOS, Windows Support. (In Windows, recommend installation of msys2)
228              
229             =item * Provide default CSS for Smart phone site.
230              
231             =item * Header, Hooter and Side bar support
232              
233             =item * You can customize Top and Bottom section of content.
234              
235             =item * You can customize HTML head.
236              
237             =item * Automatical Line break. p tag is automatically added.
238              
239             =item * Escape E, E automatically in pre tag
240              
241             =item * Title tag is automatically added from first h1-h6 tag.
242              
243             =item * Description meta tag is automatically added from first p tag.
244              
245             =item * You can customize your web site by Perl.
246              
247             =item * You can serve your web site in local environment. Contents changes is detected and build automatically(need L).
248              
249             =item * Fast. Build 645 pages by 0.78 seconds in starndard linux environment.
250              
251             =item * Support Github Pages, both user and project page.
252              
253             =back
254              
255             =head1 TUTORIAL
256              
257             =head2 Create web site
258              
259             B<1. Create Empty website>
260              
261             "new" command create empty website. "mysite" is a name of your web site.
262              
263             giblog new mysite
264              
265             If you want to create empty site, choice this command.
266             Templates and CSS is empty and provide minimal site building process.
267              
268             B<2. Create Website>
269              
270             "new_website" command create simple website. "mysite" is a name of your web site.
271              
272             giblog new_website mysite
273              
274             If you want to create simple website, choice this command.
275             Top page "templates/index.html" is created.
276             List page "templates/list.html" is created, which is prepare to create blog entry pages easily for feature.
277              
278             CSS is responsive design and supports smart phone and provide basic site building process.
279              
280             B<3. Create Blog>
281              
282             "new_blog" command create empty website. "mysite" is a name of your web site.
283              
284             giblog new_blog mysite
285              
286             If you want to create blog, choice this prototype.
287             Top page "templates/index.html" is created, which show 7 days entries.
288             List page "templates/list.html" is created, which show all entries links.
289              
290             CSS is responsive design and supports smart phone and provide basic blog building process.
291              
292             =head2 Add blog entry page
293              
294             You need to change directory to "mysite" before run "add" command if you are in other directory.
295              
296             cd mysite
297              
298             "add" command add entry page.
299              
300             giblog add
301              
302             Created file name is, for example,
303              
304             templates/blog/20080108132865.html
305              
306             This file name contains current date and time.
307              
308             To write new entry, You open it, write h2 head and content.
309              
310            

How to use Giblog

311              
312             How to use Giblog. This is ...
313              
314             Other parts wrapping content like Header and footer is automatically added in building process.
315              
316             =head2 Add content page
317              
318             If you want to create content page, put file into "templates" directory.
319              
320             templates/access.html
321             templates/profile.html
322              
323             Then open these file, write h2 head and content.
324              
325            

How to use Giblog

326              
327             How to use Giblog. This is ...
328              
329             Other parts wrapping content like Header and footer is automatically added in building process.
330              
331             You can put file into sub directory.
332              
333             templates/profile/more.html
334              
335             Note that "templates/static" and "templates/common" is special directories.
336             Don't push content page files into these directories.
337              
338             # Special directories you don't put content page files into
339             templates/static
340             templates/common
341              
342             =head2 Add static page
343              
344             If you want to add static files like css, images, JavaScript, You put these file into "templates/static" directory.
345              
346             Files in "templates/static" directory is only copied to public files by build process.
347              
348             templates/static/js/jquery.js
349             templates/static/images/logo.png
350             templates/static/css/more.css
351              
352             =head2 Customize header or footer, side bar, top of content, bottom of content
353              
354             You can customize header, footer, side bar, top of content, bottom of content.
355              
356             ------------------------
357             Header
358             ------------------------
359             Top of content |
360             -----------------|
361             |Side
362             Content |bar
363             |
364             -----------------|
365             Bottom of content|
366             ------------------------
367             Footer
368             ------------------------
369              
370             If you want to edit these section, you edit these files.
371              
372             templates/common/header.html Header
373             templates/common/top.html Top of content
374             templates/common/side.html Side bar
375             templates/common/bottom.html Bottom of content
376             templates/common/footer.html Footer
377              
378             =head2 Customize HTML header
379              
380             You can customize HTML header.
381              
382            
383            
384            
385            
386            
387              
388            
389            
390              
391             If you want to edit HTML header, you edit the following file.
392              
393             templates/common/meta.html
394              
395             =head2 Build web site
396              
397             You need to change directory to "mysite" before run "build" command if you are in other directory.
398              
399             cd mysite
400              
401             "build" command build web site.
402              
403             giblog build
404              
405             What is build process?
406              
407             build process is writen in "lib/Giblog/Command/build.pm".
408              
409             "build" command only execute "run" method in "Giblog::Command::build.pm" .
410              
411             # "lib/Giblog/Command/build.pm" in web site created by "new_blog" command
412             package Giblog::Command::build;
413              
414             use base 'Giblog::Command';
415              
416             use strict;
417             use warnings;
418              
419             use File::Basename 'basename';
420              
421             sub run {
422             my ($self, @args) = @_;
423              
424             # API
425             my $api = $self->api;
426              
427             # Read config
428             my $config = $api->read_config;
429              
430             # Copy static files to public
431             $api->copy_static_files_to_public;
432              
433             # Get files in templates directory
434             my $files = $api->get_templates_files;
435              
436             for my $file (@$files) {
437             # Data
438             my $data = {file => $file};
439              
440             # Get content from file in templates directory
441             $api->get_content($data);
442              
443             # Parse Giblog syntax
444             $api->parse_giblog_syntax($data);
445              
446             # Parse title
447             $api->parse_title_from_first_h_tag($data);
448              
449             # Edit title
450             my $site_title = $config->{site_title};
451             if ($data->{file} eq 'index.html') {
452             $data->{title} = $site_title;
453             }
454             else {
455             $data->{title} = "$data->{title} - $site_title";
456             }
457              
458             # Add page link
459             $api->add_page_link_to_first_h_tag($data, {root => 'index.html'});
460              
461             # Parse description
462             $api->parse_description_from_first_p_tag($data);
463              
464             # Read common templates
465             $api->read_common_templates($data);
466              
467             # Add meta title
468             $api->add_meta_title($data);
469              
470             # Add meta description
471             $api->add_meta_description($data);
472              
473             # Build entry html
474             $api->build_entry($data);
475              
476             # Build whole html
477             $api->build_html($data);
478              
479             # Write to public file
480             $api->write_to_public_file($data);
481             }
482              
483             # Create index page
484             $self->create_index;
485              
486             # Create list page
487             $self->create_list;
488             }
489              
490             You can customize build process if you need.
491              
492             If you need to know Giblog API, see L.
493              
494             =head2 Serve web site
495              
496             You can serve web site by C command.
497              
498             # Serve web site
499             giblog serve
500              
501             You see the following message.
502              
503             Web application available at http://127.0.0.1:3000
504              
505             This command is same as the following code. L command of L start up C.
506              
507             # Same as the following
508             morbo -w giblog.conf -w lib -w templates serve.pl
509              
510             If C, files in C or C directory is changed, Web site is automatically rebuild.
511              
512             If you use before Giblog 2.0, you can serve a web site by the following way.
513              
514             # Old style before Giblog 2.0
515             morbo serve.pl
516              
517             =head2 Publish web site
518              
519             You can publish the web site by C command.
520              
521             # Publish the web site
522             giblog publish origin main
523              
524             This is the same as the following command. In this example, the repository name is origin and the branch name is main. YY-mm-dd HH:MM:SS is current date and time.
525              
526             git -C public add --all
527             git -C public commit -m "Published by Giblog at YY-mm-dd HH:MM:SS"
528             git -C public push origin main
529              
530             =head1 CONFIG FILE
531              
532             Giblog config file is "giblog.conf".
533              
534             This is Perl script and return config as hash reference.
535              
536             use strict;
537             use warnings;
538             use utf8;
539              
540             # giblog.conf
541             {
542             site_title => 'mysite😄',
543             site_url => 'http://somesite.example',
544             }
545              
546             =head2 site_title
547              
548             site_title => 'mysite😄'
549              
550             Site title
551              
552             =head2 site_url
553              
554             site_url => 'http://somesite.example'
555              
556             Site URL.
557              
558             =head2 base_path
559              
560             base_path => '/subdir'
561              
562             Base path. Base path is used to deploy your site to sub directory.
563              
564             For example, Project page URL of Github Pages is
565              
566             https://yuki-kimoto.github.io/giblog-theme1-public/
567              
568             You specify the following
569              
570             base_path => '/giblog-theme1-public'
571              
572             Top character of base_path must be slash "/".
573              
574             HTML files is output into "public/giblog-theme1-public" directory.
575              
576             =head1 METHODS
577              
578             These methods is internally methods.
579             Normally, you don't need to know these methods.
580             See L to manipulate HTML contents.
581              
582             =head2 new
583              
584             my $api = Giblog->new(%params);
585              
586             Create L object.
587              
588             B
589              
590             =over 4
591              
592             =item * home_dir - home directory
593              
594             =item * config - config
595              
596             =back
597              
598             =head2 run_command
599              
600             $giblog->run_command(@argv);
601              
602             Run command system.
603              
604             =head2 config
605              
606             my $config = $giblog->config;
607              
608             Get Giblog config.
609              
610             =head2 home_dir
611              
612             my $home_dir = $giblog->home_dir;
613              
614             Get home directory.
615              
616             =head1 DOCUMENT
617              
618             =over 2
619              
620             =item * L
621              
622             =item * L
623              
624             =item * L
625              
626             =item * L
627              
628             =item * L
629              
630             =item * L
631              
632             =item * L
633              
634             =item * L
635              
636             =item * L
637              
638             =item * L
639              
640             =item * L
641              
642             =item * L
643              
644             =back
645              
646             =head1 FAQ
647              
648             =head2 Dose Giblog support Windows?
649              
650             Giblog doesn't support native Windows(Strawberry Perl, or Active Perl) because Giblog depends on L and L.
651              
652             If you use Giblog in Windows, you can use L or WSL2.
653              
654             =head2 What is the lowest version of Perl supported by Giblog?
655              
656             The lowest version of Perl is the same version as L because Giblog depends on L. The current version is Perl 5.16+.
657              
658             =head2 What is the lowest version of Git required by Giblog?
659              
660             Git 1.8.5+.
661              
662             =head2 What to consider when upgrading from Giblog 2 to Giblog 3?
663              
664             Giblog 3.0 is compatible with Giblog 2.0. You can upgrade from Giblog 2.0 to Giblog 3.0 naturally.
665              
666             =head2 What to consider when upgrading from Giblog 1 to Giblog 2?
667              
668             From Giblog 2.0 the lowest version of Perl depends on L, so use the latest Perl as possible.
669              
670             Git 1.8.5+ is required.
671              
672             =head1 OFFICEAL SITE
673              
674             L
675              
676             =head1 AUTHOR
677              
678             Yuki Kimoto, C<< >>
679              
680             =head1 CONTRIBUTORS
681              
682             Yasuaki Omokawa, C<< >>
683              
684             =head1 LICENSE AND COPYRIGHT
685              
686             Copyright 2018-2021 Yuki Kimoto.
687              
688             This program is free software; you can redistribute it and/or modify it
689             under the terms of the the Artistic License (2.0). You may obtain a
690             copy of the full license at:
691              
692             L
693              
694             =cut
695              
696             1;