App-PFT

 view release on metacpan or  search on metacpan

bin/pft  view on Meta::CPAN

use FindBin;
use File::Spec::Functions;
use File::Basename qw/basename/;

use Pod::Usage;
use Pod::Find qw/pod_where/;

use Encode;
use Encode::Locale;

$_ = decode(locale => $_) foreach @ARGV;
binmode STDIN, ':encoding(console_in)';
binmode STDOUT, ':encoding(console_out)';
binmode STDERR, ':encoding(console_out)';
$0 = basename $0;

my $subcmd = shift @ARGV;
unless (defined $subcmd) {
    print STDERR "Usage: $0 <command> [<args>]\n",
                 "Usage: $0 --help\n";
    exit 1;

bin/pft-clean  view on Meta::CPAN

            -input => App::PFT::help_of 'clean',
    }
) or exit 1;

my $tree = eval{ PFT::Tree->new } || do {
    say STDERR $@ =~ s/ at.*$//rs;
    exit 1
};

File::Path::rmtree
    encode(locale_fs => $tree->dir_build),
    { verbose => $verbose }
;

bin/pft-edit  view on Meta::CPAN


=head1 DESCRIPTION

The L<pft-edit(1)> command allows to conveniently edit a text entry in a
I<PFT> site. It takes care of creating a header for the new entries, to
position files correctly within your I<PFT> filesystem tree, and to maintain
the filesystem location consistent depending on the type of content.

All entries are stored under the C<ROOT/content> directory, where C<ROOT>
is the base path of your I<PFT> site. Each entry has the same format:
a text file encoded as by locale, composed by a I<YAML> header concatenated
with Markdown text (more details later in this document).

There can be different kind of entries:

=over

=item Regular Pages

Regular pages do not declare a date in their header. They get positioned
in C<ROOT/content/pages>. Their file name depends on the page title.

bin/pft-edit  view on Meta::CPAN

The content file is selected according to the given options, and the content is
retrieved from standard input.  If the file does exist it gets created with a
reasonable header. If the file exists but the header is corrupted, the whole
file gets replaced.  If the file exists and the header is well formed, the
header is maintained and the remaining part of the file is replaced with content
retrieved from standard input.

If this option is in use the B<--editor> is ignored.

This editing mode handles input and output encoding according to the current
locale, under the assumption that your content is text data.

=item B<--append>

As for B<--stdin>, but append content instead of replacing it.

If the content file does not exist or is empty, and header will be
automatically defined depending on the given command options.

If the header exists but is corrupted, the command will issue a warning.
No corrective action will be taken.

bin/pft-edit  view on Meta::CPAN

=item B<--help> | B<-h>

Shows this help.

=back

=head2 Editing

Content entries are in encoded text format.

The expected encoding for the file corresponds to the C<locale>.  On modern
systems I<UTF-8> is the more popular encoding, but you can use the
L<locale(1)> command to figure out.

Each file starts with a header in I<YAML> format. The header is followed
by a line with three dashes (C<--->) which marks the beginning of the
actual content. The content will be parsed as I<Markdown> when the site is
compiled.

The header of a content entry is created automatically by L<pft-edit(1)>
when the accessed entry does not exist. The file gets then opened with a
text editor. The C<$EDITOR> environment variable will be honored unless an
editor is defined in the C<pft.yaml> configuration file (see

bin/pft-edit  view on Meta::CPAN

    if ($opts{stdin}) {
        die "Supported --stdin or --append, not both" if $opts{append};
    }
    elsif ($opts{append}) {
        if (-f $entry->path) {
            $mode .= '>';
            $skip_header = 1;
        }
    }

    open my $out, "$mode:encoding(locale)", $entry->path
        or die 'Cannot open ', $entry->path, ": $!";
    $hdr->dump($out) unless $skip_header;
    print $out <STDIN>;
    close $out;
}

eval {
    if ($opts{stdin} or $opts{append}) {
        feed_file
    }

bin/pft-gen-rss  view on Meta::CPAN

my $feed_path   = $conf->{site}{feed}{path} || "feed.rss";
my $feed_url    = "$site_url/$feed_path";
my $encoding    = $conf->{site}{encoding};
my $description = $conf->{site}{feed}{description} || "News from $site_title";
my $length      = $conf->{site}{feed}{length} || 10;

my $outfile;
do {
    my $path = catfile($tree->dir_build, $feed_path);

    make_path encode(locale_fs => dirname($path));
    open($outfile, ">:encoding($encoding)", encode(locale_fs => $path))
        or die "opening $path $!";
    select $outfile;
};

sub node_to_href {
    my $node = shift;
    confess unless $node;

    join '/', $site_url, do {
        my $hdr = $node->header;

bin/pft-grab  view on Meta::CPAN

};

my $dst_dir = do {
    if ($opts{date_prefix} || grep defined @date{qw/year month day/}) {
        catdir($dst_base, PFT::Date->from_spec(%date)->repr('-'))
    } else {
        $dst_base
    }
};

make_path encode(locale_fs => $dst_dir);

ITEM: for my $orig_path (@ARGV) {
    my $uri = URI->new($orig_path);
    my $fn = basename $uri->path . ($uri->query || '');

    my $dst_path = catfile($dst_dir, $opts{rename} || $fn);

    if ($uri->has_recognized_scheme) {
        my $status = LWP::Simple::getstore($uri->as_string, $dst_path);
        if ($status < 200 || $status >= 300) {

bin/pft-init  view on Meta::CPAN

    author => $conf->{site}{author},
));
$home->open('a') unless $home->exists;

my $glob = File::Spec->catdir(
    File::ShareDir::module_dir('App::PFT'),
    'templates',
    '*',
);

foreach (glob encode(locale_fs => $glob)) {
    my $outfn = File::Spec->catfile(
        encode(locale_fs => $tree->dir_templates),
        basename($_)
    );

    open my $in, '< :encoding(UTF-8)', $_ or do {
        say STDERR 'Cannot open ', decode(locale_fs => $_), ": $!";
        exit 1;
    };

    open my $out, '> :encoding(locale_fs)', $outfn or do {
        say STDERR 'Cannot open ', decode(locale_fs => $outfn), ": $!";
        exit 1;
    };

    print $out (<$in>);

    close $in;
    close $out;
};

=head1 CONFIGURATION OPTIONS

bin/pft-init  view on Meta::CPAN

Defaults to $USER (environment variable).

=item B<--site-author>=I<USER>

Global Author, can be overriden by individual entries.
Defaults to C<$USER> (environment variable).

=item B<--site-encoding>=I<ENC>

Charset of the generated web pages.
Defaults to what is defined by L<locale(1)>.

=item B<--site-feed-description>=I<DESC>

Description of the channel (C<E<lt>descriptionE<gt>> in the XML).
Defaults to C<News from a PFT website>.

=item B<--site-feed-length>=I<N>

Number of most recent blog entries to list in the RSS feed.
Defaults to C<10>.

bin/pft-ls  view on Meta::CPAN

=item B<--pretty>=I<fmt>

Print properties of the listed nodes according to the specified format. The
format supports a custom percent notation similar in spirit to L<printf(2)>.

Note that some of placeholders will be expanded with empty strings when the
corresponding object property is void. For example, pages don't have a
date). If this is the case the placeholder gets expanded with an empty
string.

The output is encoding depending on the locale.

=over

=item %t

Title

=item %p

Path (might be void if the node is virtual)

bin/pft-make  view on Meta::CPAN

    );

    write_file $out_data => $out_path;
}

sub install_blob {
    my($node, $content) = @_;

    my $out_path = File::Spec->catfile($dir_build, node_to_rel($node));

    ln encode(locale_fs => $content->path),
       encode($conf->{site}{encoding}, $out_path)
}

my $inject = $tree->dir_inject;
foreach (
    File::Spec->no_upwards(
        map substr($_, 1 + length $inject) => (
            PFT::Util::locale_glob(File::Spec->catfile($inject, '*')),
            PFT::Util::locale_glob(File::Spec->catfile($inject, '.*')),
        )
    )
) {
    my $orig = File::Spec->catfile($inject, $_);
    my $dst = File::Spec->catfile($dir_build, $_);
    ln encode(locale_fs => $orig),
       encode($conf->{site}{encoding}, $dst)
}

if (defined $home_node) {
    my $fn = File::Spec->catfile($dir_build, 'index.html');
    open my $f, ">:encoding($conf->{site}{encoding})", $fn
        or croak "Unable to open $fn: $!";
    my $href = join '/', node_to_rel($home_node);
    my $title = $home_node->title;
    print $f

bin/pft-pub  view on Meta::CPAN

    defined $tree || return qw/path/;
    check qw/path/;

    my $dst = File::Spec->rel2abs($conf->{publish}{path}, $tree->dir_base);

    remove_tree $dst, { verbose => 0 };
    make_path $dst, { verbose => 0 };

    local $File::Copy::Recursive::CopyLink = 0;
    File::Copy::Recursive::rcopy_glob(
        encode(locale => File::Spec->catfile($tree->dir_build, '*')),
        encode(locale => $dst),
    );
}

t/editing_cases.t  view on Meta::CPAN

Sincerely, Your Bottom.
IN

my $filename;
run ["$pft-ls", qw(blog --pretty=%p)], \undef, \$filename, \$err;
chomp($filename);
ok -e $filename => "File exists ($filename)";

# Breaking header
subtest 'breaking header' => sub {
    open my $content, '+< :encoding(locale)', $filename or die "$!";
    scalar <$content>;
    my $second = <$content>;
    seek $content, -length($second), 1;
    ok $second =~ s/:/_/ => "Replaced second line: $second";
    print $content $second;
    seek $content, 0, 0;
    diag($_) foreach <$content>;
    close $content;
};



( run in 0.754 second using v1.01-cache-2.11-cpan-ceb78f64989 )