Loading views_accordion through an ajax request - drupal

I am currently loading my view through an ajax request in my custom module:
$.getJSON('/reports/summarized-progress/get_output_activities/'+nid, null,activities);
The drupal page for the above request returns the following:
$output_arg=arg(3);
$html="";
$activities=views_embed_view('activities','block_activities',$output_arg); //this returns a view accordion view
if(!empty($activities)) {
$html.='';
$html.=$activities;
$html.='';
}
drupal_json_output(array('data'=>$html));
The accordion/collapsible functionality is not working on the loaded content. Any ideas whether I need to include through module_load_include any files in my custom module? What needs to be done for this to work?

Whenever you load content through ajax request, you have to ensure that the needed js settings/files are loaded along with your content.
In most cases, the $javascript static variable that is filled during a content load through drupal_add_js() is not sent to the browser, but you can do this manually :
Here a working Drupal 6 example :
// Get the view content.
$view = views_embed_view($name, $display_id);
// Get javascript data.
$js = drupal_add_js(NULL, NULL, 'header');
// Prepare data to be processed clientside.
$settings = drupal_to_js(call_user_func_array('array_merge_recursive', $js['setting']));
// Tell the client to extend Drupal.settings with collected $settings.
$script = '<script type="text/javascript">
jQuery.extend(true, Drupal.settings, ' . $settings . ');
</script>';
drupal_set_header('Content-Type:text/html; charset=utf-8');
print $script . $view;
exit;
Same in Drupal 7 :
$view = views_embed_view($name, $display_id);
$js = drupal_add_js(NULL, array('type' => 'setting'));
$settings = drupal_json_encode(call_user_func_array('array_merge_recursive', $js['settings']['data']));
$script = '<script type="text/javascript">
jQuery.extend(true, Drupal.settings, ' . $settings . ');
</script>';
drupal_add_http_header('Content-Type', 'text/html; charset=utf-8');
print $script . $view;
exit;
Note :
If your accordion view rely on a specific .js file, ensure this file is sourced inside every page where ajax requests take place. Usually, you'll have to explicitly source this file if such a page is loaded (full page load) without the view.
You can achieve this in a hook_page_preprocess() implementation :
function moduleName_preprocess_page(&$variables) {
// Include .js to the page so views can rely on in future ajax request
drupal_add_library('system', 'ui.accordion');
drupal_add_js(drupal_get_path('module', 'views_accordion') . '/views-accordion.js');
// Add the css for fixing/preventing accordion issues.
drupal_add_css(drupal_get_path('module', 'views_accordion') . '/views-accordion.css');
// ...
}
... or by including the file when the content is requested (as we do for Drupal.settings), just add a script tag in the $script variable in the ajax callback :
$script .= '<script type="text/javascript" src="sourcefile.js"></script>'
Hope this helps!

Related

How to notify through email in wordpress

How to notify through email in wordpress when visitor clicks on a link that this link was pressed and/or user ip, city and country was this?
I have given the link a class 'email-link'.
something like this should get you started
// functions.php
// HTML form markup
function mail_form_stuff() {
echo '<form action="' . esc_url( $_SERVER['REQUEST_URI'] ) . '" method="post">';
echo '<p><input type="submit" name="send_the_email_to_admin" value="Click this button"></p>';
echo '</form>';
}
// make sure the email will allow for html -- not just plain text
add_filter( 'wp_mail_content_type', 'send_the_email_to_admin_content_type' );
function send_the_email_to_admin_content_type() {
return 'text/html';
}
// if the button is clicked, send the email
function deliver_mail_link_stuff() {
$admin_email = get_option( 'admin_email' );
if ( isset($_POST["send_the_email_to_admin"]) ) {
$_user = wp_get_current_user();
$_name = esc_html( $_user->user_firstname );
$_email = esc_html( $_user->user_email );
$to = $admin_email;
$subject = "Some person clicked my link";
$message = 'Hey this person clicked on that button'.'<br>';
$message .= "the persons email address was: $_email";
$headers[] = "From: $_name <$_email>" . "\r\n";
// $headers[] = "Bcc: John Smith <jsmith#gmail.com>" . "\r\n";
// If everything worked -- display a success message
if ( wp_mail( $to, $subject, $message, $headers ) ) {
echo '<p>sent</p>';
} else {
echo 'An unexpected error occurred';
}
// reset wp_mail_content_type
remove_filter( 'wp_mail_content_type', 'send_the_email_to_admin_content_type' );
}
}
function add_short_code_stuff() {
ob_start();
deliver_mail_link_stuff();
mail_form_stuff();
return ob_get_clean();
}
add_shortcode( 'EMAIL_BUTTON', 'add_short_code_stuff' );
this will add a short code for you
you can then call the shortcode in your theme with
echo do_shortcode('[EMAIL_BUTTON]');
You can't do this as a direct consequence of WordPress since a link is HTML and has no correlation to or integration with anything controlled or processed directly by WordPress. WordPress is merely a structure/processes through which you can add info to a database and then later retrieve it.
If you question is actually meant in a more generic and not specifically wordPress sense, then the answer is any number of ways. You could for example create some JQuery or JS that would add that info everytime a link was clicked. But, you would need to interact with the page headers to try and get all the required info.
But, why bother doing that when a free & arguably market leading tool that does this is already available?
The logical process to this is to use Google Analytics (or a rival tool) as this already collects this kind of info with very little work required to set it up. If you want more specific "event" triggered data (eg a link is clicked), then you can also do this fairly easily too.
https://analytics.google.com
UPDATE
In your comment, you clarify that you want a real time email to be sent to you when a link is clicked, and thus analytics isn't going to fit the bill. In that case you will need to do some work using JQuery & AJAX.
In simple terms you'll need to do something this:
1) Create some JQuery to intercept the url of the link clicked
2) Pass the link (and header info) to a function via an AJAX call
3) Process the header data / send the email
4) Redirect user to the url passed from the link
Here's a tutorial on creating a simple AJAX process in WordPress: https://www.makeuseof.com/tag/tutorial-ajax-wordpress/

Send pdf from wp_remote_get to browser

I'm integrating a wordpress site with an external API. I have a form that posts to my server and I call a function on my server that makes a wp_remote_get call to the external API.
The external API returns a PDF, with headers like:
[date] => Fri, 18 Aug 2017 15:59:19 GMT
[x-powered-by] => Servlet/3.0
[cache-control] => no-cache
[content-type] => application/pdf;charset=utf-8
[content-language] => en-US
And the response body is the PDF in nasty string format, which seems like a good start.
How do I pass this PDF to the user's browser?
ie,
$response = wp_remote_get( $url, array ( //stuff the request needs));
if (is_wp_error ($response)) {
$error_message = $response->get_error_message();
echo "Something went wrong: $error_message";
} else {
//What here?
}
I have to hit my server first, cannot post the form directly to the external API.
I managed this by using javascript to redirect my form submit to a new window on my site, passing along the form information as URL params.
ie,
in my HTML:
<form onsubmit="return qrsDownload()">
And then in javascript:
function qrsDownload() {
// a bunch of jquery and processing to build the URL..
window.open(url, 'My Title', 'width=800, height=600');
}
The page I opened was a single-use page template I created, that I omitted the standard WP templates in (so no header, no footer, no wordpress loop), and in that page's php file:
<?php
if (isset($_GET['someParam'])) {
// started off with logic to verify that I had the params needed
// because anybody could just jump directly to this page now
}
$url = "whateverurl.com/myendpoint";
// additional logic to set up the API call
$server_response = wp_remote_get($url, $args);
if (is_wp_error( $server_response) ) {
// do something to handle error
} else {
// PASS OUR PDF to the user
$response_body = wp_remote_retrieve_body( $server_response);
header("Content-type: application/pdf");
header("Content-disposition: attachment;filename=downloaded.pdf");
echo $response_body;
}
} else {
get_header();
$html = "<div class='content-container'><p>A pretty error message here.</p></div>";
echo $html;
get_footer();
}
?>
The approach is essentially to pass the result from the API straight back out the user, but you need the headers to specific it's a PDF, and the headers have to be set before you write out any output. An easier way to ensure this was to do it in a new window, rather than strictly on the form postback.

How to load jQuery before fallback in Wordpress footer

I enqueue a bunch of scripts into the footer of my page:
function core_scripts() {
wp_deregister_script('jquery');
wp_register_script('jquery', '//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js', false, null, true);
wp_register_script('bootstrap', '//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js', array('jquery'), '3.1.1', true);
wp_register_script('flexslider', get_template_directory_uri().'/js/jquery.flexslider-min.js', array('jquery'), '2.2.2', true);
wp_register_script('jqzoom', get_template_directory_uri().'/js/jquery.jqzoom-core-pack.js', array('jquery'), '2.3', true);
wp_register_script('fancybox', get_template_directory_uri().'/js/jquery.fancybox.pack.js', array('jquery'), '2.1.5', true);
... a bunch of others ...
}
add_action('init', 'core_scripts'); // Add Custom Scripts
function write_site_scripts()
{
wp_enqueue_script('jquery');
wp_enqueue_script('bootstrap');
wp_enqueue_script('flexslider');
wp_enqueue_script('jqzoom');
wp_enqueue_script('fancybox');
...etc...
}
add_action('wp_enqueue_scripts', 'write_site_scripts'); // write all enqueued scripts
function write_custom_scripts()
{
$html = "<!-- Custom script -->
<script>
var custom = '1';
</script>";
echo $html;
}
add_action('wp_footer', 'write_custom_scripts'); // this script writes in the footer before the dependent js scripts
My problem is that the custom script is always written to the page before the jQuery scripts, I guess because the custom script is written to the page via an echo write command.
How can I add custom javascript code into the footer after the jQuery scripts have been written to the page? ie. I need to delay the add_action('wp_footer', 'write_custom_scripts'); to be executed at a later moment, or how can I use enqueue to add a custom javascript?
Note I have removed the CDN code posted earlier since this leads everyone into another discussion - a valid one, but it's not the issue I am after at this moment.
Edit II
Since the question has changed in essence many times, and In order to save you from reading ( e.g. - understanding ) all of the long explanation below, just use .
add_action('wp_footer', 'write_custom_scripts',9999);
This will set the priority to very high and will probably echo your code last ( unless you or other plugin / theme developers used a higher priority or later filter ..)
For those who want to do the right way :
function my_javascripts() {
wp_enqueue_script('the-script-handle',
'path/to/file.js',
array('jquery','other_script_that_we_depend_on'),
'scriptversion eg. 1.0',
true);
}
add_action('wp_enqueue_scripts', 'my_javascripts');
When you enqueue a script like above ( the right way ) , you can see that it wp_enqueue_script() has 4 arguments.path, dependencies ,version ,and in-footer .
This is the only right way to load a script , and if you need , just enqueue also jquery at the same function -- wp will make sure it loads first .
The dependencies means that wp will not load your script UNLESS jQuery is already loaded and will try to load jQuery FIRST ...
The LAST argument will actually define weather to load your script in the FOOTER ( TRUE ) or in header ( FALSE )
That being said , you can always load jQuery in the HEADER and not footer ( but it is not so recommended )
After that , For the last bit of your script , you can echo it in the footer , and you can also control how and when to add it .
What I do not understand , is the overall aim of your method . ( this part is about the "doing it wrong " )
Firstly - I think that loading from CDN is not a good IDEA . AND I AM NOT ALONE. it is to be considered a bad practice in WP without any meaningful Pros ( the time issue is a joke since you will be probably loading a LOT of other scripts directly AND scripts are Cached ).
While doing it - it is good that you think of a fallback, but the fallback should be wp own version - and not one that you include yourself .
If you still insist on doing it wrong , you can always do something like ( or just change order of execution ):
remove_action('wp_head', 'wp_print_scripts');
remove_action('wp_head', 'wp_print_footer_scripts', 9);
remove_action('wp_head', 'wp_enqueue_scripts', 1);
// your stuff
add_action('wp_footer', 'wp_print_scripts', 5);
add_action('wp_footer', 'wp_enqueue_scripts', 5);
add_action('wp_footer', 'wp_print_footer_scripts', 5);
Which basically allow you to echo your stuff before or after the wp_footer action at will And while technically it will work -. it is still wrong .
Edit I After question edit .
you have several problems in that code .
you are registering jQuery (CDN ) with the handle jquery which is reserved for WP.
If you want to do that ( and you shouldn´t . please don´t ) you need to deregister jquery BEFORE registering it again .
<?php wp_deregister_script( 'jquery' ); ?>
Again. I can not stress enough how wrong that is .
2 . you are registring the whole bunch of script - but where do you enqueue them ?
3 . Again . Like in comments ( I think you still do not understand )
If you have a script to add to the footer - you need to register and enqueue it with dependencies .. ( the right way )
In your case from edited question :
make a file called my_script.js
var custom = '1';
Enqueue it !
wp_enqueue_script('the-script-handle',
'path/to/my_script.js',
array('jquery','other_script_that_we_depend_on'),
'0.0.1',
true);
In this case , your script will load AFTER the dependencies you listed ...
What you are trying to do is echoing directly .
As for the comment of how to correctly pass variables - read here
And you can also do something like this ( objects ):
$data = (object) array(
'render' => 'canvas',
'size' => 100,
'radius' => ($q_corner_r * 0.3),
);
$output .=
<script type="text/javascript">;
//<![CDATA[
var options = ' . json_encode($data) . '
// ]]>;
</script>';

How can I style the WordPress failure notice page?

Is there a way I can style the WordPress failure notice page? Take a look at the screenshot below which shows an example of the page. This page is generated at various times and for various reasons. To generate the page, open 2 tabs in your browser and login to the same WordPress site on each tab.
1: log out of the site via the first tab you have open.
2: log out via the second tab.
You'll see the failure page.
The approach I took was to set up a custom die handler which gives you the option to style all 'die' messages.
// custom die handler
function get_custom_die_handler() {
return 'custom_die_handler';
}
// hook the function
add_filter('wp_die_handler', 'get_custom_die_handler' );
// build a custom die handler
function custom_die_handler( $message, $title = '', $args = array() ) {
// whatever you want the die handler to do
}
Navigate to the file /wp-includes/functions.php look for a function called
wp_nonce_ays
That is the function which outputs the error page. That is a core function, which is called by the action of check_admin_referer. You could try to hook into that action; the only problem is that it dies after wp_nonce_ays is called, so using add_action has no effect since it dies before it would trigger. However, luckily, check_admin_referer is a pluggable function, so you can make a function to override it. Our function will be an exact copy of check_admin_referer except one extra line of code is added to style it. Save the function, I called it styleFailPage.php, and put it in your /wp-content/plugins/ folder.
<?php /*
* Plugin Name:Failure Styler
* Description:Adds a style element right before the failure notice is called
*/
if ( ! function_exists( 'wp_logout' ) ) {
function check_admin_referer($action = -1, $query_arg = '_wpnonce') {
if ( -1 == $action )
_doing_it_wrong( __FUNCTION__, __( 'You should specify a nonce action to be verified by using the first parameter.' ), '3.2' );
$adminurl = strtolower(admin_url());
$referer = strtolower(wp_get_referer());
$result = isset($_REQUEST[$query_arg]) ? wp_verify_nonce($_REQUEST[$query_arg], $action) : false;
if ( !$result && !(-1 == $action && strpos($referer, $adminurl) === 0) ) {
//this is the line I added:
echo "<style>body {background:red !important;}</style>";
wp_nonce_ays($action);
die();
}
do_action('check_admin_referer', $action, $result);
return $result;
}
}
?>
This will make invalid HTML because you have to end up inserting the <style> info ABOVE the doctype declaration, however AFAIK this is unavoidable without explicitly editing the core wp_nonce_ays function

How to add a backup javascript file in Wordpress that initially loads off internet

I'm sure you're all aware of loading files like jquery off google. I'm trying to load a file similarly, but I want to have a backup of that file on my server incase the online version is down, and I don't know how to go about that in Wordpress.
Here's what I have currently which loads it from the url
wp_deregister_script('html5shiv');
wp_register_script('html5shiv', ("http://html5shim.googlecode.com/svn/trunk/html5.js"),false);
wp_enqueue_script('html5shiv');
I think this is what you are looking for.
C&P in case someone came back later looking for this and the site is unavailable:
<?php
$url = 'http://ajax.googleapis.com/ajax/libssss/jquery/1.6.4/jquery.min.js'; // the URL to check against
$test_url = #fopen($url,'r'); // test parameters
if($test_url !== false) { // test if the URL exists
function load_external_jQuery() { // load external file
wp_deregister_script( 'jquery' ); // deregisters the default WordPress jQuery
wp_register_script('jquery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js'); // register the external file
wp_enqueue_script('jquery'); // enqueue the external file
}
add_action('wp_enqueue_scripts', 'load_external_jQuery'); // initiate the function
} else {
function load_local_jQuery() {
wp_deregister_script('jquery'); // initiate the function
wp_register_script('jquery', bloginfo('template_url').'/js/libs/jquery-1.6.1.min.js', __FILE__, false, '1.6.4', true); // register the local file
wp_enqueue_script('jquery'); // enqueue the local file
}
add_action('wp_enqueue_scripts', 'load_local_jQuery'); // initiate the function
}
?>
I'm not familiar with the Wordpress queuing system, but here is some general code for javascript with fallback. You may want to post this question at http://wordpress.stackexchange.com where WP api questions tend to get better answers. Here is a fallback mechanism
//add a property to the window object in foo.js
window.banana = 'peeled';
<head>
<script src="https://mysite.com/foo.js" type="text/javascript"></script>
<script type="text/javascript">
//fallback mechanism if not available
if (!window.Banana) { document.write(unescape("%3Cscript src='/localfoo.js' type='text/javascript'%3E%3C/script%3E")); }
</script>
</head>

Resources