Git Product home page Git Product logo

starter-theme's Introduction

Timber 2.0

By Jared Novack (@jarednova), Lukas Gächter (@lgaechter), Nicolas Lemoine (@nlemoine), Erik van der Bas (website), Coby Tamayo (@cobytamayo), Upstatement and hundreds of other GitHub contributors:

PHP unit tests Coverage Status Scrutinizer Code Quality Latest Stable Version !Financial Contributors

⚠️ Important information about the Timber plugin ⚠️

With the release of Timber 2.0, Composer is the only supported install method. We are unable to continue releasing or supporting Timber as a plugin on WordPress.org. We advise everyone to switch to the Composer based install of Timber 1 as a first step as soon as possible. If you need PHP 8.2 support you will have to switch to Timber 2.0.

For more information and a list of additional resources, please visit this discussion.

What is Timber?

Because WordPress is awesome, but The Loop isn’t.

Timber helps you create fully-customized WordPress themes faster with more sustainable code. With Timber, you write your HTML using the Twig Template Engine separate from your PHP files.

This cleans up your theme code so, for example, your PHP file can focus on being the data/logic, while your Twig file can focus 100% on the HTML and display.

This is what Timber's .twig files look like (from this Hello World example)

{% extends "base.twig" %}

{% block content %}
  <h1 class="big-title">{{ foo }}</h1>
  <h2 class="post-title">{{ post.title }}</h2>

  <img src="{{ post.thumbnail.src }}" />

  <div class="body">
	{{ post.content }}
  </div>
{% endblock %}

Once Timber is installed, it gives any WordPress theme the ability to take advantage of the power of Twig and other Timber features.

Documentation


Installation

Follow the Installation Guide for how to install Timber using Composer.

What Now?

Setup the Timber Starter Theme. Once you have that installed in your WordPress setup, continue reading the Getting Started guide to Themeing.

Timber’s mission

Timber is a tool for developers who want to translate their HTML into high-quality WordPress themes through an intuitive, consistent and fully-accessible interface.

  • Intuitive: The API is written to be user-centric around a programmer's expectations.
  • Consistent: WordPress objects can be accessed through common polymorphic properties like slug, ID and name.
  • Accessible: No black boxes. Every effort is made so the developer has access to 100% of their HTML.

What does it look like?

Nothing. Timber is meant for you to build a theme on. Like underscores it comes style-free, because you're the style expert. Instead, Timber handles the logic you need to make a kick-ass looking site.

Who is it good for?

Timber is great for any WordPress developer who cares about writing good, maintainable code. It helps teams of designers and developers working together. At Upstatement we made Timber because while our entire team needs to participate in building WordPress sites, not everyone knows the ins-and-outs of the_loop(), codex and PHP (nor should they). With Timber your best WordPress engineer can focus on building the .php files with requests from WordPress and pass the data into .twig files. Once there, designers can easily mark-up data and build out a site's look-and-feel.

Should I use it?

Timber is MIT-licensed, so please use in personal or commercial work. Just don't re-sell it. Timber is used on tens of thousands of sites (and tons more we don't know about)

Timber 1

You can find the code for Timber 1 on the 1.x branch and read the Timber 1 documentation over here.

Links

Related & Official Projects

  • Twig The template language used by Timber.
  • Timber Starter Theme The "_s" of Timber to give you an easy start to the most basic theme you can build upon and customize.
  • wp-i18n-twig WP CLI Command to grab translatable strings from Twig files.
  • Timber Debug Bar Adds a debug bar panel that will show you which template is in-use and the data sent to your twig file.

Related Timber Projects

Projects that use Timber

  • Branch Bootstrap 3 + Timber = Branch starter theme!
  • Flynt a component based WordPress starter theme built on Timber and ACF Pro
  • Gantry5 a framework for theme development
  • Hozokit a component based starter theme
  • Juniper Starter pack that incorporates Timber and Bedrock
  • Seedling a starter theme using Bootstrap 4

Helpful Links

Reporting Security Issues

To disclose a security issue to our team, please submit a report via GitHub.

Support

Please post on StackOverflow under the "Timber" tag. Please use GitHub issues only for specific bugs, feature requests and other types of issues.

Contributing & Community

We love PRs! Read the Contributor Guidelines for more info. Say hello, share your tips/work, and spread the love on Twitter at @TimberWP.

Sponsor us

Since 2013 our goal at Timber is to create a library to that helps you create fully-customized WordPress themes faster with more sustainable code.

Through the collaborative efforts of both our dedicated team and countless contributors, we have invested numerous hours in maintaining and enhancing Timber. To keep doing that, we rely on the invaluable support of our sponsors.

Are you a WordPress pro or part of an agency who relies on Timber? Keep the magic alive by becoming a sponsor! By becoming a sponsor, you contribute to the continuous maintenance and enhancement of Timber, ultimately benefiting developers worldwide.

Gold Sponsors

Our backers

Documentation

The Official Documentation for Timber is generated from the contents of this repository:

starter-theme's People

Contributors

19h47 avatar alexwoollam avatar artdevgame avatar bbarnwell avatar daronspence avatar dzienisz avatar evankennedy avatar gchtr avatar gweecl avatar hatcherygeoff avatar jarednova avatar kaido24 avatar laras126 avatar lggorman avatar marciojc avatar matbush avatar mcegielka avatar mgiulio avatar motia avatar naderabbara avatar nlemoine avatar romainmenke avatar ryanhalliday avatar stefenphelps avatar stephenniemans avatar szepeviktor avatar teddybradford avatar thisislawatts avatar titouanmathis avatar tomlecki avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

starter-theme's Issues

Flexible page.php

Wouldn't it be better to replace line 27 in page.php

Timber::render( array('page.twig' ), $context );

with

Timber::render( array( 'page-'.$post->slug.'.twig', 'page.twig' ), $context );

So you got only one page.php but multiple page-home.twig page-contact.twig aso would be possible?
Additionally you are also free to duplicate page.php to e.g. page-about.php if you need to modify some other processing.

Or is there any downside?

Any plan to update to the latest version of Underscores

Hey guys @connorjburton @jarednova

First of all thanks a lot for creating Timber and this starter theme.

I just wanted to know, is there any plan to update this starter theme to the latest version of underscores? I am afraid the base html and the functions in this starter theme have got way too old 😭

Please let me know guys, Thanks in advance!

how to use acf_fc_layout correctly to call the desired template

I've read all the examples and searched the issues here but I can't get my head around how the ACF flexible content fields work via Timber, or how to use acf_fc_layout correctly.

So far I've got as far as spitting out all of the field content, but this includes the layout names which obviously I dont want:

{% if contenu.acf_fc_layout == "layout_homehero" %}
        {% include 'partial/flexible-layouts/homehero.twig' with {'homehero': layout} only %}
    {% elseif contenu.acf_fc_layout == 'layout_homebio' %}
        {% include 'partial/flexible-layouts/linkedreferences.twig' with { 'linkedreferences': layout.linkedreferences } only %}
    {% else %}
        {% include 'politiqueconfidentialite.twig'  %}
    {% endif %}

Ant the vars:
object(WP_Post)#5027 (28) {
["ID"]=>
int(585)
["post_author"]=>
string(1) "1"
["post_date"]=>
string(19) "2019-09-16 20:29:25"
["post_date_gmt"]=>
string(19) "2019-09-16 18:29:25"
["post_content"]=>
string(0) ""
["post_title"]=>
string(10) "front-page"
["post_excerpt"]=>
string(0) ""
["post_status"]=>
string(7) "publish"
["comment_status"]=>
string(6) "closed"
["ping_status"]=>
string(6) "closed"
["post_password"]=>
string(0) ""
["post_name"]=>
string(10) "front-page"
["to_ping"]=>
string(0) ""
["pinged"]=>
string(0) ""
["post_modified"]=>
string(19) "2019-09-17 18:07:39"
["post_modified_gmt"]=>
string(19) "2019-09-17 16:07:39"
["post_content_filtered"]=>
string(0) ""
["post_parent"]=>
int(0)
["guid"]=>
string(39) "http://www.starterwp.dev/?page_id=585"
["menu_order"]=>
int(0)
["post_type"]=>
string(4) "page"
["post_mime_type"]=>
string(0) ""
["comment_count"]=>
string(1) "0"
["filter"]=>
string(3) "raw"
["status"]=>
string(7) "publish"
["id"]=>
int(585)
["slug"]=>
string(10) "front-page"
["custom"]=>
array(46) {
["inline_featured_image"]=>
string(1) "0"
["_edit_last"]=>
string(1) "1"
["_wp_page_template"]=>
string(7) "default"
["_edit_lock"]=>
string(12) "1568736459:1"
["contenu"]=>
array(5) {
[0]=>
string(15) "layout_homehero"
[1]=>
string(14) "layout_gallery"
[2]=>
string(17) "layout_homeaction"
[3]=>
string(26) "layout_homecirconscription"
[4]=>
string(14) "layout_homebio"
}
["_contenu"]=>
string(19) "field_5d6ef6f86504d"
["contenu_0_bck_homehero"]=>
string(3) "613"
["_contenu_0_bck_homehero"]=>
string(19) "field_5d6ef7886504e"
["contenu_0_title_homehero"]=>
string(17) "TITLE"
["_contenu_0_title_homehero"]=>
string(19) "field_5d6ef88a6504f"
["contenu_0_catchphrase_homehero"]=>
string(58) "catchphrase"
["_contenu_0_catchphrase_homehero"]=>
string(19) "field_5d6ef8c165050"
["contenu_1_video_videogallery"]=>
string(32) "[elfsight_facebook_feed id="1"] "
["_contenu_1_video_videogallery"]=>
string(19) "field_5d710bd6d30e9"
["contenu_2_bck_pushhero"]=>
string(3) "622"
["_contenu_2_bck_pushhero"]=>
string(19) "field_5d6fdd85208c0"
["contenu_2_whitetitle_pushhero"]=>
string(10) "MON ACTION"
["_contenu_2_whitetitle_pushhero"]=>
string(19) "field_5d6fddb6208c1"
["contenu_2_bluetitle_pushhero"]=>
string(13) "CONTRE LE GASPILLAGE"
["_contenu_2_bluetitle_pushhero"]=>
string(19) "field_5d7017714913a"
["contenu_2_resume_pushhero"]=>
string(0) ""
["_contenu_2_resume_pushhero"]=>
string(19) "field_5d7017f14913b"
["contenu_2_btn1_pushhero"]=>
string(21) "Interventions vidéos"
["_contenu_2_btn1_pushhero"]=>
string(19) "field_5d70181f4913c"
["contenu_2_btn2_pushhero"]=>
string(24) "Mes propositions"
["_contenu_2_btn2_pushhero"]=>
string(19) "field_5d7018da4913d"
["contenu_2_btn3_pushhero"]=>
string(38) "Mes questions écrites"
["_contenu_2_btn3_pushhero"]=>
string(19) "field_5d7ce72b6ac87"
["contenu_3_bck_pushreverse"]=>
string(3) "626"
["_contenu_3_bck_pushreverse"]=>
string(19) "field_5d727794b1d18"
["contenu_3_title_pushreverse"]=>
string(18) "AU QUOTIDIEN"
["_contenu_3_title_pushreverse"]=>
string(19) "field_5d72779fb1d19"
["contenu_3_resume_pushreverse"]=>
string(333) "Le Lorem Ipsum est simplement du faux texte employé dans la composition et la mise en page avant impression. Le Lorem Ipsum est le faux texte standard de l'imprimerie depuis les années 1500, quand un imprimeur anonyme assembla ensemble des morceaux de texte pour réaliser un livre spécimen de polices de texte."
["_contenu_3_resume_pushreverse"]=>
string(19) "field_5d7277ccb1d1a"
["wisiwyg_politiqueconfidentialite"]=>
string(0) ""
["_wisiwyg_politiqueconfidentialite"]=>
string(19) "field_5d6f08f90a0b3"
["contenu_4_bck_push"]=>
string(3) "637"
["_contenu_4_bck_push"]=>
string(19) "field_5d701a214913e"
["contenu_4_title_push"]=>
string(6) "MA BIO"
["_contenu_4_title_push"]=>
string(19) "field_5d701acd4913f"
["contenu_4_resume_push"]=>
string(824) "On sait depuis longtemps que travailler avec du texte lisible et contenant du sens est source de distractions, et empêche de se concentrer sur la mise en page elle-même. L'avantage du Lorem Ipsum sur un texte générique comme 'Du texte. Du texte. Du texte.' est qu'il possède une distribution de lettres plus ou moins normale, et en tout cas comparable avec celle du français standard. De nombreuses suites logicielles de mise en page ou éditeurs de sites Web ont fait du Lorem Ipsum leur faux texte par défaut, et une recherche pour 'Lorem Ipsum' vous conduira vers de nombreux sites qui n'en sont encore qu'à leur phase de construction. Plusieurs versions sont apparues avec le temps, parfois par accident, souvent intentionnellement (histoire d'y rajouter de petits clins d'oeil, voire des phrases embarassantes)."
["_contenu_4_resume_push"]=>
string(19) "field_5d701ae549140"
["contenu_4_linkbtn_push"]=>
string(0) ""
["_contenu_4_linkbtn_push"]=>
string(19) "field_5d701b1249141"
["contenu_4_textbtn_push"]=>
string(0) ""
["_contenu_4_textbtn_push"]=>
string(19) "field_5d701b2b49142"
}

thank you in advance

Breakthrough in theme structure!

Move all "WordPress files" under a subdirectory.

function _core_theme_subdir($directory) {
    return $directory . '/template';
}

add_filter('template_directory', '_core_theme_subdir', 11, 1);
add_filter('stylesheet_directory', '_core_theme_subdir', 11, 1);
add_filter('template_directory_uri', '_core_theme_subdir', 11, 1);
add_filter('stylesheet_directory_uri', '_core_theme_subdir', 11, 1);

So config (and other) files can jump around in the root
and "WordPress files" in template/

functions.php $twig->addFilter error when installed Timber via Composer

I typically install the Timber plugin via the WP admin, so maybe I am missing something, however, when I install Timber plugin via Composer and use this starter theme, I am getting the following error.

Fatal error: Uncaught TypeError: Argument 1 passed to Twig_Environment::addFilter() must be an instance of Twig_Filter, string given, called in /app/wp-content/themes/timber-starter-theme/functions.php on line 58 and defined in /app/wp-content/themes/timber-starter-theme/vendor/twig/twig/lib/Twig/Environment.php on line 748 TypeError: Argument 1 passed to Twig_Environment::addFilter() must be an instance of Twig_Filter, string given, called in /app/wp-content/themes/timber-starter-theme/functions.php on line 58 in /app/wp-content/themes/timber-starter-theme/vendor/twig/twig/lib/Twig/Environment.php on line 748 Call Stack: 0.0010 362376 1. {main}() /app/index.php:0 0.0011 362664 2. require('/app/wp-blog-header.php') /app/index.php:17 0.0505 2933488 3. require_once('/app/wp-includes/template-loader.php') /app/wp-blog-header.php:19 0.0559 2976504 4. include('/app/wp-content/themes/timber-starter-theme/page.php') /app/wp-includes/template-loader.php:74 0.0653 3064960 5. Timber\Timber::render() /app/wp-content/themes/timber-starter-theme/page.php:27 0.0653 3064960 6. Timber\Timber::fetch() /app/wp-content/themes/timber-starter-theme/vendor/timber/timber/lib/Timber.php:389 0.0653 3064960 7. Timber\Timber::compile() /app/wp-content/themes/timber-starter-theme/vendor/timber/timber/lib/Timber.php:362 0.0709 3068768 8. Timber\Loader->render() /app/wp-content/themes/timber-starter-theme/vendor/timber/timber/lib/Timber.php:318 0.0709 3068768 9. Timber\Loader->get_twig() /app/wp-content/themes/timber-starter-theme/vendor/timber/timber/lib/Loader.php:66 0.0801 3154392 10. apply_filters() /app/wp-content/themes/timber-starter-theme/vendor/timber/timber/lib/Loader.php:173 0.0801 3154792 11. WP_Hook->apply_filters() /app/wp-includes/plugin.php:203 0.0801 3156296 12. Timber\Twig->add_timber_filters() /app/wp-includes/class-wp-hook.php:286 0.0833 3252016 13. apply_filters() /app/wp-content/themes/timber-starter-theme/vendor/timber/timber/lib/Twig.php:254 0.0833 3252416 14. WP_Hook->apply_filters() /app/wp-includes/plugin.php:203 0.0833 3253920 15. StarterSite->add_to_twig() /app/wp-includes/class-wp-hook.php:286 0.0838 3255472 16. Twig_Environment->addFilter() /app/wp-content/themes/timber-starter-theme/functions.php:58

This error is being thrown by the following line inside of starter theme's functions.php file on line # 58

       function add_to_twig( $twig ) {
		/* this is where you can add your own functions to twig */
		$twig->addExtension( new Twig_Extension_StringLoader() );
		$twig->addFilter('myfoo', new Twig_SimpleFilter('myfoo', array($this, 'myfoo')));
		return $twig;
	}

If I change the function to the following it goes away and works correctly:

      function add_to_twig( $twig ) {
		/* this is where you can add your own functions to twig */
		$twig->addExtension( new Twig_Extension_StringLoader() );
		$twig->addFilter( new Twig_SimpleFilter('myfoo', array($this, 'myfoo')) );
		return $twig;
	}

To be honest I am not sure if I am doing something wrong, or if this is a bug. If it is I will be more than happy to fix it and submit a PR.

comment_form() echoes the comment form...

The change done in commit: 04aa1da

Changes the deprecated function from Timber to the one native from wordpress. However, the behavior of the wordpress function is different: it echoes the comment form instead of just passing the comment form result to the variable. As a consequence, the comment form appears on the top of any page where it is called.

Issue with $post usage and third party plugins (Yoast, Learndash)

Description of the issue

In the starter theme and documentation, the following code is included:

$post = new TimberPost();
$context['post'] = $post;

This seems to override the global $post object (codex reference). I ran into issues with various issues with third party plugins that perform safety checks of $post to see if the class of it is equal to WP_Post, where it will fail because $post is now of class Timber\Post. Examples of this include:

(is_a($post, 'WP_Post'))

and

($post instanceof WP_Post)

This causes errors and erratic behavior, as reported here for example:

Example 1
Example 2
Example 3
Example 4

Proposed change

Please correct me if I'm mistaken, but since Timber templating tends to refer to the $context['post'] rather than the $post, we could probably rewrite the code in the doc examples and starter theme as:

$timber_post = new Timber\Post();
$context['post'] = $timber_post;

This would save issues for user of these plugins and any others that expect $post to be the global variable described in the WP Codex.

Dynamic

Show me please how you add a dynamic sidebar to base.twig file. Thanks.

New folder structure breaks `theme.link` and `theme.path`

With the new folder structure, theme.link and theme.path point to the /theme folder and not to the theme root folder, and that feels wrong.

Previously:

  • theme.link would return http://example.org/wp-content/themes/my-timber-theme
  • theme.path would return /wp-content/themes/my-timber-theme

And now:

  • theme.link returns http://example.org/wp-content/themes/my-timber-theme/theme
  • theme.path returns /wp-content/themes/my-timber-theme/theme

Add theme support for HTML5

Hi there,

First of all, thanks for Timber and this starter theme, they've made me want to learn how to make WordPress websites!

I think HTML5 support can be enabled by default, what do you think? Should I make a pull request?

custom taxonomies not registering

for some reason my custom post types are working but not my custom taxonomies

<?php

function external_resources()
{
    wp_enqueue_style('style', get_stylesheet_uri());
    wp_enqueue_style('main_styles', get_template_directory_uri() . '/styles/main.css', false, '', 'screen');

    if ($_ENV['ENVIRONMENT'] == 'dev') {
        wp_enqueue_script('system', home_url() . '/src/scripts/vendor/system.js', array(), '', true);
        wp_enqueue_script('config', home_url() . '/src/scripts/config.js', array(), '', true);
    } else {
        wp_enqueue_script('main', get_template_directory_uri() . '/js/main.js', array(), '', true);
    }
}
add_action('wp_enqueue_scripts', 'external_resources');

if (! class_exists('Timber')) {
    add_action('admin_notices', function () {
        echo '<div class="error"><p>Timber not activated. Make sure you activate the plugin in <a href="' . esc_url(admin_url('plugins.php#timber')) . '">' . esc_url(admin_url('plugins.php')) . '</a></p></div>';
    });

    add_filter('template_include', function ($template) {
        return get_stylesheet_directory() . 'no-timber.html';
    });

    return;
}

Timber::$dirname = array('templates', 'views');

class jswApp extends TimberSite
{
    function __construct()
    {
        add_theme_support('post-formats');
        add_theme_support('post-thumbnails');
        add_theme_support('menus');
        add_filter('timber_context', array( $this, 'add_to_context'));
        add_filter('get_twig', array( $this, 'add_to_twig'));
        add_action('init', array( $this, 'register_post_types'));
        add_action('init', array( $this, 'register_taxonomies'));
        parent::__construct();
    }

    function register_post_types()
    {
        function projects() {
            $labels = array(
                'name'                  => _x('Projects', 'Post Type General Name', 'projects'),
                'singular_name'         => _x('Project', 'Post Type Singular Name', 'projects'),
                'menu_name'             => __('Projects', 'projects'),
                'name_admin_bar'        => __('Projects', 'projects'),
                'archives'              => __('Project Archives', 'projects'),
                'attributes'            => __('Project Attributes', 'projects'),
                'parent_item_colon'     => __('Parent Project:', 'projects'),
                'all_items'             => __('All Projects', 'projects'),
                'add_new_item'          => __('Add New Project', 'projects'),
                'add_new'               => __('Add New Project', 'projects'),
                'new_item'              => __('New Project', 'projects'),
                'edit_item'             => __('Edit Project', 'projects'),
                'update_item'           => __('Update Project', 'projects'),
                'view_item'             => __('View Project', 'projects'),
                'view_items'            => __('View Projects', 'projects'),
                'search_items'          => __('Search Projects', 'projects'),
                'not_found'             => __('Not found', 'projects'),
                'not_found_in_trash'    => __('Not found in Trash', 'projects'),
                'featured_image'        => __('Featured Image', 'projects'),
                'set_featured_image'    => __('Set featured image', 'projects'),
                'remove_featured_image' => __('Remove featured image', 'projects'),
                'use_featured_image'    => __('Use as featured image', 'projects'),
                'insert_into_item'      => __('Insert into project', 'projects'),
                'uploaded_to_this_item' => __('Uploaded to this project', 'projects'),
                'items_list'            => __('Projects list', 'projects'),
                'items_list_navigation' => __('Projects list navigation', 'projects'),
                'filter_items_list'     => __('Filter projects list', 'projects'),
            );
            $args = array(
                'label'                 => __('Project', 'projects'),
                'description'           => __('STEAM Project', 'projects'),
                'labels'                => $labels,
                'supports'              => array('title', 'author', 'thumbnail', 'comments', 'revisions', ),
                'taxonomies'            => array('project_type', 'post_tag'),
                'hierarchical'          => false,
                'public'                => true,
                'show_ui'               => true,
                'show_in_menu'          => true,
                'menu_position'         => 5,
                'menu_icon'             => 'dashicons-hammer',
                'show_in_admin_bar'     => true,
                'show_in_nav_menus'     => true,
                'can_export'            => true,
                'has_archive'           => true,
                'exclude_from_search'   => false,
                'publicly_queryable'    => true,
                'capability_type'       => 'post',
                'show_in_rest'          => true,
            );
            register_post_type('project', $args);
        }
        projects();

        function makerspaces()
        {
            $labels = array(
                'name'                  => _x('Makerspaces', 'Post Type General Name', 'makerspaces'),
                'singular_name'         => _x('Makerspace', 'Post Type Singular Name', 'makerspaces'),
                'menu_name'             => __('Makerspaces', 'makerspaces'),
                'name_admin_bar'        => __('Makerspaces', 'makerspaces'),
                'archives'              => __('Makerspace Archives', 'makerspaces'),
                'attributes'            => __('Makerspace Attributes', 'makerspaces'),
                'parent_item_colon'     => __('Parent Makerspace:', 'makerspaces'),
                'all_items'             => __('All Makerspaces', 'makerspaces'),
                'add_new_item'          => __('Add New Makerspace', 'makerspaces'),
                'add_new'               => __('Add New Makerspace', 'makerspaces'),
                'new_item'              => __('New Makerspace', 'makerspaces'),
                'edit_item'             => __('Edit Makerspace', 'makerspaces'),
                'update_item'           => __('Update Makerspace', 'makerspaces'),
                'view_item'             => __('View Makerspace', 'makerspaces'),
                'view_items'            => __('View Makerspaces', 'makerspaces'),
                'search_items'          => __('Search Makerspaces', 'makerspaces'),
                'not_found'             => __('Not found', 'makerspaces'),
                'not_found_in_trash'    => __('Not found in Trash', 'makerspaces'),
                'featured_image'        => __('Featured Image', 'makerspaces'),
                'set_featured_image'    => __('Set featured image', 'makerspaces'),
                'remove_featured_image' => __('Remove featured image', 'makerspaces'),
                'use_featured_image'    => __('Use as featured image', 'makerspaces'),
                'insert_into_item'      => __('Insert into project', 'makerspaces'),
                'uploaded_to_this_item' => __('Uploaded to this makerspace', 'makerspaces'),
                'items_list'            => __('Makerspaces list', 'makerspaces'),
                'items_list_navigation' => __('Makerspaces list navigation', 'makerspaces'),
                'filter_items_list'     => __('Filter projects list', 'makerspaces'),
              );
              $args = array(
                'label'                 => __('Makerspace', 'makerspaces'),
                'description'           => __('Makerspace locations', 'makerspaces'),
                'labels'                => $labels,
                'supports'              => array('title', 'author', 'thumbnail', 'comments', 'revisions', ),
                'taxonomies'            => array('space_type', 'post_tag'),
                'hierarchical'          => false,
                'public'                => true,
                'show_ui'               => true,
                'show_in_menu'          => true,
                'menu_position'         => 5,
                'menu_icon'             => 'dashicons-location',
                'show_in_admin_bar'     => true,
                'show_in_nav_menus'     => true,
                'can_export'            => true,
                'has_archive'           => false,
                'exclude_from_search'   => false,
                'publicly_queryable'    => true,
                'capability_type'       => 'post',
                'show_in_rest'          => true,
              );
              register_post_type('makerspace', $args);
        }
        makerspaces();
    }

    function register_taxonomies()
    {
        function project_type()
        {
            $labels = array(
                'name'                       => _x('Project Types', 'Taxonomy General Name', 'project_type'),
                'singular_name'              => _x('Project Type', 'Taxonomy Singular Name', 'project_type'),
                'menu_name'                  => __('Project Types', 'project_type'),
                'all_items'                  => __('All Project Types', 'project_type'),
                'parent_item'                => __('Parent Project Type', 'project_type'),
                'parent_item_colon'          => __('Parent Project Type:', 'project_type'),
                'new_item_name'              => __('New Project Type', 'project_type'),
                'add_new_item'               => __('Add New Project Type', 'project_type'),
                'edit_item'                  => __('Edit Project Type', 'project_type'),
                'update_item'                => __('Update Project Type', 'project_type'),
                'view_item'                  => __('View Project Type', 'project_type'),
                'separate_items_with_commas' => __('Separate project types with commas', 'project_type'),
                'add_or_remove_items'        => __('Add or remove project types', 'project_type'),
                'choose_from_most_used'      => __('Choose from the most used', 'project_type'),
                'popular_items'              => __('Popular Items', 'project_type'),
                'search_items'               => __('Search Items', 'project_type'),
                'not_found'                  => __('Not Found', 'project_type'),
                'no_terms'                   => __('No items', 'project_type'),
                'items_list'                 => __('Project types list', 'project_type'),
                'items_list_navigation'      => __('Project types list navigation', 'project_type'),
            );
            $args = array(
                'labels'                     => $labels,
                'hierarchical'               => true,
                'public'                     => true,
                'show_ui'                    => true,
                'show_admin_column'          => true,
                'show_in_nav_menus'          => true,
                'show_tagcloud'              => false,
                'show_in_rest'               => true,
            );
            register_taxonomy('project_type', array('projects'), $args);
        }
        project_type();

        function space_type()
        {
            $labels = array(
                'name'                       => _x('Makerspace Types', 'Taxonomy General Name', 'space_type'),
                'singular_name'              => _x('Makerspace Type', 'Taxonomy Singular Name', 'space_type'),
                'menu_name'                  => __('Makerspace Types', 'space_type'),
                'all_items'                  => __('All Makerspace Types', 'space_type'),
                'parent_item'                => __('Parent Makerspace Type', 'space_type'),
                'parent_item_colon'          => __('Parent Makerspace Type:', 'space_type'),
                'new_item_name'              => __('New Makerspace Type', 'space_type'),
                'add_new_item'               => __('Add New Makerspace Type', 'space_type'),
                'edit_item'                  => __('Edit Makerspace Type', 'space_type'),
                'update_item'                => __('Update Makerspace Type', 'space_type'),
                'view_item'                  => __('View Makerspace Type', 'space_type'),
                'separate_items_with_commas' => __('Separate makerspace types with commas', 'space_type'),
                'add_or_remove_items'        => __('Add or remove makerspace types', 'space_type'),
                'choose_from_most_used'      => __('Choose from the most used', 'space_type'),
                'popular_items'              => __('Popular Items', 'space_type'),
                'search_items'               => __('Search Items', 'space_type'),
                'not_found'                  => __('Not Found', 'space_type'),
                'no_terms'                   => __('No items', 'space_type'),
                'items_list'                 => __('Makerspace types list', 'space_type'),
                'items_list_navigation'      => __('Makerspace types list navigation', 'space_type'),
            );
            $args = array(
                'labels'                     => $labels,
                'hierarchical'               => true,
                'public'                     => true,
                'show_ui'                    => true,
                'show_admin_column'          => true,
                'show_in_nav_menus'          => false,
                'show_tagcloud'              => false,
                'show_in_rest'               => true,
            );
            register_taxonomy('space_type', array('makerspaces'), $args);
        }
        space_type();
    }

    function add_to_context($context)
    {
        $context['foo'] = 'bar';
        $context['stuff'] = 'I am a value set in your functions.php file';
        $context['notes'] = 'These values are available everytime you call Timber::get_context();';
        $context['menu'] = new TimberMenu();
        $context['site'] = $this;
        return $context;
    }

    function myfoo($text)
    {
        $text .= ' bar!';
        return $text;
    }

    function add_to_twig($twig)
    {
        /* this is where you can add your own functions to twig */
        $twig->addExtension(new Twig_Extension_StringLoader());
        $twig->addFilter('myfoo', new Twig_SimpleFilter('myfoo', array($this, 'myfoo')));
        return $twig;
    }
}

new jswApp();

How to use TGM in the new functions.php format

Hi guys! I tried to research a little over the internet and did not found any consistent snippet or example of using TGM with timber. I believe and built-in example here or on the doc site would be great.

Thanks.

Wpackagist

Could you add this theme as a composer package to the wpackagist.org website?

Getting search results to work

I am experiencing a challenge getting search results in a theme created with Timber and using the Timber starter theme. I've documented my issue here. In doing some further troubleshooting, I created a new site with default WP content and loaded the Timber starter theme with no modifications. Regardless of the search term (including gibberish), the results page returns the 'Hello World!' post. Thanks!

gravity forms set to display none

my forms have conditional logic on them, which adds a display: none inline tag to the forms. the display: none tag remains on the form as wp-footer() is not loading (i think). How can i ensure wp-footer() function is loaded?

Ability to register twig namespaces?

Are there any plans allow twig namespace registers? This is built-in twig functionality, see: http://twig.sensiolabs.org/doc/2.x/api.html#loaders

These namespaces would allow, for example, pattern lab twig templates to be imported via a composer and used as is, with data being passed to them in Timber context.

So a twig include statement could use something like @atoms/headings/comp-heading.twig where @atoms is namespaced to a path like /views/patterns/atoms.

Apologies if this functionality exists and I've missed it, I've only read through the Timber docs once.

Single-customposttype.twig not working

I've been unable to get the single twig templates for a custom post type to work.

My developments.twig page correctly lists the posts in custom post type developments.

However, the single template defaults to single.twig, rather than single-development.twig.
In single-development.php I have:

$context = Timber::get_context();
$post = Timber::query_post();
$context['post'] = $post;
Timber::render('single-development.twig', $context);

Like some others suggested I resaved the permalinks but that didn't help.

In timber-functions.php I have:

public function register_post_types() {
		// Use categories and tags with attachments
		register_taxonomy_for_object_type( 'category', 'attachment' );
		register_taxonomy_for_object_type( 'post_tag', 'attachment' );

		register_post_type('developments', array(
			'labels' =>
				array(
					'name' => __( 'Developments' ),
					'singular_name' => __( 'development' )
				),
			'public' => true,
			'supports' => array( 'title', 'author', 'excerpt', 'custom-fields', 'revisions', 'page-attributes' ),
			'show_in_menu' => true,
			'taxonomies'  => array( 'category' ),
		));
	}

How is this structure supposed to work.. have I missed something?

Password protected posts / pages form action issue

Today I have found a bug in the starter-theme/templates/single-password.twig. I was getting 502 on WP Engine for password-protected pages and posts. After some research, it turned out that WP Engine is appending an extra query string to the action URL. Currently, we have:

<form action="{{ site.site_url }}/wp-login.php?action=postpass" method="post">

I was able to fix it by adding this piece of code in my single.php and page.php:

$context['form_action'] = esc_url( site_url( 'wp-login.php?action=postpass', 'login_post' ) );

Doing it this way allows hooks to alter the URL.

The form action field looks like this:

<form action="{{ form_action }}" method="post">

I got the idea from this issue: https://toolset.com/forums/topic/password-protected-post-bug-with-wpengine/

What do you think would be the best way to handle this? Is it better to provide a globally accessible variable like site.password_proteced_url or just modify the single.php and page.php as well as the templates/single-password.twig. Or maybe you have another suggestion? Let me know and I'll create a pull request.

need a little modification in the single.php file.

I add just one line to get this tutorial working in the single.php file.

This is the tutorial part:

{% extends "single.twig" %}

{% block headline %}
    <h1><img src="/wp-content/uploads/2014/05/jareds-face.jpg" alt="Jared’s Mug"/></h1>
{% endblock %}

That the line i need to add in the single.php file:

'single-' . $timber_post->slug . '.twig',

In this part of single.php file:

Timber::render(
	    array(
	        'single-' . $timber_post->ID . '.twig',
                'single-' . $timber_post->post_type . '.twig',
                'single-' . $timber_post->slug . '.twig',
                'single.twig'
        ),

I post this just to help any body with that tutorial, because this librairy "TIMBER" is awesome, thank good work.

Empty img element when there is no featured image

When a post has no featured image, there is an empty <img src=""> element in each single post. Singe.twig seems to assume there is always a featured image on a post, which is not always true. There should probably be a check on that.

How i can set how many posts per page are displayed in the archive section

Hello, i want to change the quantity of posts displayed in the archive section, but i dont know how.
If i use this snippet in the end of the archive.php file i get the correct number of posts in pagination but the posts are the same no matter the category i selected previously.

        if (!isset($paged) || !$paged){
		$paged = 1;
	}
	$args = array(
		'posts_per_page' => 8,
		'paged' => $paged
	);

$context['posts'] = new Timber\PostQuery($args);
$context['pagination'] = Timber::get_pagination();
Timber::render( $templates, $context );

if i run Timber\PostQuery() without arguments i get the correct posts of one category or search result, but the quantity in the pagination is not which i need.
$context['posts'] = new Timber\PostQuery();

get_header

I'm a little confused about wp_head, get_header and wp_footer:
I installed WooSidebars which needs a call to get_header();
So i placed get_header in page.php
Now the header.php gets executed and does an ob_start.

Do i have to include get_footer now also because there's the ob_end?
And if i do: What happens with the buffered content if i ain't got a view/page-plugin.twig template?

Would this be the right code and more important the right spot to include the get_header and get_footer calls?
Do i have to call those functions on all the different types of pages like single.php, archive.php, page.php aso.? Or is there a better, centralized way?

`
$context = Timber::get_context();
$post = new TimberPost();
$context['post'] = $post;

get_header();

if(!is_home() && !is_front_page()){
$context['has_sidebar'] = true;
$context['dynamic_sidebar'] = Timber::get_widgets('primary-widget-area-id');
}

Timber::render( array( 'page-'.$post->post_name.'.twig', 'page.twig' ), $context );

get_footer();
`

Call to undefined function ctype_alpha()

I read about Timber on Chris Coyier's blog and thought I would give it a shot. Is there anything additional we have to do to get this starter theme up and running? I've performed a clean install of Wordpress 4.3 and installed the Timber plugin, but when I activate this theme I get the following error:

Fatal error: Call to undefined function ctype_alpha() in /plugins/timber-library/vendor/twig/twig/lib/Twig/Lexer.php on line 378

Timber + AFC template resource bug

Hi, I'm new to Wordpress Timber + AFC theme development.

I read all the Getting started pages and set up my local env.

I stopped when I wanted to use Other resources -> This branch of the starter theme has some more example code with ACF and a slightly different set up.

This link is broken. It led me to branch that is something better than template but without AFC features. Maybe it's this branch: https://github.com/laras126/timber-starter-theme/tree/options-demo?

Please fix that or delete completely.

I assume that I can't recreate that easily but I already spend like 2 hours to dig though this without any effect in code 👎

Wordpress SEO plugin (Yoast and SEO Framework) create a conflict with Timber plugin

I'm using the Timber plugin with Underscores.me template (https://github.com/timber/starter-theme) to create a website (manual install).

I used the Yoast and SEO Framework plugin and both create an issue! When I add a description in the meta of a page, Timber doesn't work anymore. There is no error message. But content is empty.

I have:
WordPress 4.9.2
Timber Version 1.6.0
The SEO Framework Version 3.0.3

Do you have an idea why?

Performance issues /w ACF

Hey guys, we're inheriting a project which was built on timber and are running into quite the mess in terms of performance.

On every page load timber Term class is creating over 2000 queries... I need to understand how the term class is supposed to work and how I could fix this issue...

The site is using ACF and when the Term class gets loaded it riggers

$custom = $this->get_term_meta( $term->term_id );

which then applies filters

$customs = apply_filters( 'timber_term_get_meta', $customs, $tid, $this );

which finally loads this monstrosity

public function term_get_meta( $fields, $term_id, $term ) {
		$searcher = $term->taxonomy . '_' . $term->ID; // save to a specific category
		$fds = get_fields( $searcher );
		if ( is_array( $fds ) ) {
			foreach ( $fds as $key => $value ) {
				$key = preg_replace( '/_/', '', $key, 1 );
				$key = str_replace( $searcher, '', $key );
				$key = preg_replace( '/_/', '', $key, 1 );
				$field = get_field( $key, $searcher );
				$fields[ $key ] = $field;
			}
			$fields = array_merge( $fields, $fds );
		}
		return $fields;
	}

On 35 terms in the system this creates 2000+ queries that run on EVERY single page load... is this normal for this starter theme?

Shouldn't any form of caching be implemented here to prevent this from happening on every single page load?

Any thoughts on work around of this?

No loop on the blog page (with static homepage)

I have changed my blog settings > reading that the front page displays a static page. That works fine and i can also modify the template with a front-page.php.

But - the post page named "News" also just shows the page content of the page "News", but not the latest posts. The body tags shows

<body class="blog logged-in admin-bar customize-support" data-template="base.twig">

So obviously the theme already wants to display the "blog" here. For some reasons it doesn't work out. Also didn't find anything in the documentation about how to fix this issue.

But in general - thanks guy for this wonderful templating engine. WordPress starts to make sense again thanks to you.

Child Theme

We need to be able to create a child theme off the parent theme.

home.twig template doesn't exist

index.php contains the following:

$templates = array( 'index.twig' );
if ( is_home() ) {
    array_unshift( $templates, 'home.twig' );
}

So, if the current page is the home page, home.twig should be added in front of index.twig in the $template array, yet there is no home.twig template included.

archive.twig missing?

I don't see archive.twig even tho it is referenced in archive.php as a template, no big deal just something I came across.

Would it be possible to dual license it?

Hi,

Would it be possible to dual license the starter-theme under the MIT License and the GPLv2+ License?

Why i'm asking that :

I'm working on a theme and I would like to release it under a GPLv2+ so that any derivative works would need to release their modifications under the same license. In other words, it would give us the choice to use a Copyleft license.

I know it is possible to license only my code under the GPL and keep yours under the MIT but I don't really like mixing licenses. It's not really convivial for people you want to reuse the code after that.

I also want to use a GPL License to respect the choice made by the Wordpress team [1].

There is some legal grey area regarding what is considered a derivative work, but we feel strongly that plugins and themes are derivative work and thus inherit the GPL license.

Of course, you can disagree ;) but it would be nice to let the user of the starter-theme to make their own choice.

Thank you in advance for taking the time to read me.

PHP Fatal Error - TWIG

My site is giving off this error:

[Wed Sep 04 18:04:09.484966 2019] [php7:error] [pid 3862] [client 23.31.164.153:11890] PHP Fatal error: Uncaught RuntimeException: Passing a name as a first argument to the Twig\Environment::addFilter method is deprecated since version 1.21. Pass an instance of "Twig_SimpleFilter" instead when defining filter "place_button". in /nas/content/live/benchmarkunive/wp-content/plugins/event-tickets/common/src/functions/utils.php:504\nStack trace:\n#0 [internal function]: tribe_catch_and_throw(16384, 'Passing a name ...', '/nas/content/li...', 1123, Array)\n#1 /nas/content/live/benchmarkunive/wp-content/plugins/timber-library/vendor/twig/twig/src/Environment.php(1123): trigger_error('Passing a name ...', 16384)\n#2 /nas/content/live/benchmarkunive/wp-content/themes/backoffice/functions.php(82): Twig\Environment->addFilter('place_button', Object(Twig\TwigFilter))\n#3 [internal function]: StarterSite->add_to_twig(Object(Twig\Environment))\n#4 /nas/content/live/benchmarkunive/wp-includes/class-wp-hook.php(286): call_user_func_array(Array, Array)\n#5 /nas/content/live/benchmarkunive/wp-includes/plugin.php(208): WP_Hook->apply_fi in /nas/content/live/benchmarkunive/wp-content/plugins/event-tickets/common/src/functions/utils.php on line 504, referer: https://www.benchmarkbackoffice.com/wp-admin/

Update composer.json timber-library version

I'm trying to install Starter-theme using Composer. Seems to work but installation failed because of requirements not satisfied.

The Starter-theme requires Timber-library v 0.22.* while actual version is 1.1.

→ composer require upstatement/timber-starter-theme dev-master
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

Problem 1
- upstatement/timber-starter-theme dev-master requires wpackagist-plugin/timber-library 0.22.* -> satisfiable by wpackagist-plugin/timber-library[0.22.6, 0.22.5, 0.22.4, 0.22.3, 0.22.2, 0.22.1, 0.22.0] but these conflict with your requirements or minimum-stability.
- upstatement/timber-starter-theme dev-master requires wpackagist-plugin/timber-library 0.22.* -> satisfiable by wpackagist-plugin/timber-library[0.22.6, 0.22.5, 0.22.4, 0.22.3, 0.22.2, 0.22.1, 0.22.0] but these conflict with your requirements or minimum-stability.
- Installation request for upstatement/timber-starter-theme dev-master -> satisfiable by upstatement/timber-starter-theme[dev-master].

Installation failed, reverting ./composer.json to its original content.

Can you update it ?

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.