mindkomm / timber-integration-woocommerce

WooCommerce integration for Timber
MIT License
109 stars 20 forks source link

PHP template over twig #9

Closed tlygnersjo closed 4 years ago

tlygnersjo commented 6 years ago

When developing an classic theme (not with Timber integrated), WooCommerce templates can be overrided by placing php templates in i.e. woocommerce/cart/cart.php.

What i want is:

  1. Your default way is a great starting point (doesnt need woocommerce.php or woocommerce folder).
  2. If "woocommerce" folder exists each file in that should override your default way (as described above). In some situations i want to append certain variables to context and work with them (i.e. cart.twig).

Is that possible in your integration?

gchtr commented 6 years ago

Hey @tlygnersjo

When you have a file woocommerce.php, you can’t override specific templates, e.g. woocommerce/cart/cart.php. This is a limitiation in WooCommerce.

You can already set a file woocommerce/cart/cart.php, that you can set up like a normal Timber template, where you get the context and then render your custom template trough Timber::render().

If you want to append certain variables to the context, you can use an existing filter timber/woocommerce/template/context. For the cart, it might look something like this:

add_filter( 'timber/woocommerce/template/context', function( $context, $template_name ) {
    // Bail out if it’s not the targeted template.
    if ( 'woocommerce/cart/cart.php' !== $template_name ) {
        return $context;
    }

    $context['my_additional_cart_variable'] = 'This will only be available in views/woocommerce/cart/cart.twig';

    return $context;
}, 10, 2 ); 

Does this help? Otherwise, can you make a specific example so I can see what you want to achieve?

tlygnersjo commented 6 years ago

Hi @gchtr

Thanks for your response!

So it should be possible to handle templates through woocommerce/cart/cart.php and views/woocommerce/cart.twig as long as i don't have a woocommerce.php in theme root?

woocommerce/cart/cart.php

<?php
  $context = Timber::get_context();
  $post = new TimberPost();
  $context['post'] = $post;

  foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) {
    $_product   = apply_filters('woocommerce_cart_item_product',    $cart_item['data'],       $cart_item, $cart_item_key);
    $product_id = apply_filters('woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key);
    $quantity = false;
    if ($_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters('woocommerce_cart_item_visible', true, $cart_item, $cart_item_key)) {
        if (!$_product->is_sold_individually()) {
            $quantity = [
                'name'  => "cart[{$cart_item_key}][qty]",
                'value' => $cart_item['quantity'],
                'min'   => '0',
                'max'   => $_product->backorders_allowed() ? '' : $_product->get_stock_quantity()
            ];
        }
    }
    $cart_products[] = [
        'title'     => apply_filters('woocommerce_cart_item_name', $_product->get_title(), $cart_item, $cart_item_key),
        'remove_url' => WC()->cart->get_remove_url($cart_item_key),
        'price'     => apply_filters('woocommerce_cart_item_price', WC()->cart->get_product_price($_product), $cart_item, $cart_item_key),
        'quantity'  => $quantity,
        'weight' => $_product->get_weight(),
        'link' => get_permalink( $product_id ),
        'thumbnail' => wp_get_attachment_url(get_post_thumbnail_id($product_id)),
        'subtotal'  => apply_filters('woocommerce_cart_item_subtotal', WC()->cart->get_product_subtotal($_product, $cart_item['quantity']), $cart_item, $cart_item_key)
    ];
  }

  $context['cart_empty'] = WC()->cart->is_empty();
  $context['cart_subtotal'] = WC()->cart->subtotal;
  $context['cart_total'] = WC()->cart->total;
  $context['action'] = WC()->cart->get_cart_url();
  $context['shop_url'] = wc_get_page_permalink('shop');
  $context['checkout_url'] = wc_get_checkout_url();
  $context['cart_products'] = $cart_products;
  $context['wc_coupons_enabled'] = wc_coupons_enabled();

  // WooCommerce Notices
  $context['wc_notices'] = wc_get_notices();
  wc_clear_notices();

  Timber::render( 'woocommerce/cart/cart.twig', $context );

views/woocommerce/cart.twig

{% block content %}
    <div class="wrapper wrapper--cart">
        {% if wc_notices %}
            {% for wc_notice in wc_notices.success %}
                <div class="notice notice--success">{{ wc_notice }}</div>
            {% endfor %}
            {% for wc_notice in wc_notices.error %}
                <div class="notice notice--error">{{ wc_notice }}</div>
            {% endfor %}
        {% endif %}

        <div class="cart-border-wrap">
            <div class="cart-wrap">
                <form action="{{ cart_url }}" method="post" class="cart-list-items woocommerce-cart-form">
                    <div class="cart-list">
                        <div class="cart-list-item cart-list-item--header">
                            <div class="cart-list-item-element cart-list-item__image"></div>
                            <div class="cart-list-item-element cart-list-item__name">Product</div>
                            <div class="cart-list-item-element cart-list-item__price">Price</div>
                            <div class="cart-list-item-element cart-list-item__count">Quantity</div>
                            <div class="cart-list-item-element cart-list-item__subtotal">Total</div>
                            <div class="cart-list-item-element cart-list-item__remove"></div>
                        </div>
                        {% for product in cart_products %}
                        <div class="cart-list-item cart-list-item--body cart_item">
                            <div class="cart-list-item-element cart-list-item__image">
                                <img src="{{ product.thumbnail|resize(150, 150) }}" alt="">
                            </div>
                            <div class="cart-list-item-element cart-list-item__name">
                                <a href="{{ product.link }}">{{ product.title }}</a>
                                {% if product.weight %}
                                    <p><strong>Вес: </strong><span>{{ product.weight }} {{ weight_unit }}</span></p>
                                {% endif %}
                            </div>
                            <div class="cart-list-item-element cart-list-item__price">{{ product.price }}</div>
                            <div class="cart-list-item-element cart-list-item__count">
                                {% if product.quantity %}
                                <div class="cart__product__quantity counter">
                                    <button type="button" class="counter__subtract">-</button>
                                    <input name="{{ product.quantity.name }}" min="{{ product.quantity.min }}" max="{{ product.quantity.max }}" type="number" value="{{ product.quantity.value }}" class="counter__number qty">
                                    <button type="button" class="counter__add">+</button>
                                </div>
                                {% endif %}
                            </div>
                            <div class="cart-list-item-element cart-list-item__subtotal">{{ product.subtotal }}</div>
                            <div class="cart-list-item-element cart-list-item__remove"><a href="{{ product.remove_url }}">Remove</a></div>
                        </div>
                        {% endfor %}
                    </div>
                    <div class="presents-info">
                        {% if wc_coupons_enabled %}
                            <div class="coupon">
                                <input type="text" name="coupon_code" class="input-text" id="coupon_code" value="" placeholder="Coupon code" />
                                <button type="submit" class="button" name="apply_coupon" value="Apply">Apply</button>
                                {% do action('woocommerce_cart_coupon') %}
                            </div>
                            <button type="submit" class="button update-cart-button" name="update_cart" value="Update cart">Update cart</button>
                        {% endif %}
                    </div>

                    <div class="cart-total">
                        <div class="cart-total-item">
                            <div class="cart-total-item__name">Amount</div>
                            <div class="cart-total-item__value">{{ cart_subtotal }} р</div>
                        </div>
                        <a class="button button--red" href="{{ checkout_url }}">Cart</a>
                        {% do action('wp_nonce_field', 'woocommerce-cart') %}
                    </div>
                </form>
            </div>
        </div>
    </div>
{% endblock %}
tlygnersjo commented 6 years ago

Do you have any answer on my previous question? @gchtr

gchtr commented 6 years ago

So it should be possible to handle templates through woocommerce/cart/cart.php and views/woocommerce/cart.twig as long as i don't have a woocommerce.php in theme root?

Yes, that should be possible. But it also means that you then have to define all other template files yourself inside a woocommerce/ folder in your theme.

The alternative I see would be to handle what you now have in woocommerce/cart/cart.php inside the timber/woocommerce/template/context filter, like mentioned above.