This Theme is a port of the wonderful Freelancer Theme from Start Bootstrap, optimized for PicoCMS.
Freelancer is a one page, freelancer portfolio theme built with Bootstrap created by Start Bootstrap. This theme features several content sections, a responsive portfolio grid, modal windows for each portfolio item, and a contact form.
A Live Demo of the original theme is available from Start Bootstrap themselves.
To use this theme:
- Download the Latest Release on GitHub (or clone the repo directly into your Pico
themesfolder). - Extract all files to
themes/freelancer-picofolder within your Pico installation. - Set your
themetofreelancer-picoin Pico'sconfig.yml. - Configure your website using
index.mdand the YAML options described in Index Configuration below.- There's an optional starter template you can use if you want. Simply copy
index-sample.mdto yourcontentfolder and rename itindex.md. It comes with every possible config option, with the proper YAML indentation, but starts commented out. - Simply uncomment (remove the
#) the lines you need and their respective parents.
- There's an optional starter template you can use if you want. Simply copy
- Add items to your portfolio by adding
.mdfiles. Portfolio items have a few configuration options, so see Page Configuration below for more details.
Freelancer for Pico builds you a one-page site with a portfolio gallery made from your markdown .md pages.
Your pages will each show up as a thumbnail tile in the portfolio section, and they'll showcase their content in a modal popup dialog.
Configuration of Freelancer is done entirely through the YAML metadata of your index.md. This metadata also contains all the content for the main page besides the portfolio items.
Please note that the content of your index.md (that is to say, the part after the YAML metadata) isn't actually used for anything in this theme, so if you write something there, you won't see it displayed anywhere.
We'll go into more details about the many configuration options below.
This Pico port also adds limited support for having additional, standalone pages. Any Pico page can be visited (gallery items included) and will be rendered as the full page instead of the usual Heading, Portfolio, About, and Contact sections. These pages won't be exposed as links anywhere however, you'll have to link to them yourself. They are mostly intended for semi-hidden pages, such as linking to a more in-depth page about one of your portfolio items. You can use them however you see fit. And if you add hidden: true to your page, it'll also be hidden from the gallery.
Pico has several choices when it comes to ordering your pages (alphabetically, by date, or using a page meta property). With Freelancer, page order is used to determine the order of your portfolio items. You can change it in Pico's config.yml by changing the pages_order_by property.
# Example of Alphabetical order:
pages_order_by: alpha
pages_order: ascOptionally, if you'd like your portfolio items to instead display in a specific, static order, you can set pages_order_by to meta, change pages_order_by_meta to index, and then give each page an index value in its metadata (eg index: 0, index: 1 and so on). You'll probably also want to set your pages_order to ascending (asc) if it's not already.
# Example of a Static order, using an `index` metadata value
pages_order_by_meta: index
pages_order_by: meta
pages_order: ascThe bulk of Freelancer's configuration is done through your index.md, through a series of nested sections.
Indentation is important in your YAML header, so make sure each item is nested properly! They should also be in lower case.
Most items are optional and have default values.
There's an index-sample.md template available for you to copy if you'd like the indentation taken care of for you. Just be sure that your editor doesn't try to mess up the indentation when you uncomment each line.
The following items are root-level, don't need to be indented, and don't have subsections.
-
title - This is the standard Pico title header. If a title is given on your index page, it will be used instead of Pico's
site_titleconfig option, and will be displayed on your Navbar and under your avatar image. -
og_image - The path to an "Open Graph" standard image (eg
og_image: "%assets_url%/og_image.png"). This is the little preview image that displays when someone shares your URL via most modern messaging apps. -
robots - PicoCMS's default handling of the
robotsmeta option. Whatever you enter here (egnoindex, nofollow) will be put in thecontentattribute of the meta robots tag. -
css - The path to a custom
.cssfile (eg"%assets_url%/styles.css") that you can use to override and augment this theme's css styles. You can also specify multiple files by using the relevant YAML notation. See Color Customization for additional information on styling.
# Example with multiple files.
css:
- "%assets_url%/styles1.css"
- "%assets_url%/styles2.css"- fonts - The url or path to a custom font via a CSS stylesheet. You can provide your own, or use a Google Fonts API url to easily add more fonts. You can also specify multiple files by using the relevant YAML notation.
# Example with multiple files.
fonts:
- https://fonts.googleapis.com/css?family=Roboto
- https://fonts.googleapis.com/css?family=UbuntuThe header section contains configuration related to Freelancer's masthead (the big header at the top of the page containing your avatar).
-
avatar - The path to your avatar image (eg,
"%assets_url%/avatar.png"). -
avatar_alt - Accessibility
alttext for your avatar image. Optional, and probably not necessary unless your image conveys extra information that needs an accessibility explanation. -
divider - The Font Awesome icon to use in the divider underneath this section's header. You can search Font Awesome's website or browse the FontAwesome v5 Cheatsheet for available icon names. You should only enter the name of the icon, without its
fa-prefix. Please note, only free icons are supported in this theme. -
skills - A list of your personal skills (or anything other text) you'd like displayed under the divider in your masthead.
-
disabled - Set this to
trueif you'd like to disable this section of the page.
# Example Header Section
header:
avatar: "%assets_url%/avatar.png"
divider: pen
skills: Writer, Blogger, Journalist.The nav section contains configuration related to the navigation bar.
-
portfolio - An override for the title of the
portfoliosection. If not supplied, the navbar will default to using the title of the section. -
about - An override for the title of the
aboutsection. If not supplied, the navbar will default to using the title of the section. -
contact - An override for the title of the
contactsection. If not supplied, the navbar will default to using the title of the section. -
disabled - Set this to
trueif you'd like to disable the navbar.
# Example Nav Section
nav:
portfolio: Projects
about: About
contact: Contact UsThe portfolio section contains configuration related to the portfolio gallery.
-
title - The heading of the
portfoliosection. -
divider - The Font Awesome icon to use in the divider underneath this section's header. You can search Font Awesome's website for available icon names. You should only enter the name of the icon, without its
fa-prefix. Please note, only free icons are supported in this theme. -
disabled - Set this to
trueif you'd like to disable theportfoliosection. -
disable_close_buttons - Set this to
trueif you don't want your portfolio modal popups to have theClose Windowbutton at the bottom (they will still have anXat the top of the window).
# Example Portfolio Section
portfolio:
title: Recent Projects
divider: clock
disable_close_buttons: trueThe about section contains configuration related to the about section of the page, no surprise there. This section contains a few blocks worth of text, with optional button "actions" at the bottom.
-
title - The heading of the
aboutsection. -
divider - The Font Awesome icon to use in the divider underneath this section's header. You can search Font Awesome's website for available icon names. You should only enter the name of the icon, without its
fa-prefix. Please note, only free icons are supported in this theme. -
content - The
contentfor the about section. This block of text supports inline markdown elements (links, emphasis, etc). Text will be split into paragraphs based on line breaks, and this section fits about two to three paragraphs (It's designed for two, but will fit up to three before they start to wrap onto another row.) You can write multiple paragraphs easily using|(vertical pipe) to indicate a text block -
disabled - Set this to
trueif you'd like to disable theaboutsection.
# Example Config
about:
title: About Me
divider: question
content: |
According to the earlier example, I suppose I'm a writer, blogger and journalist.
You should check out my work, because I'm very important and successful.- actions - Add buttons to the bottom of your
aboutsection. See the Actions section below for details.
The contact section lets you configure and display your contact information, either as buttons or an email form.
Please note that having the contact form send email requires additional setup which is unfortunately out-of-scope of this theme. Sending email is a complicated process with security implications and should only be attempted if you're well versed in the subject. Please also check out the Contact Form Disclaimer below.
-
title - The heading of the
contactsection. -
divider - The Font Awesome icon to use in the divider underneath this section's header. You can search Font Awesome's website for available icon names. You should only enter the name of the icon, without its
fa-prefix. Please note, only free icons are supported in this theme. -
subtitle - A secondary heading, displayed between the contact form and contact icons if using both.
-
subdivider - A secondary divider, displayed between the contact form and contact icons if using both.
-
disabled - Set this to
trueif you'd like to disable thecontactsection. -
form - Use the following subsections to configure your contact form, if you'd like one. (Please read above!)
-
enabled - Set this to
trueif you'd like to have a contact form, either on its own or in addition to contact icons. -
action - The
actionattribute of your contact form. This is the HTTP address to send it to for processing. -
method - The
methodattribute of your contact form, usuallyGETorPOSTdepending on your backend.
-
# Example of a contact section using a contact form.
contact:
title: Get in Touch
divider: envelope
form:
enabled: true
action: "%assets_url%/email.php"
method: POST-
items - A YAML array of contact methods to render as icons in the contact section. The start of each item should be indented with a
-dash.-
title - The name of the contact method. This is displayed in smaller print above its
content. -
icon - The Font Awesome icon to use for this contact method. You can search Font Awesome's website for available icon names. You should only enter the name of the icon, without its
fa-prefix. Please note, only free icons are supported in this theme. -
brands - Set this to
trueif you're using an icon from the Font Awesome "Brands" collection (eg,twitter,facebook,github, etc.) Without it, the icon will fail to display. Likewise, enablingbrandson a non-brand icon will cause it to fail as well, since they are in separate icon sets. -
content - The content text of this contact method. Typically the short version of your address or handle (eg @my_name). This will be a clickable link if you include the
linkproperty below. -
link - The destination URL for your contact method. Turns the
contentinto a link.
-
# Example of a contact section using icons
contact:
items:
- title: Twitter
icon: twitter
brands: true
content: "@my_name_1234"
link: https://twitter.com/my_name_1234
- title: Email
icon: envelope
content: name@example.com
link: mailto:name@example.comThe location section is located at the far left of the footer. It can hold a small blurb such as an address.
-
title - The heading of the
locationsection. -
content - The
contentfor the location section. This block of text supports inline markdown elements (links, emphasis, etc). Text will be split into paragraphs based on line breaks. You can write multiple paragraphs easily using|(vertical pipe) to indicate a text block -
disabled - Set this to
trueif you'd like to disable thelocationsection.
# Example Location Section
location:
title: Address
content: |
123 Example Ave
Someplace, CA, 01234The social section is located in the middle of the footer. It can generate several social icon buttons with links.
-
title - The heading of the
socialsection. -
disabled - Set this to
trueif you'd like to disable thesocialsection. -
items - A YAML array of items to render as social icons in the
socialsection. The start of each item should be indented with a-dash.-
icon - The Font Awesome icon to use for this social icon. You can search Font Awesome's website for available icon names. You should only enter the name of the icon, without its
fa-prefix. Please note, only free icons are supported in this theme. -
brands - Set this to
trueif you're using an icon from the Font Awesome "Brands" collection (eg,twitter,facebook,github, etc.) Without it, the icon will fail to display. Likewise, enablingbrandson a non-brand icon will cause it to fail as well, since they are in separate icon sets. -
link - The destination URL for your social icon.
-
# Example Social Section
social:
title: Find Me On
items:
- icon: github
brands: true
link: https://github.com/octocat
- icon: twitter
brands: true
link: https://twitter.com/my_name_1234
- icon: envelope
link: mailto:me@example.comThe footer section is the "About" section located on the far right of the footer. It can hold a small blurb of text.
-
title - The heading of the
footersection. -
content - The
contentfor the "About" section of the footer. This block of text supports inline markdown elements (links, emphasis, etc). Text will be split into paragraphs based on line breaks. You can write multiple paragraphs easily using|(vertical pipe) to indicate a text block -
disabled - Set this to
trueif you'd like to disable thefootersection.
# Example Footer Section
footer:
title:
content: |
Writer, Blogger, Journalist.
Very Important Person.
Super Skillful.The copyright section is the copyright block located at the very bottom of the page.
-
content - The
contenttext for the copyright. This block of text supports inline markdown elements (links, emphasis, etc). Text will be split into paragraphs based on line breaks. You can write multiple paragraphs easily using|(vertical pipe) to indicate a text block.- You can also specify
autoto have your copyright text filled in automatically using yoursite_titleor indextitleand the current year (egCopyright © Your Website 2021).
- You can also specify
-
disabled - Set this to
trueif you'd like to disable thecopyrightsection.
# Example Single-Line Copyright
copyright:
content: Copyright © Myself 2021# Example Multi-Line Copyright
copyright:
content: |
Copyright © Myself 2021.
All Rights Reserved.
And some other legal print.Portfolio items and standalone pages share the same configuration options (since they're technically one in the same). Standalone pages (that are hidden from the gallery) don't require images, but you can include one if you'd like. It'll be displayed at the top just like in the modal view.
The content of your pages (below the YAML header) will be used for the main body of its modal view and/or page.
-
title - This is the standard Pico title header. This is used for the
h1heading at the top of your portfolio item or page. -
date - This is the standard Pico date header. You can specify a date if you'd like to organize your portfolio by date. Be sure to also set the
pages_order_byproperty in Pico'sconfig.ymlif you want this.dateis optional, and doesn't affect anything if you're not ordering your pages by date. -
hidden - The standard Pico
hiddenheader. Set this totrueto hide this page from your portfolio.- The page will still be viewable as a standalone page if navigated to, or linked to, manually. This can be a good way to have standalone pages that aren't a part of the gallery!
-
image - An optional image to use for your portfolio item or standalone page. This image is displayed at the top of the modal view or page, just under the
h1heading. If a dedicatedthumbnailis not specified for a portfolio item, this image will be used instead for convenience. -
thumbnail - The thumbnail image for your portfolio item. If not specified, your
imagewill be used instead. If neither are available, a random thumbnail image will be chosen from the theme's demo data as a temporary placeholder. This goes unused onhiddenpages.- The included thumbnail images are sized at
900x650pixels. You'll want to stick to a similar size or aspect ratio for your own.
- The included thumbnail images are sized at
-
image_alt - Accessibility
alttext for your image in the modal view or standalone page. Optional, depending on whether your image needs an accessibility explanation. -
thumbnail_alt - Accessibility
alttext for your thumbnail in the portfolio gallery. Optional, and defaults to using yourtitleif not provided. -
video - An optional video to use for your modal or standalone page. This video is displayed at the top of the modal view or page, just under the
h1heading.- This video offers controls and does not autoplay itself.
- If an
imageis also specified, it will be used as theposterfor the video. - The video's MIME type will attempt to be identified using its file extension, by checking whatever comes after the last
.in the file path provided, against a list of common types. If this fails, the video tag'stypeattribute will be omitted to give the browser a chance to identify the video itself. If you'd like to provide a MIME type, you can do so using array YAML notation. Just wrap the file path in brackets[]and add the MIME type, separated by a comma. Any provided MIME type will override an autodetected one. videoalso supports multiple sources (with or without MIME types as well.) You can specify each source on a new line with an indented dash-. The browser will play the first supported source it can find.
# Example Video
video: "%assets_url%/video.mp4"# Example Video with MIME Type
video: ["%assets_url%/video.mp4", "video/mp4"]# Example Video with Multiple Sources
video:
- "%assets_url%/video.mp4"
- "%assets_url%/video.mov"- thumbnail_video - A thumbnail video to use for your portfolio item instead of a thumbnail image. A short looping video will work best for this.
- This video will autoplay, be muted, have no controls, and automatically loop when it's finished.
- Unlike with images,
thumbnail_videoandvideoare completely separate items and won't be substituted in for one another. - If a
thumbnailis also specified, it will be used as theposterfor the video. - You'll want to stick to a similar size or aspect ratio as the
thumbnailimages (900x650pixels) for the best looking result. - The video's MIME type will attempt to be identified using its file extension, by checking whatever comes after the last
.in the file path provided, against a list of common types. If this fails, the video tag'stypeattribute will be omitted to give the browser a chance to identify the video itself. If you'd like to provide a MIME type, you can do so using array YAML notation. Just wrap the file path in brackets[]and add the MIME type, separated by a comma. Any provided MIME type will override an autodetected one. thumbnail_videoalso supports multiple sources (with or without MIME types as well.) You can specify each source on a new line with an indented dash-. The browser will play the first supported source it can find.
# Example Thumbnail Video
thumbnail_video: "%assets_url%/thumbnail.mp4"# Example Thumbnail Video with Multiple Sources
thumbnail_video:
- "%assets_url%/thumbnail.mp4"
- "%assets_url%/thumbnail.mov"- actions - Add buttons to the bottom of your portfolio modal or standalone page. See the Actions section below for details.
---
# Example Gallery Item / Standalone Page
Title: Awesome Thing
image: assets/images/awesome.png
Date: 2021/03/20
actions:
- icon: external-link-alt
content: Learn More
link: http://example.com
---
Here's where I tell you about my super awesome thing!
The About section and standalone pages both support having button links at the bottom of their content. These "actions" are configured the same in either section, so I've condensed their descriptions here for simplicity.
Don't forget to apply the proper indentation no matter where you're using them!
-
actions - Add buttons to the bottom of your
aboutsection or standalone page by defining actions. These should be a YAML array, with the start of each item being indented with a-dash.-
icon - The Font Awesome icon to use for this button. Icons are displayed at the far left of the button. You can search Font Awesome's website for available icon names. You should only enter the name of the icon, without its
fa-prefix. Please note, only free icons are supported in this theme. -
content - The text to display on the button.
-
link - The destination URL for the button. For privacy reasons, if you set your button to
disabled(below), this URL will not be included in the HTML of the page. -
outline - Set this to
falseto have a solid color button instead of the default outline-only style. -
size - Change the size of the button. Choices are
small,medium,large, andxlarge(the default). -
color - The Bootstrap color name this button should use. Choices are
primary,secondary,success,danger,warning,info,light, anddark. These can be customized with CSS (see Color Customization). -
disabled - Set this to
trueif you'd like to disable this button. For privacy reasons, if you disable a button, the URL of itslinkproperty will not be included in the HTML of the page.
-
# Example Actions
actions:
- icon: download
content: Free Download!
link: "%assets_url%/download.zip"
- icon: external-link-alt
content: Learn More
link: http://example.com
disabled: trueThe original Freelancer contact form used Proprietary Start Bootstrap javascript to tie into their paid contact-form service. This unfortunately meant that all the styles and theming around the contact form and its validation was essentially broken unless using their solution.
I've included a very basic script to allow users to instead utilize browser-based validation, as well as have a ajax-based form submission that way you can submit the form without leaving the page.
However, and I can't stress this enough, I am NOT a Javascript Developer! I don't know even a shred about Javascript, and this whole effort was done by following and tweaking a few tutorials.
The code works, in that, it doesn't throw any errors, and it successfully submits the form for post-processing. But I have absolutely no idea if it is secure or follows best coding practices in any way!
I felt that leaving the contact form "incomplete" just wasn't a good solution, so I did my best to bridge that gap.
If you are a Javascript Developer, and you see a flaw with this, or you think you can measurably improve it, please submit an Issue or a Pull Request with your suggestions. Thank you.
Since Freelancer is based on Bootstrap, there are a lot of built-in color variables that can be used for customization. By default in the original Freelancer code, these are configured using SCSS.
Since this port is only based on the final compiled version of Freelancer, most of these variables were unused and hard-coded to their compiled values.
As a workaround, I've gone through and find-and-replace'd most of them with their variable names for ease of customization using an additional CSS Stylesheet. This does mean that there could be a few instances of the wrong variable being used for the same color. If you find any instances where this is the case, please make a new Issue to let me know.
I've also added a few "Extra" CSS Variables for colors that were originally SCSS mixes of other colors. There's no way to accomplish mixing colors with regular CSS, so these extra variables can be used instead to manually replace said colors.
These... are a mess, and I apologize for that. I hate them too, but I haven't come up with a better solution that doesn't involve simply crushing all the color variations down to their primary color and pretending it's not different.
If you have any ideas for how to improve this while keeping faithful to the original source theme, feel free to open a new Issue with your suggestion.
The following color variables are available for use in your own CSS Stylesheet. There are also plenty more Bootstrap color variables available, however they go mostly unused out-of-the-box.
:root {
/* Default Bootstrap Colors */
--bs-primary: #1abc9c; /* Primary Color */
--bs-primary-rgb: 26, 188, 156; /* Primary Color as RGB */
--bs-secondary: #2c3e50; /* Secondary Color */
--bs-secondary-rgb: 44, 62, 80; /* Secondary Color as RGB */
/* Pico Additions */
--bs-copyright: #1a252f; /* Darker Secondary Color used for Copyright background (Approx. RGB values times 0.6) */
--bs-primary-dark: #16a085; /* Primary RGB * 0.85 */
--bs-primary-darker: #15967d; /* Primary RGB * 0.80 */
--bs-primary-darkest: #148d75; /* Primary RGB * 0.75 */
--bs-primary-lighter-rgb: 60, 198, 171; /* Lighter, faded Primary Color used for the button Focus Highlight. */
--bs-primary-lightest: #8ddece; /* Even lighter, faded Primary Color. Used as a Focus Highlight on the Contact Form */
--bs-secondary-dark: #253544; /* Secondary RGB * 0.85 */
--bs-secondary-darker: #233240; /* Secondary RGB * 0.8 */
--bs-secondary-darkest: #212f3c; /* Secondary RGB * 0.75 */
--bs-secondary-lighter-rgb: 76, 91, 106; /* Lighter, faded Secondary Color used for the button Focus Highlight. */
}Optionally, you may be able to generate new CSS using the original theme's SCSS, but this is out of the scope of this readme. There's also a small block of Pico additions at the end of styles.css you'll likely want to preserve if you do this.
This 2.0 release is a complete rewrite from my older 1.0 port. The original 1.0 version was based on an out-of-date Jekyll port of Freelancer and not the upstream code.
The new 2.0 version should essentially be treated as a new theme.
While it shouldn't be too hard to "migrate" from the old version, just be mindful of the different header configuration values, since it's not intended to be a drop-in replacement.
If you have any issues with this port, or would like to request a feature, please create a new Issue on GitHub.