How to include global styles to elementor? - wordpress

I want to learn more about elementor theme development. I have set up header.php, footer.php and index.php and created a new page via wordpress admin. I added a new widget, which show correctly in my editor, but when i publish the page, my global elementor styles are not applied. I tried searching the documentation and googling, but found nothing. I assume i need to call some elementor function to make this work. What am i missing?
For example: --e-global-color-primary is undefined
Here are my files:
header.php
<!DOCTYPE HTML>
<html>
<head>
</head>
<body <?php body_class(); ?>>
<?php wp_head(); ?>
footer.php
<?php wp_footer(); ?>
</body>
</html>
index.php
<?php get_header(); ?>
<?php the_content(); ?>
<?php get_footer(); ?>

I have done some extra research on this. It is a bug in elementor and is not fixed yet. I ended up doing a workaround. It is provided below if anyone needs it.
add_action('the_content', 'load_elementor_style');
function load_elementor_style($content) {
[
$primary_color,
$secondary_color,
$text_color,
$accent_color
] = get_elementor_colors();
[
$primary_font,
$primary_font_weight,
$secondary_font,
$secondary_font_weight,
$text_font,
$text_font_weight,
$accent_font,
$accent_font_weight
] = get_elementor_fonts();
$content .= sprintf(
'
<style>
:root {
--e-global-color-primary: %s !important;
--e-global-color-secondary: %s;
--e-global-color-text: %s;
--e-global-color-accent: %s;
--e-global-typography-primary-font-family: %s;
--e-global-typography-primary-font-weight: %s;
--e-global-typography-secondary-font-family: %s;
--e-global-typography-secondary-font-weight: %s;
--e-global-typography-text-font-family: %s;
--e-global-typography-text-font-weight: %s;
--e-global-typography-accent-font-family: %s;
--e-global-typography-accent-font-weight: %s;
}
</style>
',
$primary_color,
$secondary_color,
$text_color,
$accent_color,
$primary_font,
$primary_font_weight,
$secondary_font,
$secondary_font_weight,
$text_font,
$text_font_weight,
$accent_font,
$accent_font_weight
);
return $content;
}

If you look at your browser developer tools inspector and take a look at .elementor-kit-X {...} (where X is a number set by elementor) at the bottom of your CSS declarations, you'll see all of the specified __globals__, which includes your font families as well.
Take this control as an example:
// Circle Color
$this->add_control(
'list_circle_color', [
'label' => __('Circle Color', 'vs-elementor-elements'),
'type' => \Elementor\Controls_Manager::COLOR,
'default' => __('', 'vs-elementor-elements'),
'frontend_available' => true,
'label_block' => true,
'placeholder' => __('E.g. #11a0c0', 'vs-elementor-elements'),
]
);
Next, add this near the top of your protected function render(){...}: echo'<pre>';print_r($settings);echo'</pre>';
Go into edit mode, and specify a non-global color for your list_circle_color control. Then save. Now refresh your page.
You will see your data printed on the page resembling the following:
(
[control_item1] => 6000
[control_item2] => Lorem ipsum
[list_circle_color] => #AFE039
[control_itemETC] => Dolor Sit Amet
)
You see list_circle_color set to #AFE039.
Now go back and edit your color again, but this time select an Elementor global color. Then save. New refresh your page.
You will see your data printed on the page resembling the following:
(
[control_item1] => 6000
[control_item2] => Lorem ipsum
[__globals__] => Array
(
[list_circle_color] => globals/colors?id=13c6ce9
)
[list_circle_color] =>
[control_itemETC] => Dolor Sit Amet
)
Now how to work with this? Recall from above I mentioned that Elementor stores your globals inside .elementor-kit-N {...}? Here is a reference at w3schools.
But how do you get the value set by globals/colors?id=13c6ce9? You can do this using PHP's str_replace, as in the following:
$list_circle_color_global = $setting['__globals__']['list_circle_color'];
$list_circle_color_global = str_replace('globals/colors?id=','--e-global-color-',$list_circle_color_global);
This will give you the var with the full property ending that you need, as in:
--e-global-color-13c6ce9
Now assign either via an internal spreadsheet in your widget, or as an inline style:
.mycircle{ background-color: <?php echo 'var(' . $list_circle_color_global . ')'; ?>; }
Lastly, how do you check to see if you are using a global or a non-globally set color value? Check __globals__ and list_circle_color using a simple if condition:
$circlecolor = $list_circle_color_global ? 'var(' . $list_circle_color_global . ')' : $list_circle_color;
** $list_circle_color should be set when you're specifying your variables. I excluded that before. When you specified $list_circle_color_global initially above, you would also create $list_circle_color = $settings['list_circle_color'];

Related

How to display feautured image of a post when hovering on the posts link (WordPress)?

I want to make my website's first page so you have posts listed with only titles and meta (reader friendly, easy to load...).
When you found something interesting you'd put the cursor on the title (linking to the post) and that would display a featured image beside (either on a specific spot on the site or offset just enough to not cover any of the text or replacing the cursor).
It's been done before, here is an example:
I'm assuming I'd have to use this to get the feautured image:
get_the_post_thumbnail_url( int|WP_Post $post = null, string|array $size = 'post-thumbnail' ).
The problem is I that I only know HTML and CSS, some very basic JS and have no clue about PHP. I found a couple examples on the web but couldn't get any to work.
Can you tell me how to get the image from the post link and display it (dynamically so it can work for any post link on the site)?
Thank you.
You can add output of the_post_thumbnail inside a <div></div> tag which it is hidden, Then you can show it when mouse:hover has been happened.
Structure is something like this:
<div class="featured-image">
<?php the_title(); ?>
<php the_post_thumbnail( 'full' ); ?>
</div>
In css file you should set:
div.featured-image img{
display:none;
}
When mouse hover has been occurred you should display Featured Image,Code will be something like this:
div.featured-image a:hover + img{
display: inline-block;
}
Try using this the_post_thumbnail(); it should display the post's image.
Check those:
https://developer.wordpress.org/reference/functions/get_the_post_thumbnail/
https://codex.wordpress.org/Post_Thumbnails
https://smartwp.com/wordpress-get-featured-image/
That's the first link when I googled it, so I will post solution here.
So I've achieved this effect by using Ajax:
AJAX is an acronym standing for Asynchronous JavaScript and XML and this technology helps us to load data from the server without a browser page refresh.
Details: https://api.jquery.com/jquery.ajax/
Diagram is helpful in understanding: https://i.stack.imgur.com/Zqyrn.gif
I've created jQuery which is getting url from the hovered link and sends it through Ajax to a server, and if process is successful, it renders the data returned:
var hrefValue;
jQuery(document).ready(function($) {
$('#bio-box').find('a').mouseover(function() {
hrefValue = ($(this).attr('href'))
//console.log(hrefValue)
$.ajax({
url: frontendajax.ajaxurl,
type: 'POST',
data: {
'action': 'image',
'php_test': hrefValue
},
success: function(data){
$('#featured-image').html(data);
//console.log(data);
}
});
});
});
This function generates the data:
function fimg() {
if ( isset( $_POST['php_test'] ) ) {
$testing = sanitize_text_field( wp_unslash( $_POST['php_test'] ) );
$post_id = url_to_postid( $testing );
echo get_the_post_thumbnail( $post_id );
}
die();
}
add_action( 'wp_ajax_image', 'fimg' );
add_action( 'wp_ajax_nopriv_image', 'fimg' );
HTML:
<div id="featured-imageā€>
</div>
It is working, and solves the problem. I hope it will help someone. Make notice that whole thing still needs some sanitation.

Change Wordpress logo click redirection

I would like to change the logo redirection when clicked. Right now when you click on the logo, the user is redirected to the homepage but I want it to redirect to another site. How do I do this?
I agree with Stu Mileham. Another way to implement what you are asking for would be to use JavaScript / jQuery.
Save the following code to a .js file (eg. pageRedirect.js, let's say placed in a js folder inside your theme's root folder):
(function($) {
$(document).ready(function() {
$('#pageLogo').on( "click", function(event) {
event.preventDefault();
window.location.assign("http://www.google.com/");
});
});
})(jQuery);
To make the previous code work, you would have to select somehow the page logo via jQuery.
On the previous code this is achived via $('#pageLogo') since I have made the assumption that your logo has an id with the value pageLogo.
Of course, to enable your theme to use this pageRedirect.js file, you have to enqueue it by placing the following code to your theme's functions.php file:
/**
* Enqueue pageRedirect script.
*/
function pageRedirect_scripts() {
wp_enqueue_script( 'page-redirect-js', get_template_directory_uri() . '/js/pageRedirect.js', array('jquery'), '20150528', true );
}
add_action( 'wp_enqueue_scripts', 'pageRedirect_scripts' );
Code Explanation:
//-jQuery selects html element with id='pageLogo'
//-when it is clicked, it calls a function in which it passes the event
$('#pageLogo').on( "click", function(event) {
//prevents page from redirecting to homepage
event.preventDefault();
//redirects to your desired webpage
window.location.assign("http://www.google.com/");
});
If you don't have the option to change the link from admin then you will have to edit your theme's header.php file (most likely, depends on how the theme is built though).
Many themes have a tag similar to the following:
<img src="logo.jpg">
You would need to change this to:
<img src="logo.jpg">
I've added the target tag to open the site in a new window, this is my personal preference when re-directing to a different site but it's optional.
Your theme files might look very different to this, it's impossible to know for sure without seeing some code, but this should give you an idea.
Also be aware that your changes could be overwritten by a theme update. This can be avoided by creating a child theme.
https://codex.wordpress.org/Child_Themes
Depends on your theme
Some theme creators gives you the possibility to change the link from admin
Some theme creators just believe that clicking the logo you need to go on homepage - so you need to edit the theme
Depending upon the theme you are using, you can try one of the following options.
Explore the admin options and see if the theme provides a direct way to change the link on the logo.
If not found in admin options, try looking for the code in header.php. Do an inspect element on your logo and see the html code surrounding the logo file, If the code is directly present in header.php, your task is simple. Just change the code to update the URL, instead of reading it from home_url(). Something like <a href="<?php echo home_url();?>"> will need to be replaced with <a href="https://www.example.com">
The other option to look for is get_custom_logo. Some themes get the logo code from this function. You can apply a filter to change the home_url just before this method is called in your theme and then remove filter afterwards. Or else you can copy the code from wordpress and update it with a differently named function say get_custom_link_logo in functions.php then where'ver your theme is using get_custom_logo you can use get_custom_link_logo instead of that.
function get_custom_link_logo ( $blog_id = 0 ) {
$html = "";
$switched_blog = false;
if ( is_multisite() && ! empty( $blog_id ) && (int) $blog_id !== get_current_blog_id() ) {
switch_to_blog( $blog_id );
$switched_blog = true;
}
$custom_logo_id = get_theme_mod( 'custom_logo' );
// We have a logo. Logo is go.
if ( $custom_logo_id ) {
$custom_logo_attr = array(
'class' => 'custom-logo',
'itemprop' => 'logo',
);
/*
* If the logo alt attribute is empty, get the site title and explicitly
* pass it to the attributes used by wp_get_attachment_image().
*/
$image_alt = get_post_meta( $custom_logo_id, '_wp_attachment_image_alt', true );
if ( empty( $image_alt ) ) {
$custom_logo_attr['alt'] = get_bloginfo( 'name', 'display' );
}
/*
* If the alt attribute is not empty, there's no need to explicitly pass
* it because wp_get_attachment_image() already adds the alt attribute.
*/
$html = sprintf( '%2$s',
esc_url( "https://www.example.com" ),
wp_get_attachment_image( $custom_logo_id, 'full', false, $custom_logo_attr )
);
}
// If no logo is set but we're in the Customizer, leave a placeholder (needed for the live preview).
elseif ( is_customize_preview() ) {
$html = sprintf( '<img class="custom-logo"/>',
esc_url( "https://www.example.com" )
);
}
if ( $switched_blog ) {
restore_current_blog();
}
/**
* Filters the custom logo output.
*
* #since 4.5.0
* #since 4.6.0 Added the `$blog_id` parameter.
*
* #param string $html Custom logo HTML output.
* #param int $blog_id ID of the blog to get the custom logo for.
*/
return apply_filters( 'get_custom_logo', $html, $blog_id ); }
This might not cover all the use cases, but you get the idea. Depending upon the theme you'll have a similar solution for your case. The important thing to figure out which case you fall under will be to identify the code where html for your logo is getting added. header.php is a good starting point.
Use this javascript in the header or footer of your theme:
<script>
document.getElementsByClassName("site-logo")[0].getElementsByTagName('a')[0].href="https://www.test.com";
</script>
i am assuming that site-logo is the class name of your LOGO.

Strange code in an attribute creating a Google Maps shortcode

I'm creating a shortcode that outputs the javascript code to create a customized Google Map, like this:
[map w="600" h="400" style="full" z="16" marker="yes" infowindow="<h2>Title</h2>" address="New York"]
Here are some extracts of the code:
function gmap($atts) {
$atts = shortcode_atts(array(
[...]
'infowindow' => '',
[...]
'style' => ''
), $atts);
[...]
//infowindow
if($atts['infowindow'] != '')
{
$thiscontent = htmlspecialchars_decode($atts['infowindow']);
$returncode .= '
var contentString = \'' . $thiscontent . '\';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
';
}
[...]
return $returncode;
}
Everything is fine if in "infowindow" I only use text, but if I use markup, like <h2>Title</h2> what I get in the code is:
var contentString = '<br />
<h2>Title</h2>
<p>';
... with two newlines that mess up the js.
Can anybody help me?
Thanks a lot!
Looks like you're getting screwed over by WordPress's automatic paragraph formatting.
Option 1: Sometimes you can get around this by switching to the html tab of the editor, then removing any whitespace in your markup, but this also has a tendency to fall apart next time you edit the same page/post.
Option 2: Disable wpautop in your theme's functions.php:
remove_filter( 'the_content', 'wpautop' );
However, this might screw up your content elsewhere on your site.
Option 3. Use yet another plugin, to toggle wpautop on or off of specific pages: https://wordpress.org/plugins/toggle-wpautop/
Option 4. Add some more shortcode attributes, then apply the required html via PHP, so you don't have to deal with this!

Drupal 7 - Appending class names to a menu block <ul>

I've been stuck on how to manipulate in the template file what a menu block outputs in it's html. The regular < ul class="menu" > with li links is fine and I don't need to completely gut this html that drupal creates for all menus but I want to inject classes 'inline' and 'links' like the system main menu (usually) already has under it's ul element. I could print the menu directly in the theme skipping blocks altogether but it would be more helpful in the long run to learn injecting class names into the output of menu blocks that are generated.
So far from googling around I've only been able to find a module that can enter ID's and Class names on the individual li's but not the ul wrapping them and I've been unable to get any similar template file snippets I've come across to work.
There is a way to use a hook function to do this isn't there?
Why don't you add the classes you want via javascript?!
Example:
jQuery("#MY_MENU_WRAPPER ul.menu").addClass("inline");
If that's the case, try the following code in your theme's template.php file
function return_menu_markup($menu_name, $attributes)
{
$items = array();
$menu_tree = menu_tree_all_data($menu_name);
$menu_tree_output = menu_tree_output($menu_tree);
foreach($menu_tree_output as $item_id => $item_data)
{
if(is_numeric($item_id) && is_array($item_data))
{
$items[] = l('<span>' . $item_data['#title'] . '</span>', $item_data['#href'], array(
'attributes' => $item_data['#attributes'],
'html' => TRUE,
)
);
}
}
return theme('item_list', array('items' => $items, 'type' => 'ul'));
}
Then anywhere in the template, simply do the following:
$attributes = array();
$attributes['id'] = "MY_MENU_ID";
attributes['class'] = array('MY_CLASS_1', 'MY_CLASS_2', 'MY_CLASS_3');
return_menu_markup("main-menu", $attributes);
Hope you find what needed :)
-Muhammad.
You can use template.php in your theme folder, use hook:
function THEMENAME_menu_tree__menu_main_navigation($variables){
return "<ul class=\"inline\">\n" . $variables['tree'] ."</ul>\n";
}
also note this menu_main_navigation is menu URL path, other values are always same. Do some cache delete few times, maybe it want work immediately.

Insert code right after body tag using theme functions

I am trying to add a piece of code at the begining of every page in a Drupal site.
Since I have more than one page template, I want to do this programatically... but am not succeeding.
I am still new and, though I get the gist of hooks, theme functions, and the such, I just can't figure the correct way to achieve this.
So far I've overriden the theme_preprocess_page(&$vars) to add the necessary css and js:
function mytheme_preprocess_page(&$vars) {
if(condition) {
drupal_add_js(drupal_get_path('module', 'mymodule').'/js/modal.js');
}
}
How can I now add html code in every drupal page, preferably just after the opening bodytag or in any other starting section, via a function in the template.phpfile?
Thank you
In your preprocess function, any variable set, will be available in your page.tpl.php file.
function mytheme_preprocess_page(&$vars) {
if (condition) {
$vars['foo'] = '<div id="bar">TEST</div>';
}
}
then, in your page templates:
<body>
<?php print !empty($foo) ? $foo : ''; ?>
...
Had a look at https://www.drupal.org/project/google_tag. This is how they did it:
/**
* Implements hook_page_alter().
*
* Adds a post_render callback
*/
function MYMODULE_page_alter(&$page) {
$page['#post_render'][] = 'MYMODULE_CALLBACK';
}
/**
* Implements callback_post_render().
*
* Inserts JavaScript snippet immediately following the opening body tag.
*/
function MYMODULE_CALLBACK(&$children, $elements) {
$script = '<script type="text/javascript">console.log(\'hello world\');</script>';
// Insert snippet after the opening body tag.
$children = preg_replace('#<body[^>]*>#', '$0' . $script, $children, 1);
return $children;
}
This should keep you from having to modify any code in your templates:
function MY_MODULE_page_build(&$page)
{
$page['page_bottom']['my-markup'] = array('#markup' => '<div>My Markup Here</div>');
}
My approach finally was overriding the first rendered block in the page, in my case the Language Switcher.
Since I already was overriding it to customize it, it wasn't too much of a big deal, but it is anyway an ugly way to achieve that.
<?php
function mytheme_languageswitcher($links) {
// inserting this here like a virus in a dna strip
if(condition) {
drupal_add_js(drupal_get_path('module', 'mymodule').'/js/modal.js');
}
// the *real* code for the language switcher override
}
?>
Since the Language Switcher is rendered in every page, it works. The day the language switcher stops being displayed for whatever reason, this solution will FAIL.
You can add it to the footer with an option passed into the drupal_add_js function.
function THEMENAME_preprocess_page(&$variables) {
if (condition) {
drupal_add_js(drupal_get_path('theme', 'THEMENAME') . '/PATH/TO/FILE.js', array('scope' => 'footer'));
}
}
This will end up printing just before the closing body tag via the $page_bottom variable in the template html.tpl.php.
Another way to do it is to use the native drupal methods drupal_add_js and drupal_get_js.
// first, add your JS with a custom "scope" (before process phase)
<?php
drupal_add_js($tag_js, array(
'type' => 'inline',
'group' => JS_GROUP_TAGS,
'every_page' => TRUE,
'scope' => 'body_start',
'weight' => 1,
));
?>
// ugly way : add the drupal_get_js directly into html.tpl.php (but for testing, it's useful):
<body>
<?php print drupal_get_js('body_start'); ?>
...
</body>
// A cleaner way : use an intermediate variable, in a process method
// Exactly like template_process_html, in theme.inc
<?php
function MYMODULEORTHEME_process_html(&$variables){
$variables['js_body_start'] .= drupal_get_js('body_start');
}
?>
Enjoy :)

Resources