MAMP Allow CORS

Life

To allow cors from MAMP for development, add the following:

Header set Access-Control-Allow-Origin "*"

To your “additional parameters for <VirtualHost> directive: section.

Advertisements

Bose Quiet Comfort/QC35 OSX Mic Always On

Life

I have been having issues with my Bose QC35 microphone being on, negating the noise cancellation. I’ve tried so many fixes like bluetooth bitrate hacks and such.

I finally found the true cause and true fix.

Make sure System Preferences > Dictation > Microphone is not set to your QC35.

Shopify Checkout GA Cross Domain Tracking

Life

Grovemade.com has a very odd setup using Shopify. We have our own frontend layer using the Shopify API to populate products, with the rest of the site fully in our control.

This is done by having nginx proxy all requests to our app *except* shopify URLs such as /cart, /checkout

We then use the JS API and proxy requests to Shopify with a few fake headers to allow Shopify to work this way.

The biggest problem thus far has been e-commerce tracking, as Shopify does not let us control the checkout pages. E-commerce data arrives, but is not associated to any visitor session.

 

Shopify has a decorator that sets a _shopify_ga cookie immediately upon direct checkout links or cart submissions being executed. The response from Shopify appends parameters that identify the session on the previous domain to the checkout.shopify.com URL.

If you host pages outside Shopify and want cross domain support for Google Analytics, replicate the linker decorator and add the GA linker string in a cookie called _shopify_ga on click for checkout links or carts.

Any action that ultimately takes you to checkout.myshopify.com should add the _shopify_ga cookie with google linker parameter.

Here’s the relevant function to use on your site.

In our case, we had to modify the form element being looked for to match our environment.

 window.addShopifyLinkerLinks = function() {
  ga('require', 'linker');
  function addListener(element, type, callback) {
    if (element.addEventListener) {
      element.addEventListener(type, callback);
    }
    else if (element.attachEvent) {
      element.attachEvent('on' + type, callback);
    }
  }
  function decorate(event) {
    event = event || window.event;
    var target = event.target || event.srcElement;
    if (target && (target.getAttribute('action') || target.getAttribute('href'))) {
      ga(function (tracker) {
        var linkerParam = tracker.get('linkerParam');
        var cookie = '_shopify_ga=' + linkerParam + '; ' + 'path=/';
        document.cookie = cookie;
      });
    }
  }
  for (var i=0; i < document.forms.length; i++) {
    var action = document.forms[i].getAttribute('action');
    if(action && action.indexOf('/cart') >= 0) {
      addListener(document.forms[i], 'submit', decorate);
    }
  }
  for (var i=0; i < document.links.length; i++) {
    var href = document.links[i].getAttribute('href');
    if(href && href.indexOf('/checkout') >= 0) {
      addListener(document.links[i], 'click', decorate);
    }
  }
}

Hubspot API undocumented “Options” format

Life
HubSpot documentation ignores how to format the "Options" field in their API calls.

Their examples always leave it empty.

It returns an “Incorrect JSON format” error straight from Java if you try to pass an array of values.

The correct format is

[
{
u’description’:None,
u’value’:u’WALNUT &amp; LEATHER iPHONE CASE’,
u’label’:u’WALNUT &amp; LEATHER iPHONE CASE’,
u’readOnly’:None,
u’hidden’:False,
u’displayOrder’:-1,
u’doubleData’:None
}
]

I’m not sure what doubleData does.

Sublime Shortcut for Toggling Find/Search “In Selection”

Life

Sublime has shortcuts for almost all of the common search operations.

Find in file.
Find and replace in file.
Find and or replace in entire project.
Use regex
Match case
Match whole words

In selection is a very common, and useful tool.

You can add it by adding this to your user key bindings. I picked super+alt+s, which follows the rest of the search hotkeys. It overrides the "save all files" command, but only when the search window is open.

Plus, I hardly use that command, and when I need to, I use the command pallete.

    { "keys": ["super+alt+s"], "command": "toggle_in_selection", "context":
      [
         { "key": "setting.is_widget", "operator": "equal", "operand": true }
      ]
   }

Get Instagram oAuth Token

Life

This should be rather simple but there are no 3 step tutorials to do this. I’ve even done it multiple times in the past. Bullet points:

1: Register an application in instagram’s developer page. https://instagram.com/developer/clients/manage

2: Take the CLIENT ID from the newly created app.

3: Log into the instagram account of the client that you want access to

4: Visit the following URL, replacing client_id and redirect_uri with the ones you defined in your application. https://instagram.com/oauth/authorize/?client_id=*****************&redirect_uri=*************&response_type=token

5: Accept. NOTE: If you are using this to use a javascript / frontend / non serverside method of communicating with the API, ensure you add &scope=basic to the URL https://instagram.com/oauth/authorize/?client_id=*****************&redirect_uri=*************&response_type=code&scope=basic So that a publicly available key can’t be abused.

6: You will get your token in the redirect_url in the form of a hash (#<ACCESS_TOKEN>)

7: Profit

Removing Shopify Admin Bar

Life

The admin bar keeps adding new tricks, like adding top: 40px to any fixed elements.

Try this:

&lt;script&gt;
try {
document.addEventListener(&quot;DOMContentLoaded&quot;, function(event) {
try {
var element = document.getElementById(&quot;admin_bar_iframe&quot;);
var html = document.getElementsByTagName(&quot;html&quot;)[0];
element.parentNode.removeChild(element);
html.style.paddingTop = &quot;0&quot;

} catch(ex) {}
})
} catch(ex) {};

function removeShopifyAdminBarHeights() {
$('[style=&quot;top: 40px;&quot;]').css('top', '');
}
$(function() {
removeShopifyAdminBarHeights();
});
setTimeout(removeShopifyAdminBarHeights, 500);
&lt;/script&gt;

Wacom Alternative – Huion h610 Pro is Amazing

Life

EDIT: I take this all back. Wacom is king. Unfortunately. Those patents are rock solid. I sadly have now purchased more than 4 Wacoms, and 3 Huions or so.

OLD POST:
I have owned many Wacom tablets.

I own 3 right now, an Intuos Pro Medium, Intuos 4 Wide (wish they kept this dimension), and a Bamboo.

My Pro broke after a month, and while I trust it will be replaced with the warranty, I need a tablet now, and I didn’t want to drop another $350 while I wait.

I finally tried a Wacom alternative, and it is quite frankly amazing. The Huion H610 Pro for $80 or roughly 1/4th the price.

It works out of the box on my Retina MBP with Yosemite (Q1 2015 latest) with no drivers necessary. This is huge. Tablet driver issues even between Wacoms is a pain. Reinstalls, clearing crazy folders via command line, etc.

The only cons is that it requires you plug in the pen (which feels no different to me than a Wacom tablet), but you’re not fumbling with batteries. It’s just another simple USB cord that plugs directly into the battery.

Wacom has a patent on the most effective wireless/powerless pen technology, and is why they have a stronghold on the market and can control prices at will. Going third party means adopting a battery powered pen.. which until now I thought would be a huge bother. It’s not bad at all. The pen is the same size and light.

In general the whole thing is lighter / has slightly lower build quality, but that doesn’t matter to me. My Wacom’s get abused and especially the new, black PRO line gets ugly fast from use.

If you’re looking for a tablet, just get this thing. Buy the Wacom when you can afford it. It’s kind of like buying a nice car vs an economy car. They both do similar things, and both have justifications.

I like to buy top of the line for things I use for work. I will go back to a Wacom when mine is repaired, but this Huion is nothing short of impressive! Give it a shot and let me know what you think.

Here’s my referral link:
Huion H610 Pro Graphics Tablet

For the price, just buy it. I expect 0 support on this thing, or warranty. It’s 1/4 the price.