我正在尝试将某种小部件或菜单添加到我所有 Wordpress 网站页面的顶部

Posted

技术标签:

【中文标题】我正在尝试将某种小部件或菜单添加到我所有 Wordpress 网站页面的顶部【英文标题】:I am trying to add some sort of widget or menu to the top of all of my Wordpress sites pages 【发布时间】:2019-03-10 02:57:04 【问题描述】:

我目前在一个 Wordpress 网站上工作,其中一项任务是创建我能够做到的自定义帖子位置帖子类型。然后,我使用我在functions.php 中编写的过滤器来包含我编写的单独的locations.php 文件,以显示在我的位置帖子类型页面上。请参阅下面的过滤器:

add_filter('the_content', 'prepend_location_data' );
function prepend_location_data( $content )
    if( is_singular('location'))

        $html=include("locations.php");
    return $content . $html;
    
    return $content;

然后,我能够使用 ACF 插件将自定义字段添加到我的位置帖子中,并使用 ACF 函数在我的 locations.php 页面上显示它们。我的下一个任务是在所有页面的顶部添加某种小部件或菜单,以根据用户 IP 显示特定的电话号码。我能够在我创建的locations.php文件中编写一个php函数来获取用户的IP,使用IP来获取IP的城市,然后如果该城市等于城市自定义字段之一中包含的城市我创建它将返回该城市的电话号码。请参阅以下功能:

<?php
function get_the_user_ip() 
    if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) 
    //Checks if IP is from shared internet
    $ip = $_SERVER['HTTP_CLIENT_IP'];
    
    elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) 
    //Checks if IP is passed from proxy
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
     
    else 
    //Most trustworthy source of IP address
    $ip = $_SERVER['REMOTE_ADDR'];
    
    //Uses ipinfo.io to find location information based on IP address
    $details = json_decode(file_get_contents("https://ipinfo.io/$ip"));

    //Returns city value from the details array
    $city=$details->city;

    return apply_filters('wpb_get_ip', $city );
    


function display_phone()
    $cityField=get_field('city');
    $phoneField=get_field('phone_number');
    //Assigns the return value of get_the_user_ip to a variable
    $userCity=get_the_user_ip();
    if($userCity==$cityField)
        return ($phoneField);
    


add_shortcode('show_phone', 'display_phone');
?>

问题是短代码仅适用于位置页面。我意识到我必须以某种方式将 display_phone 函数的返回值传递回 functions.php 文件,或者可能只是在 functions.php 中执行所有这些逻辑。有没有人对尝试的事情或去哪里有任何建议?我可以在我的functions.php 中使用ACF 函数吗?我应该使用 javascript 函数来执行此操作吗?任何建议表示赞赏。

我也尝试过对 display_phone 函数进行以下修改,但无济于事。

function display_phone()
    global $post;
    $current_id = $post->ID;
    $cityField=get_field('city', $post->ID);
    $phoneField=get_field('phone_number');
    //Assigns the return value of get_the_user_ip to a variable
    $userCity=get_the_user_ip();
    if($userCity==$cityField)
        return ($phoneField);


对display_phone函数的下一个修改:

function display_phone()
    global $post;
    $current_id = $post->ID;
    $cityField=get_field('city', $current_id);
    $phoneField=get_field('phone_number');
    //Assigns the return value of get_the_user_ip to a variable
    $userCity=get_the_user_ip();
    if($userCity==$cityField)
        return ($phoneField);


更新: 好的,所以在考虑了更多之后,我想我需要编写一个函数,该函数将遍历位置帖子类型的所有城市和电话号码字段,以查看它们是否与 get_the_user_ip 函数返回的城市匹配。显然,必须修改显示电话功能才能做到这一点,我想我必须将这两个功能都从 locations.php 中取出,并且可能在 header.php 文件中执行这个逻辑。有没有人有做类似事情的经验或关于如何做到这一点的任何建议?我不确定如何遍历我的位置帖子类型的字段数据,除非我实际上是在帖子中执行逻辑。我意识到这可以通过使用硬编码的城市和电话号码数组来解决,但我试图避免这种情况并改用 ACF 插件。

更新: 所以我从locations.php 页面中取出逻辑并将其移到functions.php 文件的末尾。现在它正在加载的每一页的顶部打印正确的电话号码,但只有一秒钟。因此,该过程的下一步似乎是将这个数字分配给一个变量并以某种方式传递给一个函数,这样我就可以分配给一个短代码并在我的整个站点中使用。

<?php 

function get_the_user_ip() 
    if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) 
    //Checks if IP is from shared internet
    $ip = $_SERVER['HTTP_CLIENT_IP'];
    
    elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) 
    //Checks if IP is passed from proxy
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
     
    else 
    //Most trustworthy source of IP address
    $ip = $_SERVER['REMOTE_ADDR'];
    
    //Uses ipinfo.io to find location information based on IP address
    $details = json_decode(file_get_contents("https://ipinfo.io/$ip"));

    //Returns city value from the details array
    $city=$details->city;

    return apply_filters('wpb_get_ip', $city );
    


$posts = get_posts(array(
    'posts_per_page'    => -1,
    'post_type'         => 'location'
));
$userCity=get_the_user_ip();
if( $posts ): 



     foreach( $posts as $post ): 

        $cityField=get_field('city');
        //echo "$cityField";        
        $phoneField=get_field('phone_number');
        //echo "$phoneField";
         if($userCity==$cityField)
             echo ($phoneField);
         

     endforeach;


    wp_reset_postdata(); 

 endif; 


?>

【问题讨论】:

我不确定我是否理解您在此处尝试执行的操作,但您可以在主题的 header.php 文件中的某处添加&lt;?php if ( is_single() ) do_shortcode('show_phone'); ?&gt;(有关更多详细信息,请参阅do_shortcode())。 @cabrerahector 基本上我试图根据用户的位置在顶部菜单上向用户显示不同的电话号码,因为公司有多个分支机构。谢谢你的建议。我现在正在浏览 header.php 文件。我会告诉你它是否有效。 您将 IP 地址与 get_field('city'); 的值进行比较,但这些字段仅添加到位置帖子中,因此当您在在其他页面上。 @johnnyd23 有没有办法运行我在不同区域编写的函数,或者以某种方式将它们拉入 functions.php 文件中,以便我可以在站点范围内显示返回值? 您会在站点范围内将 IP 地址与什么进行比较? 【参考方案1】:

我认为您还需要提供页面 ID,否则 WordPress 将如何知道要使用哪些位置的电话号码?所以

get_field('city');

会变成

get_field('city', $post->ID);

您可以在 display_phone 函数中使用以下内容获取当前页面 ID:

global $post;
$current_id = $post->ID;

更新:

看起来你很高兴。就像你说的,你需要做的就是创建一个短代码来调用它。

function rusty_showphone() 
  $posts = get_posts(array(
    'posts_per_page'    => -1,
    'post_type'         => 'location'
  ));
  $userCity=get_the_user_ip();
  if( $posts ): 
    foreach( $posts as $post ): 
        $cityField=get_field('city');        
        $phoneField=get_field('phone_number');
         if($userCity==$cityField)
             return $phoneField;
         
     endforeach;
     wp_reset_postdata(); 
   endif; 
  
add_shortcode('showphone', 'rusty_showphone');

【讨论】:

这是有道理的,做你所说的并不会破坏我的功能,但它仍然只会显示在我所在的位置页面上。例如,短代码将仅在主页上显示为 [show_city],而不是实际显示电话号码。基本上,短代码仅适用于位置帖子。 我试过了,但由于某种原因,电话号码仍然没有显示在网站范围内。短代码可以在任何位置发布。这看起来很奇怪,因为当我打印它而不是返回它时,电话号码会在每一页上出现一秒钟,所以我知道它必须以某种方式访问​​。【参考方案2】:

所以我找到了解决方案。如果有人对我如何做得更好有任何建议,那就太好了。

首先,我在我的 wordpress 子主题中创建了一个名为 phone-display.php 的新文件,如下所示:

<?php 

function get_the_user_ip() 
    if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) 
    //Checks if IP is from shared internet
    $ip = $_SERVER['HTTP_CLIENT_IP'];
    
    elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) 
    //Checks if IP is passed from proxy
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
     
    else 
    //Most trustworthy source of IP address
    $ip = $_SERVER['REMOTE_ADDR'];
    
    //Uses ipinfo.io to find location information based on IP address
    $details = json_decode(file_get_contents("https://ipinfo.io/$ip"));

    //Returns city value from the details array
    $city=$details->city;

    return apply_filters('wpb_get_ip', $city );
    


$posts = get_posts(array(
    'posts_per_page'    => -1,
    'post_type'         => 'location'
));
$userCity=get_the_user_ip();
if( $posts ): 



     foreach( $posts as $post ): 

        $cityField=get_field('city');
        //echo "$cityField";        
        $phoneField=get_field('phone_number');
        //echo "$phoneField";
         if($userCity==$cityField)
             echo ($phoneField);
         

     endforeach;


    wp_reset_postdata(); 

 endif; 


?>

然后,我在希望显示电话号码的位置添加了这个自定义 div 元素。

<div id="phone"></div>

然后我将此 JavaScript 代码添加到我的 footer.php 文件的底部。

<script>document.getElementById("phone").innerHTML = '<?php include("phone-display.php"); ?>';</script>

【讨论】:

以上是关于我正在尝试将某种小部件或菜单添加到我所有 Wordpress 网站页面的顶部的主要内容,如果未能解决你的问题,请参考以下文章

缺少发布健康详细信息和发布健康概览小部件

如何以编程方式将 UI 添加到基于 Qtvtkwidget 的小部件?

谷歌地图溢出到外层

如何在我的 Qt 应用程序中对小部件进行分组?

如何将菜单添加到从 Qwidget 派生的小部件

finplot 作为布局中的小部件