- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是 WordPress 的新手,我在我的项目中使用 WooCommerce 插件,我需要修改 WooCommerce 的一些模板文件和一些核心文件。
我已经创建了子主题并在我的子主题中创建了 woocommerce
文件夹,因此我可以在那里创建/修改模板文件,在 WooCommerce 插件期间自定义不会丢失更新。但正如我在一些文章中所读到的,不建议修改 WooCommerce 的核心文件。
我在 WooCommerce 插件中自定义了这个核心文件 includes\admin\meta-boxes\views\html-order-item
我有点担心 future 的插件更新(我的自定义更改是否会保留或不保留)。我试图将此文件复制到 woocommerce
文件夹内的子主题中,但它似乎并没有覆盖原始文件,因此没有任何效果。
在这个“html-order-item.php”文件中,我刚刚添加了一小段代码,其中有一个下载按钮来下载产品的原始图像。
我如何使用“干净的推荐方式(使用 Hook /过滤器或模板)”实现此目的?
请提出任何实现它的方法。
这是我的代码片段(我的自定义以 /* Amol 添加的自定义代码 */
开头):
<?php
/**
* Shows an order item
*
* @var object $item The item being displayed
* @var int $item_id The id of the item being displayed
*/
if (!defined('ABSPATH')) {
exit;
}
$product_link = $_product ? admin_url('post.php?post=' . absint($_product->id) . '&action=edit') : '';
$thumbnail = $_product ? apply_filters('woocommerce_admin_order_item_thumbnail', $_product->get_image('thumbnail', array('title' => ''), false), $item_id, $item) : '';
$tax_data = empty($legacy_order) && wc_tax_enabled() ? maybe_unserialize(isset($item['line_tax_data']) ? $item['line_tax_data'] : '' ) : false;
$item_total = ( isset($item['line_total']) ) ? esc_attr(wc_format_localized_price($item['line_total'])) : '';
$item_subtotal = ( isset($item['line_subtotal']) ) ? esc_attr(wc_format_localized_price($item['line_subtotal'])) : '';
<tr class="item <?php echo apply_filters('woocommerce_admin_html_order_item_class', (!empty($class) ? $class : ''), $item, $order); ?>" data-order_item_id="<?php echo $item_id; ?>">
<td class="thumb">
<?php
echo '<div class="wc-order-item-thumbnail">' . wp_kses_post($thumbnail) . '</div>';
?>
</td>
<td class="name" data-sort-value="<?php echo esc_attr($item['name']); ?>">
<?php
echo $product_link ? '<a href="' . esc_url($product_link) . '" class="wc-order-item-name">' . esc_html($item['name']) . '</a>' : '<div class="class="wc-order-item-name"">' . esc_html($item['name']) . '</div>';
if ($_product && $_product->get_sku()) {
echo '<div class="wc-order-item-sku"><strong>' . __('SKU:', 'woocommerce') . '</strong> ' . esc_html($_product->get_sku()) . '</div>';
}
if (!empty($item['variation_id'])) {
echo '<div class="wc-order-item-variation"><strong>' . __('Variation ID:', 'woocommerce') . '</strong> ';
if (!empty($item['variation_id']) && 'product_variation' === get_post_type($item['variation_id'])) {
echo esc_html($item['variation_id']);
} elseif (!empty($item['variation_id'])) {
echo esc_html($item['variation_id']) . ' (' . __('No longer exists', 'woocommerce') . ')';
}
echo '</div>';
}
?>
<input type="hidden" class="order_item_id" name="order_item_id[]" value="<?php echo esc_attr($item_id); ?>" />
<input type="hidden" name="order_item_tax_class[<?php echo absint($item_id); ?>]" value="<?php echo isset($item['tax_class']) ? esc_attr($item['tax_class']) : ''; ?>" />
<?php do_action('woocommerce_before_order_itemmeta', $item_id, $item, $_product) ?>
<?php include( 'html-order-item-meta.php' ); ?>
<?php do_action('woocommerce_after_order_itemmeta', $item_id, $item, $_product) ?>
<?php echo $_product->get_categories(', ', '<div class="wc-order-item-variation"><strong>' . _n('Category:', 'woocommerce:', sizeof(get_the_terms($item['product_id'], 'product_cat')), 'woocommerce') . ' ', '</strong></div>'); ?>
<div style="float: left;" >
<?php
$image_link = wp_get_attachment_image_src(get_post_thumbnail_id($_product->id), 'large');
echo isset($image_link[0]) ? '<img src = "' . $image_link[0] . '" width = "200">' : '';
?>
</div>
<?php
/* Custom code added by Amol */
$post = $_product->post;
$attachment_count = count($_product->get_gallery_attachment_ids());
$gallery = $attachment_count > 0 ? '[product-gallery]' : '';
$props = wc_get_product_attachment_props(get_post_thumbnail_id(), $post);
$image = get_the_post_thumbnail($post->ID, apply_filters('single_product_large_thumbnail_size', 'shop_single'), array(
'title' => $props['title'],
'alt' => $props['alt'],
));
echo apply_filters(
'woocommerce_single_product_image_html', sprintf(
'<a style="text-decoration: none;clear:both;float: left;margin-top: 5px;" href="%s" download = "Order#' . $order->id . '-' . $item['variation_id'] . '"><input type = "button" value="Download image"/></a>', esc_url($props['url'])
), $post->ID
);
//End of custom code by Amol
?>
</td>
<?php do_action('woocommerce_admin_order_item_values', $_product, $item, absint($item_id)); ?>
<td class="item_cost" width="1%" data-sort-value="<?php echo esc_attr($order->get_item_subtotal($item, false, true)); ?>">
<div class="view">
<?php
if (isset($item['line_total'])) {
echo wc_price($order->get_item_total($item, false, true), array('currency' => $order->get_order_currency()));
if (isset($item['line_subtotal']) && $item['line_subtotal'] != $item['line_total']) {
echo '<span class="wc-order-item-discount">-' . wc_price(wc_format_decimal($order->get_item_subtotal($item, false, false) - $order->get_item_total($item, false, false), ''), array('currency' => $order->get_order_currency())) . '</span>';
}
}
?>
</div>
</td>
<td class="quantity" width="1%">
<div class="view">
<?php
echo '<small class="times">×</small> ' . ( isset($item['qty']) ? esc_html($item['qty']) : '1' );
if ($refunded_qty = $order->get_qty_refunded_for_item($item_id)) {
echo '<small class="refunded">' . ( $refunded_qty * -1 ) . '</small>';
}
?>
</div>
<div class="edit" style="display: none;">
<?php $item_qty = esc_attr($item['qty']); ?>
<input type="number" step="<?php echo apply_filters('woocommerce_quantity_input_step', '1', $_product); ?>" min="0" autocomplete="off" name="order_item_qty[<?php echo absint($item_id); ?>]" placeholder="0" value="<?php echo $item_qty; ?>" data-qty="<?php echo $item_qty; ?>" size="4" class="quantity" />
</div>
<div class="refund" style="display: none;">
<input type="number" step="<?php echo apply_filters('woocommerce_quantity_input_step', '1', $_product); ?>" min="0" max="<?php echo $item['qty']; ?>" autocomplete="off" name="refund_order_item_qty[<?php echo absint($item_id); ?>]" placeholder="0" size="4" class="refund_order_item_qty" />
</div>
</td>
<td class="line_cost" width="1%" data-sort-value="<?php echo esc_attr(isset($item['line_total']) ? $item['line_total'] : '' ); ?>">
<div class="view">
<?php
if (isset($item['line_total'])) {
echo wc_price($item['line_total'], array('currency' => $order->get_order_currency()));
}
if (isset($item['line_subtotal']) && $item['line_subtotal'] !== $item['line_total']) {
echo '<span class="wc-order-item-discount">-' . wc_price(wc_format_decimal($item['line_subtotal'] - $item['line_total'], ''), array('currency' => $order->get_order_currency())) . '</span>';
}
if ($refunded = $order->get_total_refunded_for_item($item_id)) {
echo '<small class="refunded">' . wc_price($refunded, array('currency' => $order->get_order_currency())) . '</small>';
}
?>
</div>
<div class="edit" style="display: none;">
<div class="split-input">
<div class="input">
<label><?php esc_attr_e('Pre-discount:', 'woocommerce'); ?></label>
<input type="text" name="line_subtotal[<?php echo absint($item_id); ?>]" placeholder="<?php echo wc_format_localized_price(0); ?>" value="<?php echo $item_subtotal; ?>" class="line_subtotal wc_input_price" data-subtotal="<?php echo $item_subtotal; ?>" />
</div>
<div class="input">
<label><?php esc_attr_e('Total:', 'woocommerce'); ?></label>
<input type="text" name="line_total[<?php echo absint($item_id); ?>]" placeholder="<?php echo wc_format_localized_price(0); ?>" value="<?php echo $item_total; ?>" class="line_total wc_input_price" data-tip="<?php esc_attr_e('After pre-tax discounts.', 'woocommerce'); ?>" data-total="<?php echo $item_total; ?>" />
</div>
</div>
</div>
<div class="refund" style="display: none;">
<input type="text" name="refund_line_total[<?php echo absint($item_id); ?>]" placeholder="<?php echo wc_format_localized_price(0); ?>" class="refund_line_total wc_input_price" />
</div>
</td>
<?php
if (!empty($tax_data)) {
foreach ($order_taxes as $tax_item) {
$tax_item_id = $tax_item['rate_id'];
$tax_item_total = isset($tax_data['total'][$tax_item_id]) ? $tax_data['total'][$tax_item_id] : '';
$tax_item_subtotal = isset($tax_data['subtotal'][$tax_item_id]) ? $tax_data['subtotal'][$tax_item_id] : '';
?>
<td class="line_tax" width="1%">
<div class="view">
<?php
if ('' != $tax_item_total) {
echo wc_price(wc_round_tax_total($tax_item_total), array('currency' => $order->get_order_currency()));
} else {
echo '–';
}
if (isset($item['line_subtotal']) && $item['line_subtotal'] !== $item['line_total']) {
echo '<span class="wc-order-item-discount">-' . wc_price(wc_round_tax_total($tax_item_subtotal - $tax_item_total), array('currency' => $order->get_order_currency())) . '</span>';
}
if ($refunded = $order->get_tax_refunded_for_item($item_id, $tax_item_id)) {
echo '<small class="refunded">' . wc_price($refunded, array('currency' => $order->get_order_currency())) . '</small>';
}
?>
</div>
<div class="edit" style="display: none;">
<div class="split-input">
<div class="input">
<label><?php esc_attr_e('Pre-discount:', 'woocommerce'); ?></label>
<input type="text" name="line_subtotal_tax[<?php echo absint($item_id); ?>][<?php echo esc_attr($tax_item_id); ?>]" placeholder="<?php echo wc_format_localized_price(0); ?>" value="<?php echo esc_attr(wc_format_localized_price($tax_item_subtotal)); ?>" class="line_subtotal_tax wc_input_price" data-subtotal_tax="<?php echo esc_attr(wc_format_localized_price($tax_item_subtotal)); ?>" data-tax_id="<?php echo esc_attr($tax_item_id); ?>" />
</div>
<div class="input">
<label><?php esc_attr_e('Total:', 'woocommerce'); ?></label>
<input type="text" name="line_tax[<?php echo absint($item_id); ?>][<?php echo esc_attr($tax_item_id); ?>]" placeholder="<?php echo wc_format_localized_price(0); ?>" value="<?php echo esc_attr(wc_format_localized_price($tax_item_total)); ?>" class="line_tax wc_input_price" data-total_tax="<?php echo esc_attr(wc_format_localized_price($tax_item_total)); ?>" data-tax_id="<?php echo esc_attr($tax_item_id); ?>" />
</div>
</div>
</div>
<div class="refund" style="display: none;">
<input type="text" name="refund_line_tax[<?php echo absint($item_id); ?>][<?php echo esc_attr($tax_item_id); ?>]" placeholder="<?php echo wc_format_localized_price(0); ?>" class="refund_line_tax wc_input_price" data-tax_id="<?php echo esc_attr($tax_item_id); ?>" />
</div>
</td>
<?php
}
}
?>
<td class="wc-order-edit-line-item" width="1%">
<div class="wc-order-edit-line-item-actions">
<?php if ($order->is_editable()) : ?>
<a class="edit-order-item tips" href="#" data-tip="<?php esc_attr_e('Edit item', 'woocommerce'); ?>"></a><a class="delete-order-item tips" href="#" data-tip="<?php esc_attr_e('Delete item', 'woocommerce'); ?>"></a>
<?php endif; ?>
</div>
</td>
</tr>
提前致谢。
最佳答案
— Code updated 2 — (FOUND THE PROBLEMS, see comments in code) —
就在 html-order-item.php
核心文件中的自定义代码下,如果查看现有代码,您有 woocommerce_admin_order_item_values
Hook ,您可以将其用于您的代码,而不是覆盖 WooCommerce 核心文件。
但您还需要使用 woocommerce_admin_order_item_headers
,您将在下面的代码片段中看到……
Because YES you are going to loose your code customization in that PHP file when WooCommerce will be updated. That's why you will find everywhere in WordPress and WooCommerce core files a lot of different hooks to use, for customizations.
You can NOT copy this core files to your active child theme (or active theme) and doing this will not have any effect on it.
What you can do is copy the
templates
folder located in WooCommerce plugin, to your active child theme (or active theme) and rename itwoocommerce
. This way you can override the WooCommerce templates via your theme, as explained here in this documentation.
现在,首先您要替换回插件中的原始核心文件。
在您的子主题中,您通常有一个 function.php 文件,您将在其中添加以下代码(一个 Hook 函数):
add_action( 'woocommerce_admin_order_item_headers', 'download_image_admin_order_item_headers', 10, 0 );
function download_image_admin_order_item_headers(){
echo '<th class="item sortable" colspan="1" data-sort="string-ins">' . __( 'Downloads', 'woocommerce' ) .'</th>';
}
add_action( 'woocommerce_admin_order_item_values', 'download_image_order_item_values', 10, 3 );
function download_image_order_item_values( $_product, $item, $item_id ){
// Calling global $post to get the order ID
global $post;
// The Order ID
$order_id = $post->ID;
// the Product ID and variation ID (if different of zero for variations)
$product_id = $item['product_id'];
$variation_id = $item['variation_id'];
// If is not a variable product we replace the variation ID by the product ID
if (empty($variation_id)) $variation_id = $product_id;
// HERE ==> Getting an instance of product object, Avoiding an error:
// "Fatal error: Call to a member function get_gallery_attachment_ids()"
$product = new WC_Product($product_id);
// the Product post object
$post_product = $product->post;
$attachment_count = count($product->get_gallery_attachment_ids());
$gallery = $attachment_count > 0 ? '[product-gallery]' : '';
// CODE ERROR ===> This was returning empty before. You need to put
// the product ID in get_post_thumbnail_id() function to get something
$props = wc_get_product_attachment_props(get_post_thumbnail_id($product_id), $post_product);
// Testing $props output (array not empty) => comment/uncomment line below
// echo '<br>ITEM ID: ' . $item_id . '<br><pre>'; var_dump($props); echo '</pre><br>';
$image = get_the_post_thumbnail( $product->id, apply_filters('single_product_large_thumbnail_size', 'shop_single' ), array(
'title' => $props['title'],
'alt' => $props['alt'],
));
// Added a condition to avoid other line items than products (like shipping line)
if(!empty($product_id))
echo apply_filters(
'woocommerce_single_product_image_html', sprintf(
'<td class="name" colspan="1" ><a style="text-decoration: none;clear:both;float: left;margin-top: 5px;" href="%s" download = "Order#' . $order_id . '-' . $variation_id . '"><input type = "button" value="Download image"/></a></td>', esc_url($props['url'])
), $product->id
);
}
在项目 metabox 的管理订单编辑页面中,您将看到:
代码在您的事件子主题(事件主题或任何插件文件)的 function.php 文件中。
此代码已经过测试并且可以工作。
关于php - 在 WooCommerce 管理员快速订单预览中自定义内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41327287/
有没有办法为 Sinatra 获取 Django Admin 风格的网络管理员? 最佳答案 没用过,但通过谷歌很快就显示出来了:http://www.padrinorb.com/ 关于ruby - S
我正在开发一个 Wordpress 插件,它为不同的用户(管理员、编辑、作者、贡献者、订阅者)提供不同的权限。我已经能够使该插件在管理员面板或页面/末尾完美运行,但是当我以编辑身份登录时,我无法在他们
在为 Web 应用程序用例图建模时,为用户可以拥有的每个角色创建一个角色是否更好?或拥有一个角色、用户和一个具有特权的矩阵? guest < 用户 < 版主 < 管理员 1: guest 、用户、版主
Tibco Administrator GUI 在哪里获取应用程序和服务的状态? 在我的项目中,我需要读取 Tibco admin 中列出的所有服务的状态。我没有安装 Tibco hawk,我需要除
我们最近将我们的多域 magento 设置从共享主机迁移到专用服务器。 一切正常,但是当我尝试转到管理部分时,登录后出现任何 404 错误。 如果我从 url 中删除 index.php 似乎可以工作
我有一个多对多字段。我想限制管理员在其 M2M 小部件中显示的选择。 我有一个这样的模型: class A(models.Model): b_field = models.ManyToMany
我正在与其他几位同事一起使用 Azure。我们有一个共享的管理员帐户,我们所有人都可以访问该帐户(凭据)。几天前,当尝试使用管理员帐户登录 Azure 门户时,我们收到此消息:“需要更多信息。您的组织
如何使 Django 后端(和一些 View )在不同的域中可访问?是通过站点框架完成的吗? 最佳答案 创建 settings.py 的副本并使用该设置文件运行管理服务器。此外,创建 urls.py
我刚刚收到以某种方式在 Django 管理面板上显示数据的要求。实际上我有日志表,其中包含用户 ID 和它采取的操作。 class AuditTrail(models.Model): id = m
每当我访问我的网站地址/admin 时,就会出现此问题 Warning: mysqli::mysqli() [mysqli.mysqli]: (28000/1045): Access denied f
我一直在为 Django/Mysql 中的情况而苦苦挣扎。 在同时有主键和外键的表中有这一列。此列与中间表具有一对多关系。 这是与植物物种相关的状态列表。有些物种可以在多个州找到。 物种(表 1)列:
firebase 身份验证和 firebase 管理员有什么区别? 据我所知,firebase admin 具有身份验证功能,并且可以绕过安全性,这与 firebase 身份验证不同。 Firebas
我创建了一个 SonarQube 组 sonar-administrators-ldap 并映射到 LDAP sonar-administrators-ldap 。 sonar-administrat
我正在创建一个 Django 应用程序,其中所有模型都可以按照用户设置的顺序相互关联。我正在使用 GenericForeignKeys 设置所有这些。关键是我需要能够支持这些类型的关系/管理的多个集合
我无法使用我创建的任何 super 用户登录 Django 管理员。尝试创建新的 super 用户、更改密码等 - 这些进程中的任何一个都没有错误消息,但仍然无法登录。 我不确定它是否相关,但我也无法
我正在将我的 Django 项目前端从使用 jquery 转换为 angularjs与 Django Rest Framework以帮助使其成为单页应用程序。我已经用 angular 转换了大部分棘手
我正在尝试在我的管理页面中的某个 ModelView 上加载脚本: class CustomView(ModelView): # Neither approach works here:
我正在尝试在我的 rails 应用程序中设置设计。它运行良好,但现在我无法以任何用户身份登录,我收到“电子邮件或密码无效”。我想更深入地了解为什么它不进行身份验证。 是否有任何设计配置设置可以提供更多
我目前正在尝试在 drupal 中实现第二个(较低的)管理层。我通过同名模块为这些用户制作了一个额外的部分,以便他们可以拥有自己的主题等。我想在他们的页面部分中为这些二级或更低级别的管理员提供一个菜单
如何显示来自 API 服务器 React-admin 3.0 版的错误响应消息? 此变体不起作用 https://github.com/marmelab/react-admin/pull/871 en
我是一名优秀的程序员,十分优秀!