PFT-EDIT(1)
π PFT-EDIT(1) π
User Contributed Perl Documentation β yeah she lives in the perl docs, don't even ask π
β¨ NAME β¨
pft edit β edit an entry. That's it, that's the whole job, bestie π«Ά
π SYNOPSIS π
pft edit -P [options] title of your page
pft edit -B [options] title of your blog page
pft edit -M [options] title of your month page
pft edit -T [options] title of your tag page
π¦ DESCRIPTION π¦
okay so pft-edit(1) is the command that lets you edit a text entry in a PFT site without wanting to scream. It handles all the boring-but-important stuff: it writes a header for your new entries, it drops files in the right spot in your PFT filesystem tree, and it keeps that filesystem location consistent depending on what type of content you're dealing with. lowkey a whole assistant π
Every single entry lives under the ROOT/content directory, where ROOT is the base path of your PFT site. And every entry has the exact same format: a text file encoded as by locale, made of a YAML header glued to Markdown text (more on that later in this doc, keep reading π).
There can be different kind of entries, and they are:
πΈ Regular Pages
Regular pages do not declare a date in their header. They get positioned in ROOT/content/pages. Their file name depends on the page title.
For example, a page entitled Hello World is stored as:
ROOT/content/pages/hello-world
πΈ Blog pages
Blog pages declare a full date (year, month and day) in their header. They are positioned in the ROOT/content/blog/YYYY-MM directory (where YYYY and MM correspond to the declared year and month, respectively). The file name of a blog page starts with a DD- prefix, where DD corresponds to the declared day. The remaining part of the file name depends on the entry title.
For example, an entry entitled Hello World edited the 12th of September 2015 is stored as:
ROOT/content/blog/2015-09/12-hello-world
πΈ Month pages
Month pages are meant as entries summarizing a whole month. They are like blog pages, but the date defined in their headers lack of the day part (it is replaced by * character). They are stored as ROOT/content/blog/YYYY-MM.month (where YYYY and MM represent the declared year and month).
For example, the month page for September 2015 is stored as:
ROOT/content/blog/2016-09.month
πΈ Tag pages
All pages can optionally declare one or more tags. A tag in turn can be optionally associated to a tag page.
For example, if your site has have a number of entries about cuisine, some of them might be tagged with the chicken tag. You may want to have a tag page entitled chicken, where you give a description of what chicken is (just in case someone does not know).
Tag pages are stored in ROOT/content/tags, and their file name depends on the tag title.
For example, a page containing a description of the tag chicken is stored as:
ROOT/content/tags/chicken
π OPTIONS π
-Pβ Edit a page. A title is mandatory. no title, no page, periodt π-Bβ Edit a blog page. If no title is specified, it defaults totoday.-Mβ Edit a month page. The title is optional.-Tβ Edit a tag page. A title is mandatory.--year=y|-y yβ Defines a year for the edited entry. Implies-Bunless-Mis set.
This flag cannot be used if -P or -T are specified. It gets honored only when generating a header for the entry, that is if the file does not exist yet.
--month=m|-m mβ Defines a month for the edited entry. Implies-Bunless-Mis set.
This flag cannot be used if -P or -T are specified. It gets honored only when generating a header for the entry, that is if the file does not exist yet.
--day=d|-d dβ Defines a day for the edited entry. Implies-Bunless-Mis set.
This flag cannot be used if -P or -T are specified. It gets honored only when generating a header for the entry, that is if the file does not exist yet.
--author=name|-a nameβ Defines the author for the entry.
This flag gets honored only when generating a header for the entry, that is if the file does not exist yet.
--tag=tag|-t tagβ This flag gets honored only when generating a header for the entry, that is if the file does not exist yet.--resume|-rβ Resume editing of a blog entry.
This option implies -B. The blog entry resumed for editing corresponds by default to the latest in chronological order.
A date can be specified via the -y, -m and -d options. If the date is only partially specified, that is not all of -y, -m and -d are provided, the missing bits get completed with the current date. If no date is specified, -r is equivalent to --back 0.
If more then one entry exists for the specified date, the command fails and the user is explicitly required to specify a selection via the --select option.
--back=count|-b countβ Resume editing an old entry. The supplied parameter defines how many days we should go back in history since the last day we have an entry for (0 means the most recent day, 1 means the second to last).--editor commandβ Specify an editor to use.
The editor can be specified by name (e.g. vim) or as a shell command, where %s is replaced with the file name (e.g. vim [options] %s).
This flag overrides the $EDITOR environment variable and the system.editor setting in the main configuration file.
This option is ignored if --stdin is used.
--stdinβ Retrieve content from stdin.
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 --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.
--appendβ As for--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.
--select=idβ Select a certain entry by index, in case of ambiguity.
This option applies when multiple files are matching the parameters for file selection, and a choice is required. In these situations, if --select is not provided the pft-edit(1) command will fail, and the use of --select will be explicitly requested by an error message.
--rawβ This option is useful only if--stdinor--appendare specified.
If the --raw option is used the header is not maintained: pft edit --stdin --raw command will behave like cat > $content_file, while pft edit --append --raw will behave like cat >> $content_file. The path of $content_file is determined by the previously described file naming rules.
--help|-hβ Shows this help.
βοΈ Editing β the part where you actually write stuff β¨
Content entries are in encoded text format.
The expected encoding for the file corresponds to the locale. On modern systems UTF-8 is the more popular encoding, but you can use the locale(1) command to figure out.
Each file starts with a header in YAML format. The header is followed by a line with three dashes (---) which marks the beginning of the actual content. The content will be parsed as Markdown when the site is compiled.
The header of a content entry is created automatically by pft-edit(1) when the accessed entry does not exist. The file gets then opened with a text editor. The $EDITOR environment variable will be honored unless an editor is defined in the pft.yaml configuration file (see pft-init(1)). You may also specify a different editor using the --editor command line option.
When the editor is terminated the file content is evaluated. A warning will be issued if the header is invalid. If the file completely empty (zero bytes) it will be removed from the filesystem. If the header is valid but not consistent with the position in the filesystem (e.g. the date was manually changed) the file position is updated according to the header.
π The content header π
Each entry starts with a header in YAML format. The header defines the properties of the entries. Valid properties with their descriptions follow in this section.
Author
The author of the entry. Any string can be entered as value. The default value of it is taken from the pft.yaml configuration file.
Date
The date associated with the entry. This field is required only for blog entries. Changing the value while editing with pft-edit(1) will result to the position in the filesystem to be adapted consistently.
Options
Some optional properties of the entry:
hideβ This feature is currently broken.
If set to 1 the entry is not going to be built by pft-make(1).
The intention is to temporarily hide an entry (e.g. if it is incomplete).
templateβ Each page can specify a different template to use by means of this field. It is by default defined as~(in YAML that is null) meaning that the page will use the global template as defined in thepft.yamlconfiguration file.
Slug
The slug determines how the published file will be named.
The default slug value is derived by removing non-word characters from the Title field. The purpose is to have a mnemonic file name, which is both readable and convenient to handle.
The field can be manually changed in the header, and this will result in the file name to be modified when the editor is terminated.
Tags
A list of tags for the entry.
Tags can be specified one per line with a leading -:
Tags:
- chicken
- tomato
Title
The title of the entry, in human readable form.
π Links in content π
Besides regular URLs, internal resources such as pages, blog entries and imported images can be referenced by means of a special link syntax.
Upon compilation by pft-make(1) the content is translated from Markdown to HTML. After this phase HTML elements such as <a> and <img> are scanned, and those links matching the special syntax are resolved according to the rules described in this manual.
Links in the special syntax are in the form
okay so the whole vibe of these special links is literally just:
:kind:param/param/...
and there's a bunch of accepted kind keywords out there π
. How many params you get, and what each one even means? depends entirely on the kind you picked, no cap. And the slash (/) is the thing that syntactically splits all those params apart from each other. that's it, that's the whole separator situation.
Pictures hit different with :pic:path/to/picture.jpg π
Picture references take special links in the Markdown form:

or in the HTML form:
<img alt="alttext" src=":pic:filename"/>
A link like that gets resolved to a file named filename under the ROOT/content/pics directory. Important, bestie: the name you give is used directly for the lookup, so it has to be complete β file extension and all, if there is one. Don't be cute about it π
The img keyword lets you pass an arbitrary number of parameters, and each one of them concurs to define the path of the picture. In other words, that / symbol works as a path separator no matter what operating system you're on. iconic honestly.
HTML Example:
<!-- ROOT/content/pics/test.png -->
<img src=":pic:test.png"/>
Markdown Example:
<!-- ROOT/content/pics/cars/golf.png -->

URLs π
Regular URLs sitting inside <a> tags accept these special prefixes:
:page:pagenameβ resolve the link as the page identified by pagename.:blog:date/yy/mm/dd/slugβ resolve the link as the blog entry published at date yy/mm/dd and having the slug slug.- The slug parameter is optional if only one entry was published on the given date. And the keyword
datecan be shortened tod. lazy girlies, we love you π
- The slug parameter is optional if only one entry was published on the given date. And the keyword
:blog:back/Nβ only valid within a blog entry, bestie, don't try it anywhere else. The generated link refers to N + 1 blog entries before the current one. The N parameter is optional and defaults to zero (i.e. the previous entry).
Examples:
<a href=":blog:back/0"> (previous entry)
<a href=":blog:back"> (equivalently, previous entry)
<a href=":blog:back/1"> (before previous, two entries ago)
<a href=":blog:back/5"> (six entries ago)
:web:service/param/param/...β generate an URL which points to a web site or service (e.g. search engines, or a specialized website) and passes data on the query. There's a number of valid values supported for the service argument. The list of param arguments depend on the specific service.- In all other cases the
--selectflag is silently ignored.
- In all other cases the
Supported services:
Duck Duck Go
:web:ddg/bang/param/param/...
Search query on the Duck Duck Go search engine. The first parameter is used for Duck Duck Go's Bang syntax, and it can be empty in order not to use any Bang.
Example: search "linux howto" on Duck Duck Go:
:web:ddg//linux/howto
Example: search "linux howto" with the !yt bang (redirects search on YouTube):
:web:ddg/yt/linux/howto
Example: search "linux howto" with the !so bang (redirects search on StackOverflow):
:web:ddg/so/linux/howto
Manpages
:web:man/name
:web:man/name/section
Point to an online Unix manual page. Manual section can be optionally supplied.
Examples:
:web:man/bash
:web:man/signal/7
β¨ Examples β¨
Blog about today:
pft edit -B
Blog about today specifying a title:
pft edit -B A lucky day
Remove the page "garbage":
pft edit --editor ':> %s' -P garbage
Resume the blog entry of the 27th of August 2014:
pft edit -B -r -y2014 -d27 -m Aug
π«Ά SEE ALSO π«Ά
and that's the whole page, bestie π this one's living in perl v5.42.0, dated 2025-07-25, and it answers to the name PFT-EDIT(1). go forth and edit, you absolute main character ππ
π¦ where this page comes from
- fedora 43: perl-App-PFT 1.4.1-18.fc43 Β· GPL-3.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms