Affari

Affari Project started out as a passion of 2 people, to see lives reached and stories told in the best way possible we know how, through web and graphic design and development.  Bringing a mission and vision to life and learning the heart behind the story that we were being tasked to tell.  This was what Affari Project was built on and will continue to serve as the solid foundation for AFFARI going forward.

AFFARI is Italian for “business” and as we have continued to grow, we are excited to be branching our strengths out to be able to meet more people, tell more stories and see more organization and businesses grow and thrive.  Now bringing other areas of specialty to the forefront, AFFARI will work to expand the reach of each client that entrusts us with their story.  With the additions of business development, digital marketing, SEO, social media management and interactive design, development and promotion, we will be seeing our ability to reach you in new and critical ways.

Our mission

Affari Project is at our core, the original foundation of AFFARI and the heat of who we are.  It has been and will continue to grow to be a leader in the design and development world.  Working to set the example of where the design world is going and not simply following the current trends.

With the growth of our business development and digital marketing, we have expanded Affari Group to meet the needs that our clients have and that organization and Businesses struggle with every day.  Our desire it to make sure that we are able to see our clients grow and thrive and be able to walk with them through that expansion.  Everyday, we strive and work to see the positive exposure of your company and in turn your success.

As we have continued to see companies met where they are and their growth pour from the work that we have been doing, we are excited to continue our expansion into industries that we are excited to meet.  Affari has continued to see the expansion of the interactive world, working on several key projects in this arena, and trying to bring a new direction to each hat we get to team with.  Affari Interactive is excited to be working with Amazon, Sony and many other companies to see the success of our clients and the growth of their missions!

As Affari continues to go, our mission to see others success will remain our primary mission.  No matter what we do, the industries that we have the honor to be a part of, we will work to make sure that others stories are told and their growth is seen!  It is an opportunity that we will never take lightly and we will continue to support every day that we exist!

Every company has seasons: seasons of development, seasons of foundation building, seasons of growth and seasons of stability and sustainability. Each season comes with its own set of tasks, needs, actions and emotions. Every leader see’s this and the best learn to act accordingly and plan for any and all, knowing that growth is always a single decision away. Affari project is excited to be launching forward into a new season, it’s next chapter, ready to challenge not only ourselves but everyone around us.

Icarus was given an amazing gift from his father.  The ability to FLY. Soar to heights that he could never have initially imagined. His father provided, gifted and entrusted him to use his talents wisely, knowing that if used right, the sky was the limit, the ability of Icarus was unmatched.  The only things that stood in his way were 2 small things, the sun and water. Simple known obstacles to prevent growth.  Two things clearly stated that could end his ability to fly and ultimately lead to death.  Business is much the same and Affari project has learned many obstacles and talents along the way. Our hope now, to simply execute our gift, our talent, to the best of our ability and continually push ourselves and set the bar higher to make sure we are at the top.

Now don’t be deceived, the things that can prevent this growth, this flight, are very real.  But don’t we know most, are we not told by those ahead of us. I know that over the past several years, I have been able to see companies come and companies go, some doing well, other barely able to keep their doors open, but every time, there were commonalities that could be gleaned.

Affari Project is growing and learning, and we are excited to show our new side, our new identity, with the SAME mission. We thought that as our team grew, both in strength and in size, we would continue to exhibit who we are as a company!   We are excited to be rolling out the “new” Affari Project, pulling a Facebook, dropping the “The” and realizing that our letters are enough to show that our creative ability and understanding of business and business development, are just the start to how we want to serve you. Our mission is still to bring your story to life, to create the future and to achieve sustainability and success, it’s just a much more public mission! Join Affari Project, and as always, Stay Hungry.

Whether you live in an apartment, condo, suburban neighborhood or a flat of some sort, nobody likes having bad neighbors. Our hosting platform is built like a neighborhood. And like in the real world, we also hate bad neighbors on our hosting platform. As such we work hard to make sure the neighborhood (our servers) are safe, orderly and that everyone is good for the neighborhood. Before we get too technical there’s a few things we feel like we should explain that will help understand our policies better:

Shared Hosting

Affari Host is a shared hosting platform. What does that mean? Simply that each server has a finite amount of resources available to it. Because of this fact, we don’t promise unlimited storage or unlimited bandwidth. We simply place a defined hard limit number of accounts on a single server. Each of those accounts then shares the server’s resources with the others on that server. We call those other accounts “neighbors.” We do this because we know that behind each website are real people doing real things with real and great ideas!

What is a bad neighbor?

A bad neighbor is an account that is continually trying to hog the server’s resources and not sharing well with the other account holders. We allow each Discovery account to “burst” up to 1GB of RAM usage and each Endeavor to burst up to 3GB of RAM usage. It’s quite rare that most common small web applications will need to push these limits. If a script or application is using this amount of RAM on a continual basis it is either one of two possible reasons, 1) the script is poorly written and should be fixed, 2) the script is far too intensive for a shared environment and should be transitioned to a VPS or Dedicated type account at another provider. That said, our team is always happy to take a look at your site’s application and see if there are any suggestions or optimizations that we can help you with to bring resource usage.

You’re probably wondering how using these resource limits makes you a bad neighbor. As we mentioned earlier, each server has a finite amount of resources available. As such continually pushing the limits makes the server slow down for other users. We run daily audits and will notify you if your account is creating issues for your neighbors. We’ll do our best to help you resolve the issue, if no resolution can be reached we will make a custom recommendation or kindly ask you to find another hosting provider who will better meet your needs.

What does a good neighbor look like?

A good neighbor keeps their lawn mowed and is friendly to the neighborhood around them. In our world that looks like a well maintained website. If your site is built on a CMS or other Platform like WordPress, Joomla, Magento or another popular one, it means you’re keeping your version of the software up to date and your plugins up to date. It also may look like taking advantage of caching. But ultimately you’re doing your best to keep your site secure, fast and optimized. If you do that, 99.99% chance you’ll never even have to worry about our neighborhood policy.

What if…

To all the other concerns, our team is happy to help and answer your questions! That’s what we’re here for! Drop us a line at

support@affari.co

Thanks for doing your part to keep the neighborhood safe and clean!

When we started Affari, it was out of the heart to see lives changed though bringing attention and quality design to organization and companies.  We wanted to see them succeed, that was our only mission.  Five years later, that is still our mission and we could not be more honored  to be able to have served all that we have.

In five years, we have had the opportunity to help hundresd of clients see their missions served and visions reached.  Each one we have strived to meet them where they are, working to see them grow and expand, creating something for them that only they have and we have only created the one time for them.  Something unique.  It is not always an easy thing to do but something we continue to do daily for all our clients and something we have a passion to continue to do going forward.

2017 is a year for Affari Project for rebirth and continued expansion and growth, so that we can continue to serve our clients even better!  We are excited to announce the addition of Affari Group and Affari Interactive to our teams.  In addition to this, we are simply going to be going by Affari going forward…working to make sure our business is you and your business success!

Recently the Affari Project had the opportunity to build a native iOS application using WordPress as its foundation. Overlaying webviews allowed the WordPress framework to handle a majority of the app functionality. One aspect that was not part of WP core was incorporating geolocation into WordPress search. Users of the app needed the ability to search for posts and in return see only posts within a certain mile radius of where they are located. Accomplishing this seemingly complex process only took five easy steps. Each step is outlined in detail below but for all you coding wizards who don’t need the long explanation here is a quick summary of the entire process of Geolocation in a WordPress based app:

  • Tie a zip code to each post as post meta.
  • Find the user’s longitude/latitude with HTML5 Geolocation http://www.w3schools.com/html/html5_geolocation.asp.
  • Gather zipcodes within a specified mile radius using this tool http://api.geonames.org/.
  • Convert the XML file output by the Geo Names page (above) into an array using the PHP function, simplexml_load_file().
  • Set our WordPress query to return posts using the specified zip codes.

Step 1: Tie each post to a zip code

If you are well versed in WordPress this is a pretty simple task. Create a custom field with the meta key ‘zip_code’ and assign a zip code to every post. If you need help setting up custom fields I recommend the popular Advanced Custom Fields plugin.

Step 2: Pinpoint the user’s location

HTML5 browsers (including iOS webviews) can pinpoint a user’s longitude and latitude coordinates using this function:

navigator.geolocation.getCurrentPosition(showPosition)

Set up a custom page template to drop all this code into. For this example we’ll use a page called Geo. Set $_GET[‘lat’] and $_GET[‘lon’] values in the url of our ‘/geo’ page to use later. This will also allow you to manually specify coordinates for testing purposes. Here is the code:

<?php if (!$_GET['lat'] || !$_GET['lon']) { ?>
  <script>
    if(navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(function(position) {
        var lat = position.coords.latitude;
        var lon = position.coords.longitude;
        document.location = "/geo/?lat=" + lat + "&lon=" + lon;
      });
    }
  </script>
<?php } ?>

Now the ‘/geo’ page redirects users to a version where the url contains their specific longitude and latitude coordinates in $_GET variables.

Step 3: Find all the zipcodes within a certain mile radius of the user

Once you have the longitude and latitude coordinates set you can find the nearby zipcodes using this tool http://www.geonames.org/ Go to the site, click login, and create an account. Their API limits each user of the free version so if you’re planning on hitting this thing more than 2,000 times an hour or 30,000 times a day you may need to sign up for their ‘Premium Webservices’. Once you have an account you can get the nearby zipcodes in XML format with the code below.

if ($_GET['lat'] && $_GET['lon']) {
  $xml = 'http://api.geonames.org/findNearbyPostalCodes?lat='. $lat . '&lng=' .$long . '&radius=30&username=YOURUSERNAME&maxRows=100';
}

Don’t forget to replace ‘YOURUSERNAME’ with the username you’ve created.

Step 4: Convert the XML to an array with simplexml_load_file()

Once you’ve set the $xml variable as a working Geo Names url; use this PHP function to convert your $xml variable (which is essentially an XML file) into an array like so:

simplexml_load_file($xml)

Now you can pull the zip codes out of the complex array this creates with the following code:

$locations = simplexml_load_file($xml);
foreach ($locations as $location) {
  $locationdata[] = get_object_vars($location);
  foreach($locationdata as $data) {
    $zipcodes[] = $data[postalcode];
  }
}

Alternatively you could use print_r($locations) to see all the data your array contains and pull out what you need.

Step 5: Use your array of zip codes in a WP_Query

The original goal was to use geolocation in a WordPress based iOS application so naturally everything comes down to the WordPress query. Since you’ve created a simple array called $zipcodes, containing all of the zip codes within a radius of the user, you can modify your WordPress query like this:

$args['meta_query'] = array(
  'key' => 'zip_code',
  'value' => $zipcodes,
  'compare' => 'IN'
)
WP_Query($args);

Voilà! With a working WP_query() that returns posts within a certain mile radius of the user, we have successfully used geolocation in a WordPress based iOS application.

The Goal

You’ve probably seen a lazy load being used on websites or in mobile apps like Instagram or Twitter. The basic concept is, when a user initially loads the page they are only served enough posts to fill their screen. Then, as the user scrolls down and their window approaches the bottom of the document a new set of posts are dynamically loaded into the page. This repeats over and over until all the posts are fully loaded. This can be accomplished using WordPress pagination and some basic jQuery. To see a working example of AJAX lazy load with WordPress Pagination click here.

The Code

Start with a wrapping div:

<div id=”lazyload”>

</div>

Inside this div modify the query:

<?php
  $paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
  $query_args = array(
    'post_type' => 'post',
    'posts_per_page' => 5,
    'paged' => $paged
  );
  if (have_posts()) {
?>

<?php
  }
?>

Within your ‘if’ statement put a div that will contain each page’s elements and has an unique page-specific id:

<div class="page" id="p<?php echo $paged; ?>">

</div>

Next, drop in your loop for each page’s posts:

<?php while (have_posts()) { the_post(); ?>
  <article>
    <header class="entryheader">
      <h2 class="entrytitle"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
    </header>
    <div class="entrycontent">
      <?php the_excerpt(); ?>
    </div>
  </article>
<?php } ?>

Now add a spinner to the bottom of the page. Keep it outside the “lazy load” div at the bottom of your document:

<div id="spinner">
  <img src="loading.gif">
</div>

At this point you have a page template that shows 5 posts on each page. Add /?p=2 to the url to make sure the pagination is working. Next we’ll implement the script that will use the jQuery load() function to pull posts in via the WordPress pagination url. First we’ll add a script tag with a jQuery function containing two variables:

<script>
  jQuery(function(){
    var page = 2;
    var loadmore = 'on';
  });
</script>

We’ll use the first variable ‘page’ to determine what page should be loaded next. The second variable ‘loadmore’ will prevent multiple .load() functions from happening at the same time. Now within the jQuery function add an .on(‘scroll resize’) trigger:

jQuery(document).on('scroll resize', function() {

});

Within this function we’ll add a condition to check if the bottom of the last loaded page is nearing the bottom of the browser’s window and another condition to check if ‘loadmore’ is set to ‘on’.

if (jQuery(window).scrollTop() + jQuery(window).height() + 60 > jQuery(document).height()) {
  if (loadmore == 'on') {
  }
}

Now if these two conditions are met we want to load the next page of posts into our #lazyload div. The first thing we’ll do is set ‘loadmore’ to ‘off’ so that we only load one page at a time. Then set the #spinner div to be visible to make the user aware that another set of posts are being loaded in.

loadmore = 'off';
jQuery('#spinner').css('visibility', 'visible');

Now we can use the jQuery .load() function to pull our content into the page. We don’t want to replace the content entirely we want to append the content at the end of our #loadmore div. Here’s the code:

jQuery('#lazyload').append(jQuery('<div class="page" id="p' + page + '">').load('YOURURLHERE/?paged=' + page + ' .page > *', function() {

}));

When working with AJAX lazy load with WordPress, be sure to replace YOURURLHERE with the url of the page you’re working on. You’ll notice that we’re appending a div that contains a unique id specific to the page we’re pulling in. This id is used to detect when the ‘page’ div is nearing the bottom of the page for the function to repeat. Within this function put these three events that will be triggered once the .load() function has completed:

page++;
loadmore = 'on';
jQuery('#spinner').css('visibility', 'hidden');

As you can see, we’ve increased the ‘page’ variable by 1 to load the next page. Then we set the ‘loadmore’ variable to ‘on’ and set the #spinner to be hidden. The final thing we should do is detect if the .load() function doesn’t return any data. That way once the final page has loaded the user won’t continue to see a spinner at the bottom as they scroll down. This function should sit within the root of your jQuery function and will look like this:

jQuery( document ).ajaxComplete(function( event, xhr, options ) {
  if (xhr.responseText.indexOf('class="page"') == -1) {
loadmore = 'off';
  }
});

Here is what your complete code should look like:

<div id="lazyload" class="grid_12">
<?php
  $paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
  $query_args = array(
    'post_type' => 'post',
    'posts_per_page' => 5,
    'paged' => $paged
  );
?>
  <?php if (have_posts()) { ?>
    <div class="page" id="p<?php echo $paged; ?>">
    <?php while (have_posts()) { the_post(); ?>
      <article id="post-<?php the_ID(); ?>" <?php post_class('entry') ?>>
        <header class="entryheader">
          <h2 class="entrytitle"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
        </header>
        <div class="entrycontent">
          <?php the_excerpt(); ?>
        </div>
      </article>
    <?php } ?>
    </div>
  <?php } ?>
</div>
<div id="spinner">
  <img src="loading.gif">
</div>
<script>
  jQuery(function(){
    var page = 2;
    var loadmore = 'on';
    jQuery(document).on('scroll resize', function() {
      if (jQuery(window).scrollTop() + jQuery(window).height() + 60 > jQuery(document).height()) {
        if (loadmore == 'on') {
          loadmore = 'off';
          jQuery('#spinner').css('visibility', 'visible');
          jQuery('#lazyload').append(jQuery('<div class="page" id="p' + page + '">').load('/?paged=' + page + ' .page > *', function() {
            page++;
            loadmore = 'on';
            jQuery('#spinner').css('visibility', 'hidden');
          }));
        }
      }
    });
    jQuery( document ).ajaxComplete(function( event, xhr, options ) {
      if (xhr.responseText.indexOf('class="page"') == -1) {
        loadmore = 'off';
      }
    });
  });
</script>

Thanks for reading this post about AJAX lazy load with WordPress Pagination, we hope it helped you! Don't forget to follow us on social media to stay up to date on all our development blog posts! Twitter, Facebook and Instagram.


Speeding up a WordPress based iOS application

The Problem

Speeding up a WordPress based iOS application is a topic becoming more popular and necessary. With the growing popularity of WordPress, you need to know how to speed up WP based iOS applications.

When building an iOS application that uses webviews to load data, speed is crucial. Unfortunately, one of the biggest complaints with WordPress how slow it is. Out of the box, WordPress simply cannot handle the need-for-speed an iOS app requires. That is why most WordPress based applications separate out the front end views using some other framework such as Laravel or Node.JS. But what if you want to build an iOS application that runs entirely on WordPress, templates and all? Fortunately there are several tricks and tools that can make it work.

The Solution

1: wp_cache_get() and wp_cache_set()

These little nuggets allow you to tailor each query’s caching specifically to your needs. Say you have a dashboard that doesn’t need to be real time but does update every hour or so. The user might use this dashboard to reach several parts of the app, returning to it five or six times in a matter of minutes. Waiting even half a second each time they return to this page will quickly get tedious and the user might give up the app altogether. If you set a cache the first time the user hits this dashboard, the next time the user returns they’ll be served a cached version cutting out the time it takes WordPress to loop through your query. Here’s how it works:

$cache_key = 'post';
$posts = wp_cache_get($cache_key);
if ($posts === false) {
  $post = new WP_Query(array(
    'post_type' => 'post',
    'posts_per_page' => 5
  ));
  wp_cache_set($cache_key, $posts, '', 3600);
}
if ($posts->have_posts()) {

In this example we’ve set the cache to expire every hour (3600 seconds). Also, be sure to always use a unique cache key every time you do this! The above example will only work for something universal. In the case of a user dashboard it might be good to throw the user’s ID into the cache key or some other unique modifier. What if you want the cache to clear every time the user does a specific action, such as accepting a friend request? You can always use this function to manually clear a cache:

wp_cache_delete('post');

2: AJAX lazy-load

AJAX is a way to pull content into an already loaded page. You see this concept used in the most popular mobile apps such as Instagram and Twitter. As you scroll down the page new content gets loaded in dynamically. WordPress pagination makes it fairly easy to accomplish this. If you want an explanation on how to implement AJAX lazy-load with WordPress pagination check out this blog post. Here is the most important part of the code:

<script>
  jQuery(function(){
    var page = 2;
    jQuery('#lazyloadwrapper').append(jQuery('<div>').load('YOURPAGEURL/?paged=' + page + ' .page', function() {
      page++;
    });
  });
</script>

3: Simplify Your Queries!

If you’re writing a custom query involving multiple custom post types and checks custom taxonomies there’s a chance you’ve overcomplicated things. Though your code might be working it may be spending precious time querying something that doesn’t serve a vital purpose. If there’s an opportunity to remove a query, do it!

4: Use a Caching Plugin

W3Total Cache is arguably the best caching plugin out there for WordPress. It works really quickly out of the box. It also provides options so you can tailor caching for your specific needs. Another great caching plugin is WP Super Cache by Automattic.

5: Minify and Combine your CSS and JS files

The plugin W3Total Cache (mentioned above) makes this easy to implement. However, if you’re not a fan of plugins you can always just combine your CSS files into one ‘master.css’ file and JS files into one ‘master.js’ file. Sometimes this can cause things to break so always check the front end after you do this!

6: Try out a Content Delivery Network

A content delivery network serves content from your site to users from a highspeed, and usually geographically closer, server. It also decreases the amount of work your server has to do. You can try this concept out free with Cloudflare. If you want to pay for a high end CDN, Max CDN works great and integrates well with W3Total Cache.

7: Clean Up Your Database

The free plugin WP-Optimize will quickly do the trick. This plugin cleans out your database by removing revisions and other unnecessary data.

8: Compress Your Images!

Images are usually the largest file sizes on WordPress sites. Compressing a 1MB image down to 100KB can make a world of a difference. For JPGs I recommend the free tool JPEGmini. For PNGs you can use TinyPNG. Their website allows free PNG compression and they also sell a handy Photoshop plugin that will allow you to export smaller PNGs seamlessly.

Using these 8 steps, speeding up a WordPress based iOS application will be a much simpler process going forward. This is just one of the many “tips and tricks” we’ve learned along the way, and we are happy to begin sharing them with the development community. Don’t forget to follow us on Facebook, Twitter and Instagram to get updates on new blog posts!