line
stmt
bran
cond
sub
pod
time
code
1
package Giblog;
2
3
2
2
82682
use strict;
2
4
2
56
4
2
2
8
use warnings;
2
4
2
57
5
6
2
2
1297
use Getopt::Long 'GetOptions';
2
21870
2
9
7
2
2
823
use Giblog::API;
2
3
2
51
8
2
2
10
use Carp 'confess';
2
5
2
85
9
2
2
1039
use Pod::Usage 'pod2usage';
2
66080
2
181
10
2
2
18
use List::Util 'min';
2
4
2
181
11
2
2
12
use File::Spec;
2
4
2
1713
12
13
our $VERSION = '3.00';
14
15
sub new {
16
59
59
1
40752
my $class = shift;
17
18
59
161
my $self = {
19
@_
20
};
21
22
59
170
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
120
sub home_dir { shift->{'home_dir'} }
89
10
10
1
37
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 - Create Websites and Blogs that can be managed with Git
154
155
=begin html
156
157
158
Website
159
160
161
162
163
164
A Website Example
165
166
167
Blog
168
169
170
171
172
173
A Blog Example
174
175
176
=end html
177
178
=head1 DESCRIPTION
179
180
Giblog is a utility to create websites or blogs.
181
You can create websites or blogs using C command.
182
All created files is static files. You can manage them using B.
183
You can customize websites using C.
184
185
=head1 SYNOPSYS
186
187
# New empty website
188
$ giblog new mysite
189
190
# New website
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
# Add new entry with home directory
203
$ giblog add -C /home/perlclub/mysite
204
205
# Build website
206
$ giblog build
207
208
# Build website with home directory
209
$ giblog build -C /home/perlclub/mysite
210
211
# Serve a website
212
$ giblog serve
213
214
# Save a website
215
$ giblog save -m "Commit Messages" origin main
216
217
# Publish website
218
$ giblog publish origin main
219
220
# Deploy a website
221
$ giblog deploy
222
223
# Do "giblog build", "giblog save", "giblog publish", "giblog deploy" at once
224
$ giblog all -m "Commit Messages" origin main
225
226
=head1 FEATURES
227
228
Giblog have the following features.
229
230
=over 4
231
232
=item * Build websites and blogs.
233
234
=item * All created files is static files. You can manage files using git.
235
236
=item * Linux, macOS, Windows Support. (Windows needs msys2 or WSL2)
237
238
=item * CSS supports smart phone.
239
240
=item * Header, hooter and side bar support
241
242
=item * Customize top and bottom section of content.
243
244
=item * Customize HTML head.
245
246
=item * Automatical Line break. p tag is automatically added.
247
248
=item * Escape E, E automatically in pre tag
249
250
=item * Title tag is automatically added from first h1-h6 tag.
251
252
=item * Description meta tag is automatically added from first p tag.
253
254
=item * You can customize your website by Perl.
255
256
=item * You can serve your website in local environment. Contents changes is detected and build automatically(need L).
257
258
=item * Fast. Build 645 pages by 0.78 seconds in starndard linux environment.
259
260
=item * Support Github Pages, both user and project page.
261
262
=back
263
264
=head1 TUTORIAL
265
266
=head2 Create Websites
267
268
=head3 Create a Empty website
269
270
L command create empty website. "mysite" is a name of your website.
271
272
giblog new mysite
273
274
If you want to create empty site, choice this command.
275
Templates and CSS is empty and provide minimal site building process.
276
277
=head3 Create a Website
278
279
L command create simple website. "mysite" is a name of your website.
280
281
giblog new_website mysite
282
283
If you want to create simple website, choice this command.
284
Top page "templates/index.html" is created.
285
List page "templates/list.html" is created, which is prepare to create blog entry pages easily for feature.
286
287
CSS is responsive design and supports smart phone and provide basic site building process.
288
289
=head3 Create a Blog
290
291
L command create empty website. "mysite" is a name of your website.
292
293
giblog new_blog mysite
294
295
If you want to create blog, choice this prototype.
296
Top page "templates/index.html" is created, which show 7 days entries.
297
List page "templates/list.html" is created, which show all entries links.
298
299
CSS is responsive design and supports smart phone and provide basic blog building process.
300
301
=head2 Add a Blog Page
302
303
L command add entry page.
304
305
giblog add
306
307
You need to change the directory created by L, L, or L before
308
309
Created file name is, for example,
310
311
templates/blog/20080108132865.html
312
313
This file name contains current date and time.
314
315
To write new entry, You open it, write h2 head and content.
316
317
How to use Giblog
318
319
How to use Giblog. This is ...
320
321
Other parts wrapping content like Header and footer is automatically added in building process.
322
323
=head2 Add a Content Page
324
325
If you want to create content page, put file into "templates" directory.
326
327
templates/access.html
328
templates/profile.html
329
330
Then open these file, write h2 head and content.
331
332
How to use Giblog
333
334
How to use Giblog. This is ...
335
336
Other parts wrapping content like Header and footer is automatically added in building process.
337
338
You can put file into sub directory.
339
340
templates/profile/more.html
341
342
Note that "templates/static" and "templates/common" is special directories.
343
Don't push content page files into these directories.
344
345
# Special directories you don't put content page files into
346
templates/static
347
templates/common
348
349
=head2 Add Satic files
350
351
If you want to add static files like css, images, JavaScript, You put these file into "templates/static" directory.
352
353
Files in "templates/static" directory is only copied to public files by build process.
354
355
templates/static/js/jquery.js
356
templates/static/images/logo.png
357
templates/static/css/more.css
358
359
=head2 Customize Header or Footer, Side bar, Top of Content, Bottom of Content
360
361
You can customize header, footer, side bar, top of content, bottom of content.
362
363
------------------------
364
Header
365
------------------------
366
Top of content |
367
-----------------|
368
|Side
369
Content |bar
370
|
371
-----------------|
372
Bottom of content|
373
------------------------
374
Footer
375
------------------------
376
377
If you want to edit these section, you edit these files.
378
379
templates/common/header.html Header
380
templates/common/top.html Top of content
381
templates/common/side.html Side bar
382
templates/common/bottom.html Bottom of content
383
templates/common/footer.html Footer
384
385
=head2 Customize HTML Header
386
387
You can customize HTML header.
388
389
390
391
392
393
394
395
396
397
398
If you want to edit HTML header, you edit the following file.
399
400
templates/common/meta.html
401
402
=head2 Giblog Variables
403
404
Explains Giblog variables.
405
406
=head3 Define Giblog Variables
407
408
You can define Giblog variable in C.
409
410
# giblog.conf
411
use strict;
412
use warnings;
413
use utf8;
414
415
{
416
site_title => 'mysite',
417
site_url => 'http://somesite.example',
418
419
# Variables
420
vars => {
421
giblog_test_variable => 'Giblog Test Variable',
422
},
423
}
424
425
C defines Giblog variables in C.
426
427
=head3 Use Giblog Variables
428
429
Use Giblog variables in templtes files.
430
431
<%= $GIBLOG_VARIABLE_NAME %>
432
433
B
434
435
C
436
437
# giblog.conf
438
use strict;
439
use warnings;
440
use utf8;
441
442
{
443
site_title => 'mysite',
444
site_url => 'http://somesite.example',
445
446
# Variables
447
vars => {
448
giblog_test_variable => 'Giblog Test Variable',
449
google_analytics_id => 'G-EIFHDUGHF45',
450
},
451
}
452
453
C
454
455
456
457
458
459
460
461
468
469
=head2 Build a Website
470
471
Build a website using L command.
472
473
giblog build
474
475
You need to change the directory created by L, L, or L before executing "giblog build" command.
476
477
L command execute C method of C module.
478
479
C module exists in C.
480
481
C module is automatically created.
482
483
See C module.
484
485
# "lib/Giblog/Command/build.pm" in website created by "new_blog" command
486
package Giblog::Command::build;
487
488
use base 'Giblog::Command';
489
490
use strict;
491
use warnings;
492
493
use File::Basename 'basename';
494
495
sub run {
496
my ($self, @args) = @_;
497
498
# API
499
my $api = $self->api;
500
501
# Read config
502
my $config = $api->read_config;
503
504
# Copy static files to public
505
$api->copy_static_files_to_public;
506
507
# Get files in templates directory
508
my $files = $api->get_templates_files;
509
510
# Add base path to public css files
511
$api->add_base_path_to_public_css_files;
512
513
for my $file (@$files) {
514
# Data
515
my $data = {file => $file};
516
517
# Get content from file in templates directory
518
$api->get_content($data);
519
520
# Parse Giblog syntax
521
$api->parse_giblog_syntax($data);
522
523
# Parse title
524
$api->parse_title_from_first_h_tag($data);
525
526
# Edit title
527
my $site_title = $config->{site_title};
528
if ($data->{file} eq 'index.html' || !defined $data->{title}) {
529
$data->{title} = $site_title;
530
}
531
else {
532
$data->{title} = "$data->{title} - $site_title";
533
}
534
535
# Add page link
536
$api->add_page_link_to_first_h_tag($data, {root => 'index.html'});
537
538
# Parse description
539
$api->parse_description_from_first_p_tag($data);
540
541
# Read common templates
542
$api->read_common_templates($data);
543
544
# Add meta title
545
$api->add_meta_title($data);
546
547
# Add meta description
548
$api->add_meta_description($data);
549
550
# Build entry html
551
$api->build_entry($data);
552
553
# Build whole html
554
$api->build_html($data);
555
556
# Replace Giblog variables
557
$api->replace_vars($data);
558
559
# Add base path to content
560
$api->add_base_path_to_content($data);
561
562
# Write to public file
563
$api->write_to_public_file($data);
564
}
565
566
# Create index page
567
$self->create_index;
568
569
# Create list page
570
$self->create_list;
571
}
572
573
You can customize build process using L and any Perl programs.
574
575
L is a usuful APIs to customize websites.
576
577
=head2 Serve a Website
578
579
You can serve a website by L command.
580
581
# Serve website
582
giblog serve
583
584
You see the following message.
585
586
Web application available at http://127.0.0.1:3000
587
588
L means the following command. L is a command to serve a L app in development mode.
589
590
# Same as the following
591
morbo -w giblog.conf -w lib -w templates serve.pl
592
593
If C, files in C or C directories are changed, the website is automatically rebuild.
594
595
B
596
597
If you use Giblog 1, you can serve your website by the following way.
598
599
# Giblog 1.0
600
morbo -w giblog.conf -w lib -w templates serve.pl
601
602
=head2 Save a Website
603
604
Save Websites using L.
605
606
giblog save -m "Commit Messages" origin main
607
608
L means the following git commands.
609
610
git add --all
611
git commit -m "Commit Messages"
612
git push origin main
613
614
=head2 Publish a Website
615
616
Publish the website using L command.
617
618
# Publish the website
619
giblog publish origin main
620
621
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.
622
623
git -C public add --all
624
git -C public commit -m "Published by Giblog at YY-mm-dd HH:MM:SS"
625
git -C public push -f origin main
626
627
=head2 Deploy a Website
628
629
Deploy websites using L.
630
631
# Deploy websites
632
giblog deploy
633
634
L means the following command.
635
636
perl deploy.pl
637
638
You can write any program for the deployment in C.
639
640
use strict;
641
use warnings;
642
643
my @args = @ARGV;
644
645
my $deploy_cmd = q(ssh prod_perl_club_sites 'git -C ~/www/en_perlzemi-public fetch && git -C ~/www/en_perlzemi-public reset --hard origin/main');
646
647
system($deploy_cmd) == 0
648
or die "Can't execute deploy command: $deploy_cmd:$!";
649
650
=head2 Execute All Commands at Once
651
652
Do all Publish the website using L, L, L, L command.
653
654
giblog all -m "Commit Messages" origin main
655
656
This means the following commands
657
658
giblog build
659
giblog save -m "Hello" origin main
660
giblog publish origin main
661
giblog deploy
662
663
If C<--no-build> option is specified, "giblog build" is not executed.
664
665
giblog all --no-build -m "Commit Messages" origin main
666
667
If C<--no-save> option is specified, "giblog save" is not executed.
668
669
giblog all --no-save -m "Commit Messages" origin main
670
671
If C<--no-publish> option is specified, "giblog publish" is not executed.
672
673
giblog all --no-publish -m "Commit Messages" origin main
674
675
If C<--no-deploy> option is specified, "giblog deploy" is not executed.
676
677
giblog all --no-deploy -m "Commit Messages" origin main
678
679
=head1 CONFIG FILE
680
681
Giblog config file is "giblog.conf".
682
683
This is Perl script and return config as hash reference.
684
685
use strict;
686
use warnings;
687
use utf8;
688
689
# giblog.conf
690
{
691
site_title => 'mysite😄',
692
site_url => 'http://somesite.example',
693
}
694
695
=head2 site_title
696
697
site_title => 'mysite😄'
698
699
Site title
700
701
=head2 site_url
702
703
site_url => 'http://somesite.example'
704
705
Site URL.
706
707
=head2 base_path
708
709
base_path => '/subdir'
710
711
Base path. Base path is used to deploy your site to sub directory.
712
713
For example, Project page URL of Github Pages is
714
715
https://yuki-kimoto.github.io/giblog-theme1-public/
716
717
You specify the following
718
719
base_path => '/giblog-theme1-public'
720
721
Top character of base_path must be slash "/".
722
723
HTML files is output into "public/giblog-theme1-public" directory.
724
725
=head1 METHODS
726
727
These methods is internally methods.
728
Normally, you don't need to know these methods.
729
See L to manipulate HTML contents.
730
731
=head2 new
732
733
my $api = Giblog->new(%params);
734
735
Create L object.
736
737
B
738
739
=over 4
740
741
=item * home_dir - home directory
742
743
=item * config - config
744
745
=back
746
747
=head2 run_command
748
749
$giblog->run_command(@argv);
750
751
Run command system.
752
753
=head2 config
754
755
my $config = $giblog->config;
756
757
Get Giblog config.
758
759
=head2 home_dir
760
761
my $home_dir = $giblog->home_dir;
762
763
Get home directory.
764
765
=head1 DOCUMENT
766
767
=over 2
768
769
=item * L
770
771
=item * L
772
773
=item * L
774
775
=item * L
776
777
=item * L
778
779
=item * L
780
781
=item * L
782
783
=item * L
784
785
=item * L
786
787
=item * L
788
789
=item * L
790
791
=item * L
792
793
=back
794
795
=head1 FAQ
796
797
=head2 Dose Giblog support Windows?
798
799
Giblog doesn't support native Windows(Strawberry Perl, or Active Perl) because Giblog depends on L and L.
800
801
If you use Giblog in Windows, you can use L or WSL2.
802
803
=head2 What is the lowest version of Perl supported by Giblog?
804
805
The lowest version of Perl is the same version as L because Giblog depends on L. The current version is Perl 5.16+.
806
807
=head2 What is the lowest version of Git required by Giblog?
808
809
Git 1.8.5+.
810
811
=head2 What to consider when upgrading from Giblog 2 to Giblog 3?
812
813
Giblog 3.0 is compatible with Giblog 2.0. You can upgrade from Giblog 2.0 to Giblog 3.0 naturally.
814
815
=head2 What to consider when upgrading from Giblog 1 to Giblog 2?
816
817
From Giblog 2.0 the lowest version of Perl depends on L, so use the latest Perl as possible.
818
819
Git 1.8.5+ is required.
820
821
=head1 OFFICEAL SITE
822
823
L
824
825
=head1 AUTHOR
826
827
Yuki Kimoto, C<< >>
828
829
=head1 CONTRIBUTORS
830
831
Yasuaki Omokawa, C<< >>
832
833
=head1 LICENSE AND COPYRIGHT
834
835
Copyright 2018-2021 Yuki Kimoto.
836
837
This program is free software; you can redistribute it and/or modify it
838
under the terms of the the Artistic License (2.0). You may obtain a
839
copy of the full license at:
840
841
L
842
843
=cut
844
845
1;