<sect1>
<title>Introduction</title>
<para>
As of version 1.7, Zend Framework integrates <ulink>jQuery</ulink> view and form helpers through
its extras library. The jQuery support is meant as an alternative
to the already existing Dojo library integration. Currently jQuery can
be integrated into your Zend Framework applications in the following ways:
</para>
<itemizedlist>
<listitem><para>View helper to help setup the jQuery (Core and UI) environment</para></listitem>
<listitem><para>jQuery UI specific Zend_View helpers</para></listitem>
<listitem><para>jQuery UI specific Zend_Form elements and decorators</para></listitem>
</itemizedlist>
<para>
By default the jQuery javascript dependencies are loaded from the Google Ajax Library
Content Distribution Network. The CDN offers both jQuery Core and jQuery UI access points and
the view helpers therefore can already offer you most the dependencies out of the box. Currently
the Google CDN offers jQuery UI support up to version 1.5.2, but the jQuery view and form helpers
already make use of the UI library 1.6 version (AutoComplete, ColorPicker, Spinner, Slider).
To make use of these great additions you have to download the release candidate version of the
<ulink>jQuery UI library</ulink> from its website.
</para>
</sect1><sect1>
<title>ZendX_JQuery View Helpers</title>
<para>
Zend Framework provides jQuery related View Helpers through its Extras Library.
These can be enabled in two ways, adding jQuery to the view helper path:
</para>
<programlisting>
$view->addHelperPath("ZendX/JQuery/View/Helper", "ZendX_JQuery_View_Helper");
</programlisting>
<para>Or using the <methodname>ZendX_JQuery::enableView(Zend_View_Interface $view)</methodname> method
that does the same for you.</para>
<sect2>
<title>jQuery() View Helper</title>
<para>
The <methodname>jQuery()</methodname> view helper simplifies setup of your jQuery environment
in your application. It takes care of loading the core and ui library dependencies if necessary
and acts as a stack for all the registered onLoad javascript statements. All jQuery view helpers
put their javascript code onto this stack. It acts as a collector for everything jQuery in your
application with the following responsibilities:
</para>
<itemizedlist>
<listitem><para>Handling deployment of CDN or a local path jQuery Core
and UI libraries.</para></listitem>
<listitem><para>Handling $(document).onLoad() events.</para></listitem>
<listitem><para>Specifying additional stylesheet themes to use.</para></listitem>
</itemizedlist>
<para>
The <methodname>jQuery()</methodname> view helper implementation, like its <methodname>dojo()</methodname> pendant,
follows the placeholder architecture implementation; the data set in it persists between view
objects, and may be directly echo'd from your layout script. Since views specified in a Zend_Layout
script file are rendered before the layout itself, the <methodname>jQuery()</methodname> helper can act as a
stack for jQuery statements and render them into the head segment of the html page.
</para>
<para>Contrary to Dojo, themes cannot be loaded from a CDN for the jQuery UI widgets and have to be implemented
in your pages stylesheet file or loaded from an extra stylesheet file. A default theme called Flora can be
obtained from the jQuery UI downloadable file.</para>
<example>
<title>jQuery() View Helper Example</title>
<para>
In this example a jQuery environment using the core and UI libraries will be needed. UI Widgets should
be rendered with the Flora thema that is installed in 'public/styles/flora.all.css'. The jQuery libraries
are both loaded from local paths.
</para>
<para>
To register the jQuery functionality inside the view object, you have to add the appropriate helpers
to the view helper path. There are many ways of accomplishing this, based on the requirements that the
jQuery helpers have. If you need them in one specific view only, you can use the addHelperPath method
on initialization of this view, or right before rendering:
</para>
<programlisting>
$view->addHelperPath('ZendX/JQuery/View/Helper/', 'ZendX_JQuery_View_Helper');
</programlisting>
<para>If you need them throughout your application, you can register them in your bootstrap
file using access to the Controller Plugin ViewRenderer:
</para>
<programlisting>
$view = new Zend_View();
$view->addHelperPath('ZendX/JQuery/View/Helper/', 'ZendX_JQuery_View_Helper');
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
$viewRenderer->setView($view);
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
</programlisting>
<para>Now in the view script we want to display a Date Picker and an Ajax based Link.</para>
<programlisting>
<?php echo $this->ajaxLink("Show me something",
"/hello/world",
array('update' => '#content'));?>

<form method="post" action="/hello/world">
Pick your Date: <?php echo $this->datePicker("dp1",
'',
array(
'defaultDate' =>
date('Y/m/d', time())));?>
<input type="submit" value="Submit" />
</form>
</programlisting>
<para>Both helpers now stacked some javascript statements on the jQuery helper and printed a link and
a form element respectively. To access the javascript we have to utilize the jQuery()
functionality. Both helpers already activated their dependencies that is they have called
<methodname>jQuery()->enable()</methodname> and <methodname>jQuery()->uiEnable()</methodname>. We only have to print
the jQuery() environment, and we choose to do so in the layout script's head segment:
</para>
<programlisting>

<title>A jQuery View Helper Example</title>
<?php echo $this->jQuery(); ?>

<?php echo $this->layout()->content; ?>

</programlisting>
<para>Although $this->layout()->content; is printed behind the $this->jQuery() statement,
the content of the view script is rendered before. This way all the javascript onLoad code has already been put
on the onLoad stack and can be printed within the head segment of the html document.
</para>
</example>
<sect3>
<title>jQuery NoConflict Mode</title>
<para>jQuery offers a noConflict mode that allows the library to be run side by side with other javascript libraries
that operate in the global namespace, Prototype for example. The Zend Framework jQuery View Helper makes usage of
the noConflict mode very easy. If you want to run Prototype and jQuery side by side you can call
ZendX_JQuery_View_Helper_JQuery::enableNoConflictMode(); and all jQuery helpers will operate in the No Conflict
Mode.</para>
<example>
<title>Building your own Helper with No Conflict Mode</title>
<para>To make use of the NoConflict Mode in your own jQuery helper, you only have to use the static method
<methodname>ZendX_JQuery_View_Helper_JQuery::getJQueryHandler()</methodname> method. It returns the variable jQuery is operating
in at the moment, either $ or <varname>$j</varname>
</para>
<programlisting>
class MyHelper_SomeHelper extends Zend_View_Helper_Abstract
{
public function someHelper()
{
$jquery = $this->view->jQuery();
$jquery->enable(); // enable jQuery Core Library
// get current jQuery handler based on noConflict settings
$jqHandler = ZendX_JQuery_View_Helper_JQuery::getJQueryHandler();
$function = '("#element").click(function() '
. '{ alert("noConflict Mode Save Helper!"); }'
. ')';
$jquery->addOnload($jqHandler . $function);
return '';
}
}
</programlisting>
</example>
</sect3>
<sect3>
<title>jQuery UI Themes</title>
<para>Since there are no online available themes to use out of the box, the implementation of the UI library themes
is a bit more complex than with the Dojo helper. The jQuery UI documentation describes for each component
what stylesheet information is needed and the Default and Flora Themes from the downloadable archive give hints
on the usage of stylesheets. The jQuery helper offers the function jQuery()->addStylesheet($path);
function to include the dependant stylesheets whenever the helper is enabled and rendered. You can optionally
merge the required stylesheet information in your main stylesheet file.
</para>
</sect3>
<sect3>
<title>Methods Available</title>
<para>
The <methodname>jQuery()</methodname> view helper always returns an instance of
the jQuery placeholder container. That container object has the
following methods available:
</para>
<sect4>
<title>jQuery Core Library methods</title>
<itemizedlist>
<listitem><para><methodname>enable()</methodname>: explicitly enable jQuery
integration.</para></listitem>
<listitem><para><methodname>disable()</methodname>: disable jQuery
integration.</para></listitem>
<listitem><para><methodname>isEnabled()</methodname>: determine whether or not
jQuery integration is enabled.</para></listitem>
<listitem><para><methodname>setVersion()</methodname>: set the jQuery version
that is used. This also decides on the library loaded
from the Google Ajax Library CDN</para></listitem>
<listitem><para><methodname>getVersion()</methodname>: get the current jQuery
that is used. This also decides on the library loaded
from the Google Ajax Library CDN</para></listitem>
<listitem><para><methodname>useCdn()</methodname>: Return true, if CDN usage is
currently enabled</para></listitem>
<listitem><para><methodname>useLocalPath()</methodname>: Return true, if local usage
is currently enabled</para></listitem>
<listitem><para><methodname>setLocalPath()</methodname>: Set the local path to the
jQuery Core library</para></listitem>
<listitem><para><methodname>getLocalPath()</methodname>: If set, return the local path to the
jQuery Core library</para></listitem>
</itemizedlist>
</sect4>
<sect4>
<title>jQuery UI Library methods</title>
<itemizedlist>
<listitem><para><methodname>uiEnable()</methodname>: explicitly enable jQuery UI
integration.</para></listitem>
<listitem><para><methodname>uiDisable()</methodname>: disable jQuery UI
integration.</para></listitem>
<listitem><para><methodname>uiIsEnabled()</methodname>: determine whether or not
jQuery UI integration is enabled.</para></listitem>
<listitem><para><methodname>setUiVersion()</methodname>: set the jQuery UI version
that is used. This also decides on the library loaded
from the Google Ajax Library CDN</para></listitem>
<listitem><para><methodname>getUiVersion()</methodname>: get the current jQuery UI
that is used. This also decides on the library loaded
from the Google Ajax Library CDN</para></listitem>
<listitem><para><methodname>useUiCdn()</methodname>: Return true, if CDN usage is
currently enabled for jQuery UI</para></listitem>
<listitem><para><methodname>useUiLocal()</methodname>: Return true, if local usage
is currently enabled for jQuery UI</para></listitem>
<listitem><para><methodname>setUiLocalPath()</methodname>: Set the local path to the
jQuery UI library</para></listitem>
<listitem><para><methodname>getUiLocalPath()</methodname>: If set, get the local path
to the jQuery UI library</para></listitem>
</itemizedlist>
</sect4>
<sect4>
<title>jQuery Helper Utility methods</title>
<itemizedlist>
<listitem><para><methodname>setView(Zend_View_Interface $view)</methodname>: set
a view instance in the container.</para></listitem>
<listitem><para><methodname>onLoadCaptureStart()</methodname>: Start capturing javascript code
for jQuery onLoad execution.</para></listitem>
<listitem><para><methodname>onLoadCaptureEnd()</methodname>: Stop capturing</para></listitem>
<listitem><para><methodname>javascriptCaptureStart()</methodname>: Start capturing javascript code
that has to be rendered after the inclusion of either jQuery Core or UI libraries.</para></listitem>
<listitem><para><methodname>javascriptCaptureEnd()</methodname>: Stop capturing.</para></listitem>
<listitem><para><methodname>addJavascriptFile($path)</methodname>: Add javascript file to be included after
jQuery Core or UI library.</para></listitem>
<listitem><para><methodname>getJavascriptFiles()</methodname>: Return all currently registered
additional javascript files.</para></listitem>
<listitem><para><methodname>clearJavascriptFiles()</methodname>: Clear the javascript files</para></listitem>
<listitem><para><methodname>addJavascript($statement)</methodname>: Add javascript statement to be included
after jQuery Core or UI library.</para></listitem>
<listitem><para><methodname>getJavascript()</methodname>: Return all currently registered
additional javascript statements.</para></listitem>
<listitem><para><methodname>clearJavascript()</methodname>: Clear the javascript statements.</para></listitem>
<listitem><para><methodname>addStylesheet($path)</methodname>: Add a stylesheet file that is needed
for a jQuery view helper to display correctly.</para></listitem>
<listitem><para><methodname>getStylesheets()</methodname>: Get all currently registered
additional stylesheets.</para></listitem>
<listitem><para><methodname>addOnLoad($statement)</methodname>: Add javascript statement that should
be executed on document loading.</para></listitem>
<listitem><para><methodname>getOnLoadActions()</methodname>: Return all currently registered
onLoad statements.</para></listitem>
<listitem><para><methodname>setRenderMode($mask)</methodname>: Render only a specific subset of the
jQuery environment via ZendX_JQuery::RENDER_ constants. Rendering all elements
is the default behaviour.</para></listitem>
<listitem><para><methodname>getRenderMode()</methodname>: Return the current
jQuery environment rendering mode.</para></listitem>
<listitem><para><methodname>setCdnSsl($bool)</methodname>: Set if the CDN Google Ajax Library should be loaded
from an SSL or a Non-SSL location.</para></listitem>
</itemizedlist>
<para>These are quite a number of methods, but many of them are used for internally by all the
additional view helpers and during the printing of the jQuery environment. Unless you
want to build your own jQuery helper or have a complex use-case, you will probably only
get in contact with a few methods of these.</para>
</sect4>
</sect3>
<sect3>
<title>Refactoring jQuery environment with setRenderMode()</title>
<para>Using the current setup that was described, each page of your website would show
a different subset of jQuery code that would be needed to keep the current jQuery related
items running. Also different files or stylesheets may be included depending on which
helpers you implemented in your application. In production stage you might want to centralize
all the javascript your application generated into a single file, or disable stylesheet
rendering because you have merged all the stylesheets into a single file and include it statically
in your layout. To allow a smooth refactoring you can enable or disable the rendering
of certain jQuery environment blocks with help of the following constants and the
<methodname>jQuery()->setRenderMode($bitmask)</methodname> function.</para>
<itemizedlist>
<listitem><para>ZendX_JQuery::RENDER_LIBRARY: Renders jQuery Core and UI library</para></listitem>
<listitem><para>ZendX_JQuery::RENDER_SOURCES: Renders additional javascript files</para></listitem>
<listitem><para>ZendX_JQuery::RENDER_STYLESHEETS: Renders jQuery related stylesheets</para></listitem>
<listitem><para>ZendX_JQuery::RENDER_JAVASCRIPT: Render additional javascript statements</para></listitem>
<listitem><para>ZendX_JQuery::RENDER_JQUERY_ON_LOAD: Render jQuery onLoad statements</para></listitem>
<listitem><para>ZendX_JQuery::RENDER_ALL: Render all previously mentioned blocks, this is default behaviour.</para></listitem>
</itemizedlist>
<para>
For an example, if you would have merged jQuery Core and UI libraries as well as other files into a single large file
as well as merged stylesheets to keep HTTP requests low on your production application.
You could disallow the jQuery helper to render those parts, but render all the other stuff
with the following statement in your view:
</para>
<programlisting>
$view->jQuery()
->setRenderMode(ZendX_JQuery::RENDER_JAVASCRIPT |
ZendX_JQuery::RENDER_JQUERY_ON_LOAD);
</programlisting>
<para>This statement makes sure only the required javascript statements and onLoad blocks of the current page are rendered by the jQuery helper.</para>
</sect3>
<sect3>
<title>Migrations</title>
<para>Prior to 1.8 the methods <methodname>setCdnVersion()</methodname>, <methodname>setLocalPath()</methodname>
<methodname>setUiCdnVersion()</methodname> and <methodname>setUiLocalPath()</methodname> all enabled the view
helper upon calling, which is considered a bug from the following perspective: If
you want to use the any non-default library option, you would have to manually disable the
jQuery helper aftwards if you only require it to be loaded in some scenarios. With version
1.8 the jQuery helper does only enable itsself, when <methodname>enable()</methodname> is called,
which all internal jQuery View helpers do upon being called.
</para>
</sect3>
</sect2>
<sect2>
<title>JQuery Helpers</title>
<sect3>
<title>AjaxLink Helper</title>
<para>The AjaxLink helper uses jQuery's ajax capabilities to offer the creation of links that do ajax requests and
inject the response into a chosen DOM element. It also offers the possibility to append simple jQuery effects
to both the link and the response DOM element. A simple example introduces its functionality:</para>
<programlisting>

<?php echo $this->view->ajaxLink("Link Name",
"url.php",
array('update' => '#container')); ?>
</programlisting>
<para>This example creates a link with the label "Link Name" that fires an ajax request to url.php
upon click and renders the response into the div container "#container". The function header
for the ajaxLink is as follows: function ajaxLink($label, $url, $options, $params);
The options array is very powerful and offers you lots of functionality to customize your
ajax requests.</para>
<para>Available options are:</para>

<title>AjaxLink options</title>
<tgroup>

<row>
<entry>Option</entry>
<entry>Data Type</entry>
<entry>Default Value</entry>
<entry>Description</entry>
</row>

<row>
<entry>update</entry>
<entry>string</entry>
<entry>false</entry>
<entry>
Container to inject response content into, use jQuery CSS Selector syntax, ie. "#container" or ".box"
</entry>
</row>
<row>
<entry>method</entry>
<entry>string</entry>
<entry>Implicit GET or POST</entry>
<entry>Request method, is implicitly chosen as GET when no parameters given and POST when parameters given.</entry>
</row>
<row>
<entry>complete</entry>
<entry>string</entry>
<entry>false</entry>
<entry>Javascript callback executed, when ajax request is complete. This option allows for shortcut effects, see next section.</entry>
</row>
<row>
<entry>beforeSend</entry>
<entry>string</entry>
<entry>false</entry>
<entry>Javascript callback executed right before ajax request is started. This option allows for shortcut effects, see next section.</entry>
</row>
<row>
<entry>noscript</entry>
<entry>boolean</entry>
<entry>true</entry>
<entry>If true the link generated will contain a href attribute to the given link for non-javascript enabled browsers. If false href will resolve to "#".</entry>
</row>
<row>
<entry>dataType</entry>
<entry>string</entry>
<entry>html</entry>
<entry>What type of data is the Ajax Response of? Possible are Html, Text, Json. Processing Json responses has to be done with custom "complete" callback functions.</entry>
</row>
<row>
<entry>attribs</entry>
<entry>array</entry>
<entry>null</entry>
<entry>Additional HTML attributes the ajaxable link should have.</entry>
</row>
<row>
<entry>title, id, class</entry>
<entry>string</entry>
<entry>false</entry>
<entry>Convenience shortcuts for HTML Attributes.</entry>
</row>
<row>
<entry>inline</entry>
<entry>boolean</entry>
<entry>false</entry>
<entry>Although far from best practice, you can set javascript for this link inline in "onclick" attribute.</entry>
</row>

</tgroup>

<para>To enlighten the usage of this helper it is best to show another bunch of more complex examples. This
example assumes that you have only one view object that you want to display and don't care a lot about
html best practices, since we have to output the jQuery environment just before the closing body tag.</para>
<programlisting>

<title>Zend Framework jQuery AjaxLink Example</title>

<?php echo $this->ajaxLink("Example 1",
"/ctrl/action1",
array('update' => '#content',
'noscript' => false,
'method' => 'POST')); ?>

<?php echo $this->ajaxLink("Example 2",
"/ctrl/action2",
array('update' => '#content',
'class' => 'someLink'),
array('param1' => 'value1',
'param2' => 'value2')); ?>

<?php echo $this->ajaxLink("Example 3",
"/ctrl/action3",
array('dataType' => 'json',
'complete' =>
'alert(data)')); ?>

<?php echo $this->ajaxLink("Example 4",
"/ctrl/action4",
array('beforeSend' => 'hide',
'complete' => 'show')); ?>

<?php echo $this->ajaxLink("Example 5",
"/ctrl/action5",
array(
'beforeSend' =>
'myBeforeSendCallbackJsFunc();',
'complete' =>
'myCompleteCallbackJsFunc(data);')
); ?>

<?php echo $this->jQuery(); ?>

</programlisting>
<para>You might have already seen that the 'update', 'complete', and 'beforeSend' options have to be executed in specific order and syntax so that you cannot
use those callbacks and override their behaviour completely when you are using <methodname>ajaxLink()</methodname>. For larger use cases you will probably want to
write the request via jQuery on your own. The primary use case for the callbacks is effect usage, other uses may very well become hard to maintain.
As shown in Example Link 5, you can also forward the beforeSend/complete Callbacks to your own javascript functions.</para>
<sect4>
<title>Shortcut Effects</title>
<para>You can use shortcut effect names to make your links actions more fancy. For example the Container that will contain
the ajax response may very well be invisible in the first place. Additionally you can use shortcut effects on the link
to hide it after clicking. The following effects can be used for callbacks:</para>
<itemizedlist>
<listitem><para>complete callback: 'show', 'showslow', 'shownormal', 'showfast', 'fadein', 'fadeinslow',
'fadeinfast', 'slidedown', 'slidedownslow', 'slidedownfast'. These all correspond to the jQuery effects
fadeIn(), show() and slideDown() and will be executed on the container specified in update.</para></listitem>
<listitem><para>beforeSend callback: 'fadeout', 'fadeoutslow', 'fadeoutfast', 'hide',
'hideslow', 'hidefast', 'slideup'. These correspond to the jQuery effects fadeOut(), hide(), slideUp() and
are executed on the clicked link.</para></listitem>
</itemizedlist>
<programlisting>
<?php echo $this->ajaxLink("Example 6",
"/ctrl/action6",
array('beforeSend' => 'hide',
'complete' => 'show')); ?>
</programlisting>
</sect4>
</sect3>
<sect3>
<title>jQuery UI Library Helpers</title>
<para>The jQuery UI Library offers a range of layout and form specific widgets that are integrated into the
Zend Framework via View Helpers. The form-elements are easy to handle and will be described first, whereas
the layout specific widgets are a bit more complex to use.</para>
<sect4>
<title>jQuery UI Form Helpers</title>
<para>The method signature for all form view helpers closely resembles the Dojo View helpers signature,
<methodname>helper($id, $value, $params, $attribs)</methodname>. A description of the parameters follows:</para>
<itemizedlist>
<listitem><para><varname>$id</varname>: Will act as the identifier name for the helper element inside a form. If in the attributes
no id element is given, this will also become the form element id, that has to be unique across
the DOM.</para></listitem>
<listitem><para><varname>$value</varname>: Default value of the element.</para></listitem>
<listitem><para><varname>$params</varname>: Widget specific parameters that customize the look and feel
of the widget. These options are unique to each widget and <ulink>
described in the jQuery UI documentation</ulink>. The data is casted to JSON, so make sure
to use the <classname>Zend_Json_Expr</classname> class to mark executable javascript as safe.</para></listitem>
<listitem><para><varname>$attribs</varname>: HTML Attributes of the Form Helper</para></listitem>
</itemizedlist>
<para>The following UI widgets are available as form view helpers. Make sure you use the correct
version of jQuery UI library to be able to use them. The Google CDN always offers you the latest
released version.</para>
<itemizedlist>
<listitem><para><methodname>autoComplete($id, $value, $params, $attribs)</methodname>: The AutoComplete View helper
is part of jQuery UI since version 1.8 and creates a text field and registeres
it to have auto complete functionality. The completion data source has to be given as jQuery
related parameters 'url' or 'data' as described in the jQuery UI manual.
</para></listitem>
<listitem><para><methodname>colorPicker($id, $value, $params, $attribs)</methodname>: ColorPicker is still
a ZendX_JQuery element for legacy reason, but was removed from jQuery UI completly.
</para></listitem>
<listitem><para><methodname>datePicker($id, $value, $params, $attribs)</methodname>: Create a DatePicker
inside a text field. This widget is available since jQuery UI 1.5 and can therefore currently be used
with the Google CDN. Using the 'handles' option to create multiple handles overwrites the default set value
and the jQuery parameter 'startValue' internally inside the view helper.</para></listitem>
<listitem><para><methodname>slider($id, $value, $params, $attribs)</methodname>: Create a Sliding element
that updates its value into a hidden form field. Available since jQuery UI 1.5.</para></listitem>
<listitem><para><methodname>spinner($id, $value, $params, $attribs)</methodname>: Create a Spinner element
that can spin through numeric values in a specified range. This element was removed from
the 1.6 jQuery UI release and has not been re-released yet.</para></listitem>
</itemizedlist>
<example>
<title>Showing jQuery Form View Helper Usage</title>
<para>In this example we want to simulate a fictional web application that offers auctions
on travel locations. A user may specify a city to travel, a start and end date, and a
maximum amount of money he is willing to pay. Therefore we need an autoComplete field
for all the currently known travel locations, a date picker for start and end dates
and a spinner to specify the amount.</para>
<programlisting>
<form method="post" action="bid.php">
Where do you want to travel?
<?php echo $this->autoComplete("location",
"",
array('source' => array('New York',
'Mexico City',
'Sydney',
'Ruegen',
'Baden Baden'))); ?>

Travel Start Date:
<?php echo $this->datePicker("startDate", '',
array(
'defaultDate' => '+7',
'minDate' => '+7',
'onClose' => new Zend_Json_Expr('myJsonFuncCechkingValidity'))); ?>

Travel End Date:
<?php echo $this->datePicker("endDate", '',
array(
'defaultDate' => '+14',
'minDate' => '+7',
'onClose' => new Zend_Json_Expr('myJsonFuncCechkingValidity'))); ?>

Your Bid:
<?php echo $this->spinner("bid",
"",
array('min' => 1205.50,
'max' => 10000,
'start' => 1205.50,
'currency' => '€')); ?>

<input type="submit" value="Bid!" />
</form>
</programlisting>
<para>You can see the use of jQuery UI Widget specific parameters. These all correspond to those given in the jQuery UI docs
and are converted to JSON and handed through to the view script.</para>
</example>
</sect4>
<sect4>
<title>Using an Action Helper to Send Data to AutoComplete</title>
<para>The jQuery UI Autocomplete Widget can load data from a remote location
rather than from an javascript array, making its usage really useful. Zend
Framework currently providers a bunch of server-side AutoComplete
Helpers and there is one for jQuery too. You register the helper
to the controller helper broker and it takes care of disabling layouts
and renders an array of data correctly to be read by the AutoComplete field.
To use the Action Helper you have to put this rather long statement into
your bootstrap or Controller initialization function:
</para>
<programlisting>
Zend_Controller_Action_HelperBroker::addHelper(
new ZendX_JQuery_Controller_Action_Helper_AutoComplete()
);
</programlisting>
<para>You can then directly call the helper to render AutoComplete Output in
your Controller</para>
<programlisting>
class MyIndexController extends Zend_Controller_Action
{
public function autocompleteAction()
{
// The data sent via the ajax call is inside $_GET['q']
$filter = $_GET['q'];
// Disable Layout and stuff, just displaying AutoComplete Information.
$this->_helper->autoComplete(array("New York", "Bonn", "Tokio"));
}
}
</programlisting>
</sect4>
<sect4>
<title>jQuery UI Layout Helpers</title>
<para>There is a wide range of Layout helpers that the UI library offers. The ones covered by Zend Framework view helpers are
Accordion, Dialog, Tabs. Dialog is the most simple one, whereas Accordion and Tab extend a common abstract class and
offer a secondary view helper for pane generation. The following view helpers exist in the jQuery view helpers collection,
an example accompanies them to show their usage.</para>
<itemizedlist>
<listitem><para><methodname>dialogContainer($id, $content, $params, $attribs)</methodname>: Create a Dialog Box that is rendered with
the given content.on startup. If the option 'autoOpen' set to false is specified the box will not be displayed
on load but can be shown with the additional <methodname>dialog("open")</methodname> javascript function. See UI docs
for details.</para></listitem>
<listitem><para><methodname>tabPane($id, $content, $options)</methodname>: Add a new pane to a tab container with the given <varname>$id</varname>.
The given <varname>$content</varname> is shown in this tab pane. To set the title use <varname>$options['title']</varname>.
If <varname>$options['contentUrl']</varname> is set, the content of the tab is requested via ajax on tab activation.
</para></listitem>
<listitem><para><methodname>tabContainer($id, $params, $attribs)</methodname>: Render a tab container with all the currently registered
panes. This view helper also offers to add panes with the following syntax:
$this->tabContainer()->addPane($id, $label, $content, $options).
</para></listitem>
<listitem><para><methodname>accordionPane($id, $content, $options)</methodname>: Add a new pane to the accordion container with the given <varname>$id</varname>.
The given <varname>$content</varname> is shown in this tab pane. To set the title use <varname>$options['title']</varname>.
</para></listitem>
<listitem><para><methodname>accordionContainer($id, $params, $attribs)</methodname>: Render an accordion container with all the currently registered
panes. This view helper also offers to add panes with the following syntax:
$this->accordionContainer()->addPane($id, $label, $content, $options).
</para></listitem>
</itemizedlist>
<example>
<title>Showing the latest news in a Tab Container</title>
<para>For this example we assume the developer already wrote the controller and model side of the script and assigned
an array of news items to the view script. This array contains at most 5 news elements, so we don't have to care
about the tab container getting to many tabs.</para>
<programlisting>
<?php foreach($this->news AS $article): ?>
<?php $this->tabPane("newstab",
$article->body,
array('title' => $article->title)); ?>
<?php endforeach; ?>

Latest News

<?php echo $this->tabContainer("newstab",
array(),
array('class' => 'flora')); ?>
</programlisting>
</example>
</sect4>
</sect3>
</sect2>
</sect1><sect1>
<title>ZendX_JQuery Form Elements and Decorators</title>
<para>All View Helpers are pressed into Zend_Form elements or decorators also. They can even be
easily integrated into your already existing forms. To enable a Form for Zend_JQuery support
you can use two ways: Init your form as $form = new ZendX_JQuery_Form(); or
use the static method <methodname>ZendX_JQuery::enableForm($form)</methodname> to enable jQuery element support.
</para>
<sect2>
<title>General Elements and Decorator Usage</title>
<para>Both elements and decorators of the Zend jQuery Form set can be initialized with
the option key jQueryParams to set certain jQuery object related parameters.
This jQueryParams array of options matches to the <varname>$params</varname> variable
of the corresponding view helpers. For example:</para>
<programlisting>
$element = new ZendX_JQuery_Form_Element_DatePicker(
'dp1',
array('jQueryParams' => array('defaultDate' => '2007/10/10'))
);
// would internally call to:
$view->datePicker("dp1", "", array('defaultDate' => '2007/10/10'), array());
</programlisting>
<para>Additionally elements jQuery options can be customized by the following methods:</para>
<itemizedlist>
<listitem><para><methodname>setJQueryParam($name, $value)</methodname>: Set the jQuery option <varname>$name</varname> to
the given value.</para></listitem>
<listitem><para><methodname>setJQueryParams($params)</methodname>: Set key value pairs of jQuery options and merge
them with the already set options.</para></listitem>
<listitem><para><methodname>getJQueryParam($name)</methodname>: Return the jQuery option with the given name.</para></listitem>
<listitem><para><methodname>getJQueryParams()</methodname>: Return an array of all currently set jQuery options.</para></listitem>
</itemizedlist>
<para>Each jQuery related Decorator also owns a <methodname>getJQueryParams()</methodname> method, to set options you have to
use the <methodname>setDecorators()</methodname>, <methodname>addDecorator()</methodname> or <methodname>addDecorators()</methodname> functionality
of a form element and set the jQueryParams key as option:</para>
<programlisting>
$form->setDecorators(array(
'FormElements',
array('AccordionContainer', array(
'id' => 'tabContainer',
'style' => 'width: 600px;',
'jQueryParams' => array(
'alwaysOpen' => false,
'animated' => "easeslide"
),
)),
'Form'
));
</programlisting>
</sect2>
<sect2>
<title>Form Elements</title>
<para>The Zend Framework jQuery Extras Extension comes with the following Form Elements:</para>
<itemizedlist>
<listitem><para>ZendX_JQuery_Form_Element_AutoComplete: Proxy to AutoComplete View Helper</para></listitem>
<listitem><para>ZendX_JQuery_Form_Element_ColorPicker: Proxy to ColorPicker View Helper</para></listitem>
<listitem><para>ZendX_JQuery_Form_Element_DatePicker: Proxy to DatePicker View Helper</para></listitem>
<listitem><para>ZendX_JQuery_Form_Element_Slider: Proxy to Slider View Helper</para></listitem>
<listitem><para>ZendX_JQuery_Form_Element_Spinner: Proxy to Spinner View Helper</para></listitem>
</itemizedlist>
<note>
<title>jQuery Decorators: Beware the Marker Interface for UiWidgetElements</title>
<para>By default all the jQuery Form elements use the ZendX_JQuery_Form_Decorator_UiWidgetElement decorator
for rendering the jQuery element with its specific view helper. This decorator is inheritly different
from the ViewHelper decorator that is used for most of the default form elements in Zend_Form.
To ensure that rendering works correctly for jQuery form elements at least one decorator has to
implement the ZendX_JQuery_Form_Decorator_UiWidgetElementMarker interface, which
the default decorator does. If no marker interface is found an exception is thrown. Use the marker
interface if you want to implement your own decorator for the jQuery form element specific rendering.
</para>
</note>
</sect2>
<sect2>
<title>Form Decorators</title>
<para>The following Decorators come with the Zend Framework jQuery Extension:</para>
<itemizedlist>
<listitem><para>ZendX_JQuery_Form_Decorator_AccordionContainer: Proxy to AccordionContainer View Helper</para></listitem>
<listitem><para>ZendX_JQuery_Form_Decorator_AccordionPane: Proxy to AccordionPane View Helper</para></listitem>
<listitem><para>ZendX_JQuery_Form_Decorator_DialogContainer: Proxy to DialogContainer View Helper</para></listitem>
<listitem><para>ZendX_JQuery_Form_Decorator_TabContainer: Proxy to TabContainer View Helper</para></listitem>
<listitem><para>ZendX_JQuery_Form_Decorator_TabPane: Proxy to TabPane View Helper</para></listitem>
<listitem><para>ZendX_JQuery_Form_Decorator_UiWidgetElement: Decorator to Display jQuery Form Elements</para></listitem>
</itemizedlist>
<para>Utilizing the Container elements is a bit more complicated, the following example builds a Form with 2 SubForms in a TabContainer:</para>
<example>
<title>SubForms with TabContainer Decorator</title>
<para>The following example makes use of all Form elements and wraps them into 2 subforms that are decorated with a tab container. First
we build the basic ZendX_JQuery_Form:</para>
<programlisting>
$form = new ZendX_JQuery_Form();
$form->setAction('formdemo.php');
$form->setAttrib('id', 'mainForm');
$form->setAttrib('class', 'flora');
$form->setDecorators(array(
'FormElements',
array('TabContainer', array(
'id' => 'tabContainer',
'style' => 'width: 600px;',
)),
'Form',
));
</programlisting>
<para>Setting the Form Id (in this case to 'mainForm') is an important step for the TabContainer. It is needed that the subforms can relate
to the Container Id in a later form building stage. We now initialize two SubForms that will be decorated with the TabPane
decorators:</para>
<programlisting>
$subForm1 = new ZendX_JQuery_Form();
$subForm1->setDecorators(array(
'FormElements',
array('HtmlTag',
array('tag' => 'dl')),
array('TabPane',
array('jQueryParams' => array('containerId' => 'mainForm',
'title' => 'DatePicker and Slider')))
));
$subForm2 = new ZendX_JQuery_Form();
$subForm2->setDecorators(array(
'FormElements',
array('HtmlTag',
array('tag' => 'dl')),
array('TabPane',
array('jQueryParams' => array('containerId' => 'mainForm',
'title' => 'AutoComplete and Spinner')))
));
</programlisting>
<para>In this stage it is important that the 'containerId' option is set in each SubForm TabPane, or the subforms
cannot relate back to the tab Container and would not be displayed. To enforce this setting, an exception of the type ZendX_JQuery_Exception
is thrown if the option is not set. We can now add all the desired elements to the subforms:</para>
<programlisting>
// Add Element Date Picker
$elem = new ZendX_JQuery_Form_Element_DatePicker(
"datePicker1", array("label" => "Date Picker:")
);
$elem->setJQueryParam('dateFormat', 'dd.mm.yy');
$subForm1->addElement($elem);
// Add Element Spinner
$elem = new ZendX_JQuery_Form_Element_Spinner(
"spinner1", array('label' => 'Spinner:')
);
$elem->setJQueryParams(array('min' => 0, 'max' => 1000, 'start' => 100));
$subForm1->addElement($elem);
// Add Slider Element
$elem = new ZendX_JQuery_Form_Element_Slider(
"slider1", array('label' => 'Slider:')
);
$elem->setJQueryParams(array('defaultValue' => '75'));
$subForm2->addElement($elem);
// Add Autocomplete Element
$elem = new ZendX_JQuery_Form_Element_AutoComplete(
"ac1", array('label' => 'Autocomplete:')
);
$elem->setJQueryParams(array('source' => array('New York',
'Berlin',
'Bern',
'Boston')));
$subForm2->addElement($elem);
// Submit Button
$elem = new Zend_Form_Element_Submit("btn1", array('value' => 'Submit'));
$subForm1->addElement($elem);
</programlisting>
<para>Three additional lines are missing to put it all together and we have a jQuery animated form:</para>
<programlisting>
$form->addSubForm($subForm1, 'subform1');
$form->addSubForm($subForm2, 'subform2');
$formString = $form->render($view);
</programlisting>
</example>
<example>
<title>Wrapping a Form into the Dialog Container</title>
<para>The only use for the Dialog Container in Zend Form context is to wrap itself around a form and
display it in a dialog. Its important to remember that the order of the decorators has to be different than in the Accordion and
Tab Container examples.</para>
<programlisting>
// Create new jQuery Form
$form = new ZendX_JQuery_Form();
$form->setAction('formdemo.php');
// Wrap the complete form inside a Dialog box
$form->setDecorators(array(
'FormElements',
'Form',
array('DialogContainer', array(
'id' => 'tabContainer',
'style' => 'width: 600px;',
'jQueryParams' => array(
'tabPosition' => 'top'
),
)),
));
// Add Element Spinner
$elem = new ZendX_JQuery_Form_Element_Spinner("spinner1", array('label' => 'Spinner:', 'attribs' => array('class' => 'flora')));
$elem->setJQueryParams(array('min' => 0, 'max' => 1000, 'start' => 100));
$form->addElement($elem);
</programlisting>
</example>
</sect2>
</sect1>


CommandT not dynamically filtering file list when typing
-
anonymous
Just an FYI, but in case CommandT doesn't seem to be responding when you type characters to filter the list of candidate files, it might be because you didn't install using the system ruby interpreter. I use rvm for my local account and forgot to switch to the system ruby while installing CommandT. A quick repeat of the install using the system ruby fixed this.
Reply
This topic is now closed.


Gov’t spends GH¢840 million on NaBCo beneficiaries
by Godwill Arthur-Mensah, GNAAccra, Nov. 13, GNA - Government has spent GH¢840 million on 97,373 beneficiaries recruited under the Nation Builders Corps (NaBCO), which is an initiative to reduce graduate unemployment in the country.
Additionally, 7,500 sheep has been supplied to farmers in the Upper West, Northern and Oti Regions, while 30,000 cockerels were distributed to 3,000 farmers in the Upper West, Eastern, Ashanti, Northern and Greater Accra Regions under the Rearing for Food and Jobs programme.
Mr Ken Ofori-Atta, the Finance Minister, who made this known when he presented the 2020 Budget Statement to Parliament in Accra on Wednesday, said Government was spending GH¢2.2 billion this academic year on 1.2 million students under the Free Senior High School Policy.
The presentation of the Budget is in accordance with Article 179 of the 1992 Constitution, which required the Government to present its financial policy plan for the next fiscal year to Parliament for consideration and subsequent approval.
On railway development, Mr Ofori-Atta said government had completed Accra-Tema Suburban, Kojokrom-Tarkwa and Achimota-Nsawam rail lines while the old Railway Training School and two workshops located at Essikado and Sekondi had received major refurbishments and facelift.
GNA


Pearson product-moment coefficient of linear correlation
Pearson’s indicates the strength and direction of the linear relationship between two time series and , which have to be normally distributed.
is the ratio of the covariance to the product of the two standard deviations .
Interpretation
The result of Pearson’s is a dimensionless number between -1 and 1.
The sign of indicates the direction, whereas the magnitude of indicates the strength of the relationship between and .
Pearson’s has to be interpreted as follows:
A very strong linear relationship between and exists. increases as increases.
: No linear relationship between and exists. does not increase or decrease as increases.
: A very strong negative linear relationship between and exists. increases as decreases.
Pearson’s provides results for linear relationship between two variables. It does not provide any causal relationship between two variables.
It is not resistant since it is very sensitive to outliers, nor is it robust, because nonlinear relationships are not recognized.


|
Coat of arms of Pritchard (left) displaying Veneti symbols; reverse of Walkenline de Ferrers’ coat of arms (right), father of Henri de Ferres Breton-Norman-English ancestry who will eventually take the name of Wilson. Both Pritchard and Wilson are related before 500 AD [Both are from the same branch of R1b-L513]. Pritchard coat of arms source: Englishgathering.co.uk and de Ferrers’ Source: C ommons.wikimedia.org
According to Welsh studies another Dáirine kingdom is Dyfed where King Tryffin Ab Aled Brosc resides around 500 AD. Brosc’s lineage (according to Wales Genealogy records) produces the family name of Phillips [R1b-L513]. Phillips families are directly related to House of Aubigny of Brittany which develop Breton surnames.
Phillips (Welsh) D’Aubigny (Breton)
(Pillips source: Heritage Registry Genealogy; D’Aubigny source: CC BY-SA 4.0 )
Padarn then encounters the Venicones of North Wales. Padarn is not able to convert King Owain Ddantgwyn (Whitetooth) of Gwynedd to Christianity, but he is allowed to enroll Prince Maelgwyn to Cor Tewdws. Maelgwyn is named directly in Life of St. Padarn (and spelt “Maelgwn”) as the next King of the Northern Britons. Owain’s wife is Guenevere Lodegreaunce. Maelgwyn is also associated with the Arthur legend.
In Padarn’s story, he travels to the land of Agam’s Cross where he overcomes Graban (as it is spelt). This perhaps refers to Dál Riata King Gabrán mac Domangairt in what is now County Antrim, Ireland. FTDNA Clan Donald’s Mark MacDonald first identified R1b-L513 as Dalriada signatures. This group established the Scottish kingdom of Dalriada in 470 AD. About a third of 400 family names have been identified as R1b-L513 Dalriadan.
Left; Ferguson crest, one of many Dál Riata R1b-L513 families. Note Veneti symbols at the base of the crown. Right; Dalriada flag represented in both Clans Campbell and MacMhathain (Matheson) [both R1b-L513]. Sources: Scotsconnection.com
Another name from Padarn’s tale, Terillan, is found in Irish Annals as King Tighearnán Sea llachan who is from a north- |


Latitude
Comparisons
Data
Plots
Temperature
Cloudiness
Humidity
Wind Speed
Comparisons: Latitude vs. X
Click on a plot to get an in-depth analysis
vs. Max Temperature
vs. Humidity
vs. Cloudiness
vs. Wind Speed


Repair Reports
exprTest...
moduleTest...
scriptTest...
AMD loader test...
Using
unknown
unknown
on
unknown


Door to Port (ORIGIN ZIP CODE), Port to port (PCS, WEIGHT LBS OR KGS, CBM OR CBF)
Door to Port / Port to Port
Dimesion
*Required Fields


Above the clouds, on a mission to provide the development tools of tomorrow with a powerful production team.
Our team is online 24/7 for your enquiries.
Our systems provide the user with full control over any operation.
Locks down the core features of your device to fend off malware.
Our services are OSA approved and are living on GitHub.
We publish our service specification and advertisement drafts for public reference.


An Open Data Story
by Paul Baker
Dec 1, 2011 – In almost all open data projects, providing raw data is not enough. And it’s not enough to be a good programmer or designer. To be useful, we need to be able to figure out what questions the data might reveal and which of these might be useful for the public to know.
The data
In early July 2011, the City of Chicago released 14 sets of lobbying-related data, including lobbyists, lobbying agencies, gifts to city employees, expenditures, clients of lobbyists, etc. However, an ordinary human being could not make heads or tails of this without some sort of integration.
That’s why we built ChicagoLobbyists.org.
Chicago Lobbyists v1.0
First, we went through each data set, attempting to draw relationships among them by looking for common fields such as clients, lobbying firms, and individual lobbyists. Our goal was to reveal answers to questions such as, “WalMart paid which lobbyist, with which lobbying firm, how much money, to argue on their behalf in front of which department or committee, and for what purpose?”
We soon found out that we couldn’t answer that question. In the above example, we could show which lobbyists Walmart paid, which firm the lobbyist worked for, and which city agencies the lobbyist appeared before, but not which tasks lobbyists were hired to do for WalMart.
Meeting with the City
After the July Google hackathon, at which we built and launched the site, we met with the city’s Chief Data Officer, Brett Goldstein, and some IT staff, and asked:
- Is there a way to determine compensation that comes to a firm versus lobbyist? (We can’t be sure adding up compensation of all lobbyists within a firm is accurate.)
- Is there a way to determine how much a client paid to a lobbying firm or lobbyist?
- Related to the question above, can we retrieve the purpose for a client payment?
- Can we receive data before 2010? If so, what years are available?
- Is there a way to determine which client requested an action in front of an agency? We only know which lobbyist requested an action—see example: Theodore Brunsvold
- Are street addresses available for lobbying firms (some give political donations from many different addresses)?
- Do you have a good state contact from which we could request political donation data?
- Is there a list of all city datasets available (besides those on Socrata)?
- Is there a schedule of when particular datasets are updated (frequency, time period)?
The City responds with updated data
By late August, Brett’s team had collected and posted the data that we had requested. Now, we are able to incorporate the new data and change the site’s design to show more detailed and new views (these changes are coming in the next day or so – stay tuned). Now we can answer most of the important questions.
Next steps …
Our next steps are to incorporate political donations to city officials by lobbyists and organizations. It would also be good to show how elected officials voted on issues of interest to lobbyists who have donated to them and their clients.
The entire 2012 city budget is about $3 billion—all of it paid by residents. Fees paid to lobbyists to influence government decisions will probably be in the neighborhood of $13 million, or about .4% of $3 billion.
We’re the 99.6%. Lobbyists paid by organizations are .4%. Are lobbyists the tail that wags the dog?
blog comments powered by Disqus
An open process
In the spirit of openness, the goal of this blog is to share our milestones, setbacks and thoughts as we continue to develop and expand this project.
Who are we?
We are Open City, a group of developers and designers based in Chicago that build civic-minded apps using open data.
- Paul Baker
- President and co-founder of Webitects
- Derek Eder
- Developer at Webitects and organizer for OpenGov Chicago
- Chad W Pry
- Engineer at Groupon, Code Academy mentor, and all around charming fellow
- Nick Rougeux
- Designer and CSS wiz at Webitects


11
Yacc
Theory
Grammars for yacc are described using a variant of Backus Naur Form (BNF). This technique,
pioneered by John Backus and Peter Naur, was used to describe ALGOL60. A BNF grammar can
be used to express
context-free
languages. Most constructs in modern programming languages
can be represented in BNF. For example, the grammar for an expression that multiplies and adds
numbers is
E -> E + E
E -> E * E
E -> id
Three productions have been specified. Terms that appear on the left-hand side (lhs) of a
production, such as
E
(expression) are nonterminals. Terms such as
id
(identifier) are terminals
(tokens returned by lex) and only appear on the right-hand side (rhs) of a production. This grammar
specifies that an expression may be the sum of two expressions, the product of two expressions,
or an identifier. We can use this grammar to generate expressions:
E -> E * E (r2)
-> E * z (r3)
-> E + E * z
(r1)
-> E + y * z
(r3)
-> x + y * z
(r3)
At each step we expanded a term and replace the lhs of a production with the corresponding rhs.
The numbers on the right indicate which rule applied. To parse an expression we need to do the
reverse operation. Instead of starting with a single nonterminal (start symbol) and generating an
expression from a grammar we need to reduce an expression to a single nonterminal. This is known
as
bottom-up
or
shift-reduce
parsing and uses a stack for storing terms. Here is the same derivation
but in reverse order:
1 . x + y * z shift
2 x . + y * z reduce(r3)
3 E . + y * z shift
4 E + . y * z shift
5 E + y . * z reduce(r3)
6 E + E . * z shift
7 E + E * . z shift
8 E + E * z . reduce(r3)
9 E + E * E . reduce(r2) emit multiply
10 E + E . reduce(r1) emit add
11 E . accept
Terms to the left of the dot are on the stack while remaining input is to the right of the dot. We start
by shifting tokens onto the stack. When the top of the stack matches the rhs of a production we
replace the matched tokens on the stack with the lhs of the production. In other words the matched
tokens of the rhs are popped off the stack, and the lhs of the production is pushed on the stack.
The matched tokens are known as a
handle
and we are
reducing
the handle to the lhs of the
production. This process continues until we have shifted all input to the stack and only the starting
nonterminal remains on the stack. In step 1 we shift the
x
to the stack. Step 2 applies rule r3 to the
stack to change
x
to
E
. We continue shifting and reducing until a single nonterminal, the start
symbol, remains in the stack. In step 9, when we reduce rule r2, we emit the multiply instruction.


Filters can be used for the $set_filter()
and $add_filter()
methods of
Appenders and Loggers. You normally do not need to construct a formal
EventFilter
object, you can just use any function
that has the single
argument event
or any object that has a filter
method.
The base class for Filters is called EventFilter
so that it doesn't
conflict with base::Filter()
. The recommended convention for Filter
subclasses is to call them FilterSomething
and leave out the
Event
prefix.
Since LogEvents are R6 objects with reference semantics, Filters can also be abused to modify log events before passing them on. lgr comes with a few preset filters that use this property:
FilterInject$new(..., .list)
...
and .list
can take any number
of named R6 objects that will be injected as custom fields into all
LogEvents processed by the Appender/Logger that this filter is attached
to. See also with_log_value()
FilterForceLevel$new(level)
Sets the level of all LogEvents
processed by the Appender/Logger that this filter is attached to to
level
. See also with_log_value()
You can use the special function .obj()
to access the calling
Logger/Appender from within a filter
# using filters to modify log events analyse <- function(){ lgr$add_filter(FilterForceLevel$new("info"), "force") lgr$add_filter(FilterInject$new(type = "analysis"), "inject") on.exit(lgr$remove_filter(c("force", "inject"))) lgr$debug("a debug message") lgr$error("an error") } analyse()#> INFO [12:43:05.961] a debug message {type: analysis} #> INFO [12:43:05.964] an error {type: analysis}lgr$error("an error")#> ERROR [12:43:05.972] an error# using .obj() l <- Logger$new("foo", threshold = "debug") f <- function(event) { cat("via event$.logger:", event$.logger$threshold, "\n") # works for loggers only cat("via .obj(): ",.obj()$threshold, "\n") # works for loggers and appenders TRUE } l$add_filter(f) l$fatal("test")#> via event$.logger: 500 #> via .obj(): 500 #> FATAL [12:43:05.979] test


I'm a creative problem solver with excellent communication and technical skills. With over 9+ years of experience in the financial sector. Passionate about learning new technologies. Knowledgeable in structured programming techniques using Java. Able to effectively interface with clients and collaborate with team members and management to provide clear direction for accomplishing objectives.
For more information about my professional experience, please visit my LinkedIn page below:
LinkedIn ProfileRyerson University 2019 Capstone Design Project Silver Excellence Award Winner
Computer Engineering
Class of 2019
The computer engineering program focused on developing technical skills. We designed and built software for various computer systems. In addition, developed firmware, created system-level and user application-level software. Capstone Project Silver Excellence Award winner.
International Business Administration
Class of 2008
The International Business program focused on collaborative, project based learning, case analysis and in–class discussions, all essential critical thinking skills. We completed the process of exporting and importing a product and culminating in the development of an international business plan.
This health and wellness blog will inspire you to cook at home and try healthy recipes. The goal is to keep you well informed about the latest health and nutrition trends, this way you can stay healthy and feel your best. This webapp is currently in the design phase.
ATC is committed to find their clients the property they are looking for fast. Focused on providing quality real estate services and investment opportunities. The website provides an interactive dashboard for properties clients are interested in. The client can find their next home quickly or inquire about various properties within the site. This webapp is in the development phase, using Python 3.0 with Django frameworks and PostgresSQL Database.
Accurate Table Retrieval from Unstructured Sources Project. The main objective of this project was to implement a technique that is capable of efficient table retrieval from a user query. The focus was to study the work of “Ad Hoc Table Retrieval using Semantic Similarity” by authors Shuo Zhang and Krisztian Balog, and propose additional improvements. The work comprised of semantic matching done with three main feature categories, table, query and table-query features.
Project LinkEveryday Heroes Kids, connects families with all pediatric professionals, encouraging earlier intervention for better outcomes in kids. This project launched the landing page and created the neccessary frameworks for the development of the the application.
Project Link


Parametric Furniture Design and Fabrication for Urban Homes Role : Founder/CEO Collaborators : Amit Nambiar
O-LAP was a startup venture in operation between 2013-2015 with focus on design, research and fabrication of parametric products. Parametric design is the design of a product based on computation of different parameters associated with the product. A number of methods in design of products as well as design of spaces in urban homes were explored. The design was done mainly keeping in mind a person living in a metropolitan city. The venture won a number of recognitions and awards mentioned at the end of this article.
O-LAP featured at TEDx Gateway
Parametric Design
The concept was based on the idea of mass manufacturing and mass customization. If a product (in this case a furniture product) had to be truly customized, it had to take into consideration the exact user that was going to use it. For the same we created a system that took in parameters of the user like age, inclination and weight. The system then converted these values into a design of a furniture product with its fabrication parts made for the exact user; i.e. mass customization. These parts would later be assembled by the user himself


University of Southern California
Designed by Yuan Ma and Qingqing Zheng
This is the final project for EE579, Wireless and Mobile Networks Design and Laboratory, 2016 Spring. Special thanks to Professor Bhaskar Krishnamachari, TA Pradipta Ghosh and WigWag company.
This project is the interaction of visual art and computer technology. We apply the characteristics of music to the characteristics of filament and call dev$ APIs to control the color and brightness of filament(s). This project can be used as a start point for a music fountain or a prototype for smart home.
There are two parallel process: one is for detectiing frequency and another is for controlling the filaments laid on deviceJS. After reading Muaic.wav file, do the fft transform, then we get the music frequency and amplitude. once we get those, we write them into the outputfile. For the other process, we need firstly start dedviceJs server, running controller on that. Then next, the controller.js will read the output file and map frequency and amplitude into color domain and brightness domain. After we get color value and brightness value, using dev$selectByID API to set the filament color and brightness.
while len(data) == chunk*swidth:
  stream.write(Data)
  indata = np.array(wave.struct.unpack("%dh"%(len(data)/swidth),\
data))*window
  fftData=abs(np.fft.rfft(indata))**2
  amp=math.sqrt(max(fftData[1:]))
  which = fftData[1:].argmax() + 1
  if which != len(fftData)-1:
    y0,y1,y2 = np.log(fftData[which-1:which+2:])
    x1 = (y2 - y0) * .5 / (2 * y1 - y2 - y0)
    thefreq = (which+x1)*RATE/chunk
    print str(thefreq)+" "+str(amp)
  else:
    thefreq = which*RATE/chunk
    print str(thefreq)+" "+str(amp)
Read from data.txt to get the frequency and amplitude of music file. By doing a mathematical calculationa and normalization, map the frequency into color and amplitude into brightness. Then call the devicejs dev$ API to parse the color and brightness to different filaments, in which way we can control the filament.
if(freq<=0){ color=0.01; }
else if(freq>1050){ color=1.0; }
else{
  color=freq/1050;
  color=color.toFixed(3); }
if(amp<=0){ brightness=0.15; }
else if (amp>10000000){ brightness =1.0; }
else{
  brightness= amp/10000000*1.5;
  brightness=brightness.toFixed(3);
  if(brightness<0.15)
    brightness=0.15
  if(brightness>1.0)
    brightness=1.0; }
dev$.selectByID('WDFL000012').set('hsl',{h:color,s:1,l:brightness});
  $:python detector.py seeyouagain.wav > data.txt
  $:devicejs start
  $:sudo devicejs run ./
  $:run controller.js
The following is the experiment demo when connecting to one filament:
The following is the experiment demo when connecting to two filaments:
The following problems are those we faced when doing the project, and you may encounter some of these problems as well. Please refer to this section to troubleshoot.
ppt slides for the project (click to download)
Email addresses:
Qingqing Zheng<EMAIL_ADDRESS>Yuan Ma: mayuan@usc.edu


21 Introduction to {charpente}
21.1 Motivations
Translating an HTML template into an R API requires the creation of a package. As stated in Chapter 0.2, this is not a good practice to proceed as follows:
ui <- fluidPage(
useShinydashboard(),
tags$script(
[1172 chars quoted with '"']
),
box2(
title = textOutput("box_state"),
"Box body",
inputId = "mybox",
collapsible = TRUE,
plotOutput("plot")
),
actionButton("toggle_box", "Toggle Box")
)
server <- function(input, output, session) {
output$plot <- renderPlot({
req(!input$mybox$collapsed)
plot(rnorm(200))
})
output$box_state <- renderText({
state <- if (input$mybox$collapsed) "collapsed" else "uncollapsed"
paste("My box is", state)
})
observeEvent(input$toggle_box, {
updateBox2("mybox")
})
}
shinyApp(ui, server)
Imagine if we had to repeat the process for more than twenty components. The package structure provides many advantages like:
- Develop a comprehensive documentation of the underlying API
- Design unit tests to guaranty code robustness and improve long term plan
- Relevant file organization
21.2 General idea
{charpente} is a game changer for custom template creation. It is not yet on CRAN but has been widely used to help developing RinteRface packages. charpente drastically:
- Eases the import of external dependencies.
- Speeds up the HTML to R conversion, which is quite frankly a rather boring process,
allowing to focus on the features rather than the syntax. This feature builds on top of the
{html2R}
shiny app by Alan Dipert, already mentioned in Chapter 3. - Eases JS code management, leveraging esbuild.
Let’s try below with html_2_R
:
##
## ── Converting code ... ──
##
## ✓ Code converted with success.
## ℹ Copy and paste the following R code
## ────────────────────────────────────────────────────────────────────────────────
## tags$div(
## class = "divclass",
## id = "someid"
## )
html_2_R
has a prefix parameter which adds a tags$
prefix if TRUE. It is
TRUE by default which prevents errors with non exported Shiny tags like nav
.
The second main benefice of charpente is the dependency management system.
21.3 A case study: {shinybulma}
In the following, we’ll illustrate charpente’s workflow, through the R in Pharma workshop exercises focused on shinybulma.
bulma is a more and more popular open source CSS framework for the web. Importantly, there isn’t any JavaScript helper in the bulma core. We’ll see later that the recent bulma JS provides such feature. For now, we only focus on HTML and CSS.
To initialize a charpente package, we do:
path <- file.path(tempdir(), "mypkg")
create_charpente(path, license = "mit")
This sets up a minimal viable package with git and optionally github remote setup, Figure 21.2.
By default, the package DESCRIPTION
Imports
field has shiny
, htmltools
and
utils
. charpente is never required to be a dependency of your package since it might
be invasive.
In the ./R
folder, charpente creates a mypkg-utils.R
script containing:
- Tools to facilitate HTML dependency management like
add_dependencies
(see corresponding section below),processDeps
. - Some validation functions mentioned in Chapter 18.
Finally, you may see some exotic folders and files like srcjs
, package.json
, package-lock.json
and node_modules
. Fear not, we describe them later in 21.3.6. Overall, they are here to support to JS code management.
21.3.1 Build the HTML dependency
The interested reader may have a look at the Getting started guide, so as to know more how to get bulma. To install bulma dependencies, there are several ways:
- The CDN method (content delivery network) which consists in getting dependencies from a dedicated server. Files are not stored locally which may be a problem if one does not have internet.
- The local method consists in downloading the production files (minified CSS).
- Using npm that installs bulma sources as well as production files. It means one can modify sources at anytime, which is not recommended since it would be hard to maintain.
In our case, we show the two first methods, the third being out of the scope of this book.
As shown in previous Chapter (custom-templates-dependencies), we could build the bulma dependency as follows:
library(htmltools)
bulma_deps <- htmlDependency(
name = ...,
version = ...,
src = c(href = ...),
stylesheet = ...
)
add_bulma_deps <- function(tag) {
tagList(..., ...)
}
but this already takes too much time. This is where charpente comes into play.
Specifically, the create_dependency
function automatically download/points to the specified dependency by just providing its name. It means you have to know what you are looking for. Best practice is to have a look at the jsdelivr website (charpente is built on top of jsdelivr) and find the good repository, as shown Figure 21.3. create_dependency
also creates the add_<DEP_NAME>_deps
function in a <DEP_NAME>--dependencies.R
script and opens it.
charpente_options(local = FALSE)
allows to fine tune the behavior. If local is FALSE,
charpente points to the CDN without downloading any file. It is substantially faster than
the local option but requires an internet connection. Package developers will prefer the
local = TRUE
to ensure dependencies are always accessible.
Extra parameters like tag control the downloaded version since HTML templates
may have several flavors. It is always good to be able to test multiple versions and select
the best option.
Once satisfied, we simply run the below code to get the latest version, or a specific version if tag is used:
# CDN method
create_dependency("bulma", options = charpente_options(local = FALSE))
create_dependency("bulma", tag = "0.7.0", options = charpente_options(local = FALSE))
# local method (default)
create_dependency("bulma")
Moreover, create_dependency
is able to filter all files, through the charpente_options
:
-
minified targets all files with
.min
, if TRUE. -
bundle targets all files containing
.bundle
, if TRUE. -
lite targets files with
lite
keyword, if TRUE. -
rtl target all files with
.rtl
, if TRUE. rtl design stands for right to left and is common in some countries for instance.
You may imagine that charpente_options
targets .min
files by default. If you don’t find
any script, you probably have to change options. For instance, some templates
like Bootstrap and Framework7 have bundle.min
files (charpente_options(bunlde = TRUE)
), whereas bulma doesn’t.
We can test our new dependency:
devtools::load_all()
findDependencies(add_bulma_deps(div()))
which works like a charm. If you chose the local option, you also get an inst/bulma-<BULMA-VERSION>
folder
with all relevant files sorted by type. The bulma-dependencies.R
script contains the
newly created add_bulma_deps
function, either pointing to the CDN or the local
files, depending on the chosen strategy:
# local dependency script output
#' bulma dependencies utils
#'
#' @description This function attaches bulma. dependencies to the given tag
#'
#' @param tag Element to attach the dependencies.
#'
#' @importFrom htmltools tagList htmlDependency
#' @export
add_bulma_deps <- function(tag) {
bulma_deps <- htmlDependency(
name = "bulma",
version = "0.9.1",
src = c(file = "bulma-0.9.1"),
stylesheet = "css/bulma.min.css",
package = "mypkg",
)
tagList(tag, bulma_deps)
}
# CDN dependencies
#' bulma dependencies utils
#'
#' @description This function attaches bulma. dependencies to the given tag
#'
#' @param tag Element to attach the dependencies.
#'
#' @importFrom htmltools tagList htmlDependency
#' @export
add_bulma_deps <- function(tag) {
bulma_deps <- htmlDependency(
name = "bulma",
version = "0.9.1",
src = c(href = "https://cdn.jsdelivr.net/npm/bulma@0.9.1/"),
stylesheet = "css/bulma.min.css"
)
tagList(tag, bulma_deps)
}
charpente sets the roxygen skeleton so that you don’t have to worry about function imports.
21.3.2 Set up the minimal page template
According to the bulma documentation, the starter page template is:
<!DOCTYPE html>

<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Hello Bulma!</title>
<link rel="stylesheet"<EMAIL_ADDRESS>

Hello World

My first website with Bulma!

Adding some charpente magic with html_2_R
, we set the path parameter to /html
to get the entire template. We, replace ...
by the appropriate content (see above). Since the copied HTML contains double quotations marks like

, we put the string in single quotation marks.
html_2_R(
'

<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Hello Bulma!</title>
<link rel="stylesheet"<EMAIL_ADDRESS>

Hello World

My first website with Bulma!

',
path = "/html"
)
##
## ── Converting code ... ──
##
## ✓ Code converted with success.
## ℹ Copy and paste the following R code
## ────────────────────────────────────────────────────────────────────────────────
## tags$html(
## tags$head(
## tags$meta(charset = "utf-8"),
## tags$meta(
## name = "viewport",
## content = "width=device-width, initial-scale=1"
## ),
## tags$title("Hello Bulma!"),
## tags$link(
## rel = "stylesheet",
## href =<EMAIL_ADDRESS>## )
## ),
## tags$body(tags$section(
## class = "section",
## tags$div(
## class = "container",
## tags$h1(
## class = "title",
## "Hello World"
## ),
## tags$p(
## class = "subtitle",
## "My first website with",
## tags$strong("Bulma"),
## "!"
## )
## )
## ))
## )
At run time, shiny adds html
around the UI, thereby making it not necessary to include.
We also don’t need the link(rel = "stylesheet", href =<EMAIL_ADDRESS>since add_bulma_deps
does already attach the dependencies to the page.
The prefix
parameter defaults to TRUE, so that we don’t have to worry about whether tags functions are exported
by shiny (see Chapter 3).
The bulma_page
function is defined below, that we save in the R
package folder:
bulma_page <- function(..., title = NULL) {
tagList(
tags$head(
tags$meta(charset = "utf-8"),
tags$meta(
name = "viewport",
content = "width=device-width, initial-scale=1"
),
tags$title(title)
),
add_bulma_deps(tags$body(...))
)
}
With some practice, going from step one to the bulma page templates literally takes three minutes, while it would have taken more than 30 minutes by hand. At any time, you may replace the dependency with another version. Be careful, since charpente does not make snapshots of old versions.
21.3.3 Exercise: add bulmaJS
As stated in the above, bulma only contains CSS things! It means we need either to develop custom JS code to add interactivity or rely on any third party existing API. bulma JS is one of these!
- Using charpente, create a bulma js dependency. We point to vizuaalog/bulmajs since some bulmajs already exist and are not what we want. Run the following code in the R console.
create_dependency(...)
Notice how many files are added to the dependency. Below, we only work with notifications:
- Only keep
notification.js
and remove all the unnecessary files - Only keep
bulma.js
that gather all plugins in 1 script.
The best practice is usually to keep only what we need since some scripts may be heavy to load!
- Run
devtools::load_all()
. Modify the below code to test the newly created dependency. Hint: toggle the HTML inspector to check all appropriate dependencies are there!
ui <- bulma_page()
server <- function(input, output, session) {}
shinyApp(ui, server)
21.3.4 Add custom JS
Notifications are always useful to send user feedback. Shiny has a notification system through shiny::showNotification
. Like Shiny, Bulma notifications are entirely built from JS (no need for any HTML code).
The API works as follows:
-
Bulma(target).notification(config)
creates the notification based on a JSON option list (config).target
expects a jQuery selector. -
show
toggles the newly instantiated notification
In other words the below code attaches the notification to the body
:
In the following we design the R interface and JavaScript handler (which is no more than an event listener).
charpente has a function that creates both pieces, namely create_custom_handler
:
create_custom_handler("notification")
We obtain the notification-handler.R
script:
send_notification_message <- function(id = NULL, options = NULL, session = shiny::getDefaultReactiveDomain()) {
message <- list(
# your logic
)
session$sendCustomMessage(type = "notification", message)
}
and the corresponding JavaScript piece in notification.js
,
derived from the golem add_js_handler
function:
By default, the JS file is created in the srcjs
directory. This is a special directory
where we store all JavaScript files that depend on the package author. For instance,
bulmaJS is an external dependency and is very unlikely to be edited by the package author. For that reason,
it remains in the inst
folder like all other external dependencies.
21.3.5 Add custom input/output bindings
In part 11.2, we created better shinydashboard boxes that one
may programmatically collapse, close and restore. Until know, there was no way to
setup an input binding skeleton and one had to copy and paste each time the same
code. charpente has a create_input_binding
and create_output_binding
(functions that
you can also find in the development version of golem). Contrary to the custom handler case,
create_input_binding
only generate the JavaScript piece since the R part is highly variable from
one input to another. To get a plug and play box input binding we call:
create_input_binding("boxBinding")
which gives the input-boxBinding.js
script in the srcjs
folder:
var boxBinding = new Shiny.InputBinding();
$.extend(boxBinding, {
find: function(scope) {
// JS logic $(scope).find('whatever')
},
getValue: function(el) {
// JS code to get value
},
setValue: function(el, value) {
// JS code to set value
},
receiveMessage: function(el, data) {
// this.setValue(el, data);
},
subscribe: function(el, callback) {
$(el).on('click.boxBinding', function(e) {
callback();
});
},
unsubscribe: function(el) {
$(el).off('.boxBinding');
}
});
Shiny.inputBindings.register(boxBinding, 'shiny.whatever');
This function has multiple options:
-
initialized is FALSE by default. If TRUE, it adds an
initialized
method to the binding. -
dev adds some
console.log
elements whenever relevant to help in the debugging process. -
event is a list containing events related to the binding. By default, it generates
a
click
event without any rate policy. To add extra events we dolist(name = c("click", "whatever"), rate_policy = c(FALSE, TRUE))
.
Similarly, the create_output_binding
function creates a ready to use output binding JS script,
in the srcjs
folder (create_output_binding("menuOutput")
):
21.3.6 Organize your JS code
This naturally leads us to this part which is about JS code organization. Shiny developers
may have a lot of custom JS scripts, and it is generally a bad idea to put them all
under inst
. Instead, we store them in srcjs
. charpente has a function providing
a tool to bundle the JS code for production or development, that is build_js()
:
- It compresses, mangles all JS files and concatenate them in one minified file called
mypkg.min.js
. If mode isdev
, the files are not minified. - In production mode (mode is
prod
, by default), it additionally generates source maps.
esbuild concatenates file by the order provided in the ./srcjs/main.js
entry point, automatically generated by create_charpente()
. The configuration is provided by charpente in the package.json
file.
The script mypkg.min.js
is not human readable but the generated source map
allows to reconstruct the original code, which location is under the web browser srcjs
folder, like all Shiny JS files. From there, we can access any mapped script and start the debugging process like setting break points.
In production, the variable names, functions, are mangled. For instance, a variable
config
could be called t
in the minified file, which may lead to confusion.
Additionally, build_js
creates the mypkg-dependencies.R
file containing the HTML
dependency pointing to the newly generated JS file (below for production):
#' mypkg dependencies utils
#'
#' @description This function attaches mypkg dependencies to the given tag
#'
#' @param tag Element to attach the dependencies.
#'
#' @importFrom utils packageVersion
#' @importFrom htmltools tagList htmlDependency
#' @export
add_mypkg_deps <- function(tag) {
mypkg_deps <- htmlDependency(
name = "mypkg",
version = packageVersion("mypkg"),
src = c(file = "mypkg-<IP_ADDRESS>00"),
script = "js/mypkg.min.js",
package = "mypkg",
)
tagList(tag, mypkg_deps)
}
Switching between prod
and dev
automatically updates the mypkg-dependencies.R
JS files.
Finally, under the hood, create_js()
, create_input_binding()
, create_output_binding()
and create_custom_handler()
add a reference to the newly created script in the main.js
entry point, which may look like:
export
and import
must be called from the top level of a script. For instance,
an export
statement cannot be inside the $( document ).ready(function(...)});
, as this would trigger a build error.
charpente currently does not provide similar process for CSS, as this is still work in progress. Other tools exist like {packer}
by John Coene, which leverages webpack to handle JS code.
21.3.7 Combine multiple dependencies
add_dependencies
allows to select any dependency available in the ./R
folder,
provided that they follow the convention <depName>_dependencies.R
(which is always the case if you use charpente):
#' Attach all created dependencies in the ./R directory to the provided tag
#'
#' This function only works if there are existing dependencies. Otherwise,
#' an error is raised.
#'
#' @param tag Tag to attach the dependencies.
#' @param deps Dependencies to add. Expect a vector of names. If NULL, all dependencies
#' are added.
#' @export
#'
#' @examples
#' \dontrun{
#' library(htmltools)
#' findDependencies(add_dependencies(div()))
#' findDependencies(add_dependencies(div(), deps = "bulma"))
#' }
add_dependencies <- function(tag, deps = NULL) {
if (is.null(deps)) {
temp_names <- list.files("./R", pattern = "dependencies.R$")
deps <- unlist(lapply(temp_names, strsplit, split = "-dependencies.R"))
}
if (length(deps) == 0) stop("No dependencies found.")
deps <- lapply(deps, function(x) {
temp <- eval(
parse(
text = sprintf("htmltools::findDependencies(add_%s_deps(htmltools::div()))", x)
)
)
# this assumes all add_*_deps function only add 1 dependency
temp[[1]]
})
htmltools::tagList(tag, deps)
}
For instance add_dependencies(div(), deps = c("bulma", "bulmajs"))
adds bulma (first) and
bulmajs dependencies to a div
tag. You may change the order as you want since most
of the time, the order matters. We update bulma_page
to benefit from that feature:
bulma_page <- function(..., title = NULL) {
tagList(
tags$head(
tags$meta(charset = "utf-8"),
tags$meta(
name = "viewport",
content = "width=device-width, initial-scale=1"
),
tags$title(title)
),
add_dependencies(
tags$body(...),
deps = c("bulma", "mypkg")
)
)
}
As mentioned above, add_dependencies
belongs to the mypkg-utils.R
script
so that you don’t have to import charpente in the DESCRIPTION
Imports
field.
21.3.8 Other {charpente}
helpers
Let’s finish this section by listing other useful charpente tools.
We know create_dependency
to install an external dependency.
As shown earlier, this code installs bulma dependencies:
create_dependency("bulma")
However, we don’t necessarily know all package versions and may need
bulma 0.9.1
or bulma 0.7.0
. get_dependency_versions
allows to look for
all existing versions:
get_dependency_versions("bulma")
## ℹ Trying with https://data.jsdelivr.com/v1/package/npm/bulma
## ✓ Success!
## ────────────────────────────────────────────────────────────────────────────────
## [1] "0.9.2" "0.9.1" "0.9.0" "0.8.2" "0.8.1" "0.8.0" "0.7.5" "0.7.4"
## [9] "0.7.3" "0.7.2" "0.7.1" "0.7.0" "0.6.2" "0.6.1" "0.6.0" "0.5.3"
## [17] "0.5.2" "0.5.1" "0.5.0" "0.4.4" "0.4.3" "0.4.2" "0.4.1" "0.4.0"
## [25] "0.3.2" "0.3.1" "0.3.0" "0.2.3" "0.2.1" "0.2.0" "0.1.2" "0.1.1"
## [33] "0.1.0" "0.0.28" "0.0.27" "0.0.26" "0.0.25" "0.0.24" "0.0.23" "0.0.22"
## [41] "0.0.21" "0.0.20" "0.0.19" "0.0.18" "0.0.17" "0.0.16" "0.0.15" "0.0.14"
## [49] "0.0.13" "0.0.12" "0.0.11" "0.0.10" "0.0.9" "0.0.8" "0.0.7" "0.0.6"
## [57] "0.0.5" "0.0.4"
get_dependency_versions("bulma", latest = TRUE)
## ℹ Trying with https://data.jsdelivr.com/v1/package/npm/bulma
## ✓ Success!
## ────────────────────────────────────────────────────────────────────────────────
## [1] "0.9.2"
Specifying latest = TRUE
ensures to recover the very last stable version
(it excludes alpha/beta versions).
You may explore also the dependency files with get_dependency_assets
, even for
a specific version with tag:
get_dependency_assets("bulma")
## ℹ Trying with https://data.jsdelivr.com/v1/package/npm/bulma
## ✓ Success!
## ────────────────────────────────────────────────────────────────────────────────
## $url
## [1]<EMAIL_ADDRESS>##
## $files
## name hash
## 1 bulma.css yImvCCH14bBb1CP+8UKH4Kq6Hd77ErtYaM4V+QSvPwc=
## 2 bulma.css.map i9ZST1s/+LQDGevUi1OlRnePnesjoYhW5PJvsUWDqok=
## 3 bulma.min.css O8SsQwDg1R10WnKJNyYgd9J3rlom+YSVcGbEF5RmfFk=
## 4 bulma-rtl.css xFqhlC3rz3OH0JlaGEBeiKIB2at5/ragR+ldLLYZzQU=
## 5 bulma-rtl.css.map Jd1QERJuvEGxAD1EPmyOdUOL7Omn2gaDx6KSgqTaIEI=
## 6 bulma-rtl.min.css OhJCKE0+noWSdE9YUEx+d+3/hdatRbf8nfFQGFCBVhU=
##
## $hasSubfolders
## [1] TRUE
This is helpful to further fine tune charpente_options
, as stated previously. It is indeed possible
that you don’t want bundles, minified, lite or rtl versions of scripts. Internally, create_dependency
relies on get_dependency_assets
.
get_installed_dependency
allows to inspect which dependencies are installed. It only works
if the dependencies were created locally, that is charpente_options(local = TRUE)
.
Finally, one may ask how to update a given dependency. update_dependency
does this, provided that
the dependency is installed locally. By default, it installs the latest version of the targeted dependency.
It gives a diagnosis comparing the current installed version
with the latest available version. The are 3 possible cases: dependencies are up to date
and update_dependency("bulma")
yields:
ℹ Trying with https://data.jsdelivr.com/v1/package/npm/bulma
✓ Success!
──────────────────────────────────────────────────────────────────────────────
Error in update_dependency("bulma") : Versions are identical
The installed dependencies are outdated (we have 0.7.0 with create_dependency("bulma", tag = "0.7.0", options = charpente_options(local = TRUE))
), the function shows the targeted version as well as
the last one:
ℹ Trying with https://data.jsdelivr.com/v1/package/npm/bulma
✓ Success!
──────────────────────────────────────────────────────────────────────────────
ℹ current version: 0.7.0 ||
target version: 0.9.1 ||
latest version: 0.9.1
! Upgrading bulma to 0.9.1
✓ Directory inst/bulma-0.9.1/css successfully created
! Remove existing file R/bulma-dependencies.R
The last use case is a downgrade, which may be possible if the package maintainer realizes
that the dependency version is too unstable. In the following, we have bulma-0.9.1
installed
and downgrade to 0.7.0 with update_dependency("bulma", version_target = "0.7.0")
:
ℹ Trying with https://data.jsdelivr.com/v1/package/npm/bulma
✓ Success!
──────────────────────────────────────────────────────────────────────────────
ℹ current version: 0.9.1 ||
target version: 0.7.0 ||
latest version: 0.9.1
! Downgrading bulma to 0.7.0
✓ Directory inst/bulma-0.7.0/css successfully created
! Remove existing file R/bulma-dependencies.R
21.4 Other tips
21.4.1 Validate JavaScript
We could not finish this chapter without mentioning tools to validate JavaScript code. JSHint, which comes with {jstools}. Below is an example of how to check all the shinyMobile JavaScript input bindings at once:
shinyMobileJS <- system.file(sprintf("shinyMobile-%s/js/shinyMobile.js", packageVersion("shinyMobile")), package = "shinyMobile")
jshint_file(input = shinyMobileJS, options = jshint_options(jquery = TRUE, globals = list("Shiny", "app")))
## ── Checking shinyMobile.js ─────────────────────────────────────────────────────
## 51 errors found.
## - Line 34: 'template literal syntax' is only available in ES6 (use 'esversion: 6').
## - Line 39: 'template literal syntax' is only available in ES6 (use 'esversion: 6').
## - Line 43: 'template literal syntax' is only available in ES6 (use 'esversion: 6').
## - Line 44: 'template literal syntax' is only available in ES6 (use 'esversion: 6').
## - Line 123: 'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
## - Line 124: 'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
## - Line 137: 'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
## - Line 138: 'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
## - Line 139: 'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
## - Line 179: 'template literal syntax' is only available in ES6 (use 'esversion: 6').
## - Line 224: 'dialog' is defined but never used.
## - Line 228: 'confirm' is defined but never used.
## - Line 236: 'prompt' is defined but never used.
## - Line 260: The Function constructor is a form of eval.
## - Line 385: Function declarations should not be placed in blocks. Use a function expression or move the statement to the top of the outer function.
## - Line 388: Function declarations should not be placed in blocks. Use a function expression or move the statement to the top of the outer function.
## - Line 419: 'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
## - Line 466: Missing '()' invoking a constructor.
## - Line 478: Missing '()' invoking a constructor.
## - Line 558: Missing '()' invoking a constructor.
## - Line 654: Missing '()' invoking a constructor.
## - Line 679: Missing '()' invoking a constructor.
## - Line 733: Missing '()' invoking a constructor.
## - Line 776: Missing '()' invoking a constructor.
## - Line 809: Missing '()' invoking a constructor.
## - Line 817: Missing '()' invoking a constructor.
## - Line 866: Missing '()' invoking a constructor.
## - Line 891: Missing '()' invoking a constructor.
## - Line 938: Missing '()' invoking a constructor.
## - Line 965: Missing '()' invoking a constructor.
## - Line 1026: Missing '()' invoking a constructor.
## - Line 1095: Missing '()' invoking a constructor.
## - Line 1131: Missing '()' invoking a constructor.
## - Line 1217: Missing '()' invoking a constructor.
## - Line 1229: 'p' is defined but never used.
## - Line 1257: 'let' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
## - Line 1273: Missing '()' invoking a constructor.
## - Line 1345: Missing '()' invoking a constructor.
## - Line 1375: Missing '()' invoking a constructor.
## - Line 1396: 's' is defined but never used.
## - Line 1425: Missing '()' invoking a constructor.
## - Line 1445: 'r' is defined but never used.
## - Line 1516: Missing '()' invoking a constructor.
## - Line 1582: Missing '()' invoking a constructor.
## - Line 1602: 's' is defined but never used.
## - Line 1724: Missing '()' invoking a constructor.
## - Line 1762: Missing '()' invoking a constructor.
## - Line 1803: Missing '()' invoking a constructor.
## - Line 1816: 'for of' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
## - Line 1856: 'template literal syntax' is only available in ES6 (use 'esversion: 6').
## - Line 1856: Too many errors. (96% scanned).
You may fine tune the jshint_file
behavior with the jshint_options
. One is often tempted to call eval
in JS code, which will result in a JSHint error. An option called evil
exists to disable the corresponding test. However, we recommend to play the game, accept those error and try to fix them instead of cheating with options! An important remark about validation is that it does not check whether your code
does what it should do. It just focus on checking whether the code runs! To test
the JavaScript behavior, please refer to Chapter <IP_ADDRESS>.
Be extremely careful: if we consider the example mentioned in section 9.6.2, the
following code is valid JavaScript:
const sendNotif = (message, type, duration) => {
Shiny.notification.show({
html: `<strong>${message}</strong>`,
type: type,
duration: duration
});
};
sendNotif('Hello')
and will pass the validation step without any error:
jshint(
"const sendNotif = (message, type, duration) => {
Shiny.notification.show({
html: `<strong>${message}</strong>`,
type: type,
duration: duration
});
};
sendNotif('Hello');
",
options = jshint_options(
esversion = 6,
jquery = TRUE,
globals = list("Shiny", "app")
)
)
## $functions
## name param line character last lastcharacter
## 1 (empty) message, type, duration 1 27 7 4
## metrics.complexity metrics.parameters metrics.statements
## 1 1 3 1
##
## $options
## $options$unstable
## named list()
##
## $options$undef
## [1] TRUE
##
## $options$unused
## [1] "vars"
##
## $options$browser
## [1] TRUE
##
## $options$jquery
## [1] TRUE
##
## $options$devel
## [1] FALSE
##
## $options$esversion
## [1] 6
##
## $options$globals
## [1] "Shiny" "app"
##
## $options$indent
## [1] 4
##
## $options$maxerr
## [1] 50
##
##
## $globals
## [1] "Shiny"
##
## $member
## $member$notification
## [1] 1
##
## $member$show
## [1] 1
##
## $member$html
## [1] 1
##
## $member$type
## [1] 1
##
## $member$duration
## [1] 1
##
##
## attr(,"class")
## [1] "list" "jshint"
Yet the code won’t work since Shiny.notification
does not exist.
21.4.2 Beautify JS code
If you work with the RStudio IDE, your JS code maybe sometimes messy with bad indentation.
jstools also provides a function and addin to fix the problem. prettier_js(code)
and
prettier_file(input = "path/to/file.js", output = "path/to/reformated.js")
does this.
I often use the Prettier
addin which is way faster than typing the function call (Figure 21.4).
21.4.3 Test JS code
charpente provides a starting point to test the JS code with test_js()
, by leveraging the mocha library. All tests are assumed to be contained within the srcjs/test
folder. Inside, we find test_basic.js
, which was created upon package initialization, as a boilerplate:
This test starts with a describe
function, similar to the testthat context()
function, where you provide the general idea behind the test. it
is equivalent to test_that()
, where we describe what specific feature is being tested. Inside, we write a series of instructions, some of them failing, others passing. Naturally, mocha
works better with other assertions libraries like expect.js or should.js, whose details are out of the scope of this book.


Mexican President Promises Release of Governor Jailed for Laundering Cartel Money
Mexican President Andres Manuel Lopez Obrador (AMLO) promised the release of a former governor who helped the Juarez Cartel move large shipments of cocaine through his state. The politician is in prison on money laundering charges and he previously served time the U.S. for drug trafficking.
by Ildefonso Ortiz and Brandon DarbyDuring a speech last week in Quintana Roo, Lopez Obrador promised to secure the release of Mario Villanueva Madrid, the former governor of that state, Proceso reported. The state is home to Cancun and Playa del Carmen.
“It is my commitment that he will be freed,” Lopez Obrador is quoted saying. He claimed the matter is currently working through the courts. If the effort fails, he would try act in an executive manner. Villanueva is in a federal prison serving a 22-year sentence on money laundering and drug-related charges, Animal Politico reported.
According to a statement from the U.S. Attorney’s Office following his sentence on drug and money laundering charges, Villanueva became a governor in 1994 and “entered into an agreement with the Juarez Cartel that would ensure its cocaine shipments traveled safely through Quintana Roo without interference from law enforcement.” In exchange for his protection, Villanueva received millions of dollars that he laundered through offshore accounts.
In 2001, Mexican authorities arrested and convicted Villanueva on organized crime and corruption charges. In 2010, the U.S. extradited him for an eventual guilty plea in 2012 on drug and money laundering conspiracy. The Mexican government extradited Villanueva in 2017 so he could serve a 22-year prison sentence. Some of the time was served in a hospital.
Ildefonso Ortiz is an award-winning journalist with Breitbart Texas. He co-founded Breitbart Texas’ Cartel Chronicles project with Brandon Darby and senior Breitbart management. You can follow him on Twitter and on Facebook . He can be contacted at<EMAIL_ADDRESS>.
Brandon Darby is the managing director and editor-in-chief of Breitbart Texas. He co-founded Breitbart Texas’ Cartel Chronicles project with Ildefonso Ortiz and senior Breitbart management. Follow him on Twitter and Facebook . He can be contacted at<EMAIL_ADDRESS>.


ACT
The ACT (originally an abbreviation of American College Testing) is a standardized test used for college admissions in the United States. It was first introduced in November 1959 by University of Iowa professor Everett Franklin Lindquist as a competitor to the Scholastic Aptitude Test (SAT). It is currently administered by ACT, a nonprofit organization of the same name.
The ACT originally consisted of four tests: English, Mathematics, Social Studies, and Natural Sciences. In 1989, however, the Social Studies test was changed into a Reading section (which included a social sciences subsection), and the Natural Sciences test was renamed the Science Reasoning test, with more emphasis on problem-solving skills as opposed to memorizing scientific facts. In February 2005, an optional Writing Test was added to the ACT, mirroring changes to the SAT that took place in March of the same year. In 2013, ACT announced that students would be able to take the ACT by computer starting in the spring of 2015; however, by the fall of 2017, computer-based ACT tests were available only for school-day testing in limited school districts in the US, with greater availability not expected until at least the fall of 2018.
The ACT has seen a gradual increase in the number of test takers since its inception, and in 2011 the ACT surpassed the SAT for the first time in total test takers; that year, 1,666,017 students took the ACT and 1,664,479 students took the SAT. All four-year colleges and universities in the U.S. accept the ACT, but different institutions place different emphases on standardized tests such as the ACT, compared to other factors including class rank, GPA, and extracurricular activities.
The main four sections are individually scored on a scale of 1–36, and a composite score (the rounded whole number average of the four sections) is provided.
|


This sample demonstrates how to automatically generate thumbnails for each images that are uploaded to Firebase Storage.
See file functions/index.js for the thumbnail generation code.
The thumbnail generation is performed using ImageMagick which is installed
by default on all Cloud Functions instances. This is a CLI so we execute
the command from node using the
child-process-promise
package. The image is first downloaded locally from the Firebase Storage
bucket to the tmp
folder using the
google-cloud
SDK.
The dependencies are listed in functions/package.json.
The function triggers on upload of any file to your Firebase project’s default Cloud Storage bucket.
To deploy and test the sample:
git clone https://github.com/firebase/functions-samples
.
cd functions-samples/generate-thumbnail
firebase use --add
and select
the project you had created.
cd functions; npm install; cd -
firebase deploy
thumb_
prefix will be created in the same folder (make sure
you refresh the UI to see the new file).
images
has been
created containing the Signed URLs for both images.


| DOSE: |
repeated |
oral |
Coffee |
(liquid) |
Caffeine has become my favorite drug. I've had significant experience with other stimulants: nicotine, cocaine, various amphetamines, ephedrine, and free-form amino acids like acetyl l-carnitine, l-tyrosine, etc.
I've quit nicotine. I avoid cocaine entirely and have for years. Sometimes I take amphetamines in the form of Adderall, but only 5 mg or less at once. I'm sensitive to stimulants yet I enjoy their effects. In my opinion, caffeine is really the best of the bunch.
Its legality certainly plays into my qualification, but its good effect combined with its relatively benign nature are what really make it so nice. I enjoy the taste of a good latte, too!
I rarely drink more than a regular cup of coffee at once. That's certainly enough for me. I play music for a living, and I find it to be stimulating both physically and creatively, unlike amphetamine which is only stimulating physically. I prefer to just sip on a coffee while I perform. It helps my coordination and concentration and I hear the music better. I can play by ear better on caffeine. I can read music more proficiently. And there's no nasty comedown at this kind of dose. There's really nothing nasty about it at all. It just fades away when the primary effect is over.
I can drink a cup of coffee up on stage and nobody thinks twice. I can drink it while I teach lessons to children and nobody cares. Their parents usually comment on their own appreciation for caffeine when they see me with my coffee.
I've never had withdrawal. I've often gone weeks or months without consuming caffeine. Never a headache or other symptom.
All in all, after having tried the harder stuff, I find caffeine to be really all I want in the stimulant department. Pharmaceutical amphetamines in very low doses are occasionally a better bet (for long driving trips, all-night studying, doing really tedious work) but I rarely need all that stimulation.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


Make Open-tsvn-url
Enable:
Activate URL:
SVN URL:
Branch Path:
Trunk Path:
Working Path:
ContextMenu:
Make Porting-to-Branch
Enable:
Activate URL:
Reference Ticket:
Excluded Project:
Excluded Status:
CheckBox Name:
InputArea Name:
Debug
Log:
Save