Postagens do Instagram

Neste tutorial vamos adicionar o componente que mostra na página inicial as últimas publicações de uma conta do instagram.

HTML

A primeira coisa que vamos fazer é criar a pasta home dentro da pasta snipplets.

1. Dentro da pasta criada, adicionamos um snipplet com o nome home-instafeed.tpl com o seguinte conteúdo:

{% if settings.show_instafeed  %}
    <section class="section-instafeed-home">
        <div class="container">
            <div class="row">
                {% set instuser = store.instagram|split('/')|last %}
                <div class="col-12 text-center">
                    {% if store.instagram %}
                        <a target="_blank" href="{{ store.instagram }}" class="instafeed-title">
                            {% include "snipplets/svg/instagram.tpl" with {svg_custom_class: "icon-inline icon-2x svg-icon-text"} %}
                            <h3 class="instafeed-user">{{ instuser }}</h3>
                        </a>
                    {% else %}
                        <div class="instafeed-title">
                            {% include "snipplets/svg/instagram.tpl" with {svg_custom_class: "icon-inline icon-2x svg-icon-text"} %}
                            <h3 class="instafeed-user">{{ "Instagram" | translate }}</h3>
                        </div>
                    {% endif %}
                </div>
            </div>
        </div>
        <div id="instafeed" class="row no-gutters">  
        </div>
    </section>
{% endif %}

2. Como queremos mostrar as últimas postagens do instagram na página inicial, adicionamos a chamada ao home-instafeed.tpl dentro de templates/home.tpl.

Vale ressaltar que é uma funcionalidade opcional, por isso vai depender se ela está ativada ou não, na seção ‘Personalizar seu layout atual’, no Administrador Nuvem.

{% include 'snipplets/home/home-instafeed.tpl' %}

3.  Por fim, para o HTML, precisamos adicionar uma pasta SVG dentro da pasta snipplets. Aqui vamos adicionar os SVGs que usamos para os ícones.

instagram.tpl

<svg class="{{ svg_custom_class }}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z"/></svg>

heart.tpl

<svg class="{{ svg_custom_class }}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M458.4 64.3C400.6 15.7 311.3 23 256 79.3 200.7 23 111.4 15.6 53.6 64.3-21.6 127.6-10.6 230.8 43 285.5l175.4 178.7c10 10.2 23.4 15.9 37.6 15.9 14.3 0 27.6-5.6 37.6-15.8L469 285.6c53.5-54.7 64.7-157.9-10.6-221.3zm-23.6 187.5L259.4 430.5c-2.4 2.4-4.4 2.4-6.8 0L77.2 251.8c-36.5-37.2-43.9-107.6 7.3-150.7 38.9-32.7 98.9-27.8 136.5 10.5l35 35.7 35-35.7c37.8-38.5 97.8-43.2 136.5-10.6 51.1 43.1 43.5 113.9 7.3 150.8z"/></svg>

comments.tpl

<svg class="{{ svg_custom_class }}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M532 386.2c27.5-27.1 44-61.1 44-98.2 0-80-76.5-146.1-176.2-157.9C368.3 72.5 294.3 32 208 32 93.1 32 0 103.6 0 192c0 37 16.5 71 44 98.2-15.3 30.7-37.3 54.5-37.7 54.9-6.3 6.7-8.1 16.5-4.4 25 3.6 8.5 12 14 21.2 14 53.5 0 96.7-20.2 125.2-38.8 9.2 2.1 18.7 3.7 28.4 4.9C208.1 407.6 281.8 448 368 448c20.8 0 40.8-2.4 59.8-6.8C456.3 459.7 499.4 480 553 480c9.2 0 17.5-5.5 21.2-14 3.6-8.5 1.9-18.3-4.4-25-.4-.3-22.5-24.1-37.8-54.8zm-392.8-92.3L122.1 305c-14.1 9.1-28.5 16.3-43.1 21.4 2.7-4.7 5.4-9.7 8-14.8l15.5-31.1L77.7 256C64.2 242.6 48 220.7 48 192c0-60.7 73.3-112 160-112s160 51.3 160 112-73.3 112-160 112c-16.5 0-33-1.9-49-5.6l-19.8-4.5zM498.3 352l-24.7 24.4 15.5 31.1c2.6 5.1 5.3 10.1 8 14.8-14.6-5.1-29-12.3-43.1-21.4l-17.1-11.1-19.9 4.6c-16 3.7-32.5 5.6-49 5.6-54 0-102.2-20.1-131.3-49.7C338 339.5 416 272.9 416 192c0-3.4-.4-6.7-.7-10C479.7 196.5 528 238.8 528 288c0 28.7-16.2 50.6-29.7 64z"/></svg>

CSS

Requisito:

Ter adicionado helper classes em seu layout. Você pode seguir este pequeno tutorial para fazer isso (é só copiar e colar algumas classes, não leva mais que 1 minuto).

1. Adicionamos o seguinte SASS de cores em style-colors.scss.tpl (ou stylesheet do seu layout que possui as cores e fontes da loja). Lembre-se de que as variáveis de cores e fontes podem variar em relação ao seu layout:

{# /* // Margin and padding */ #}

%element-margin {
  margin-bottom: 20px;
}

{# /* // Instafeed */ #}

.section-instafeed-home {
  @extend %element-margin;
}

.instafeed-title {
  display: block;
  @extend %element-margin;
  color: $main-foreground;
}

.instafeed-info {
  color: $main-background;
  fill: $main-background;
  background: rgba($main-foreground, .6);
}

2. Adicione os estilos dentro do arquivo static/style-async.tpl

Se em seu layout você usar um stylesheet para CSS assíncrono, precisaremos do seguinte código dentro dele, mas se esse não for o caso, você pode unificar o CSS dos passos 1 e 2 em um único arquivo.

{# /* // Mixins */ #}

{# This mixin adds browser prefixes to a CSS property #}

@mixin prefix($property, $value, $prefixes: ()) {
  @each $prefix in $prefixes {
    #{'-' + $prefix + '-' + $property}: $value;
  }
  #{$property}: $value;
}

{# /* // Instafeed */ #}

.instafeed-user {
    display: inline-block;
    margin: 0 0 0 5px;
  line-height: 24px;
  vertical-align: top;
}

.instafeed-link {
  display: block;
  overflow: hidden;
}

.instafeed-img {
  overflow: hidden;
  position: relative;
  padding-top: 100%;
  background-position: center center;
  background-size: cover;
  @include prefix(transition, all 0.8s ease, webkit ms moz o);
  .instafeed-info {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    padding: 0;
    text-align: center;
    opacity: 0;
    @include prefix(transition, all 0.8s ease, webkit ms moz o);
    .instafeed-info-item {
      display: inline-block;
      margin-top: 45%;
    }
  }
  &:hover,
  &:focus {
    @include prefix(transform, scale(1.03), webkit ms moz o);
    .instafeed-info {
      opacity: 1;
    }
  }
}

JS

1. Precisamos aplicar as funções no arquivo store.js.tpl (ou onde você tem suas funções JS). O código que precisamos é o seguinte:

{% if settings.show_instafeed and (template == 'home') %}

        {# /* // Instagram feed */ #}

        {% if settings.show_instafeed %}
            var width = window.innerWidth;
            if (width > 767) {  
                var resolution = "standard_resolution";
            } else {
                var resolution = "low_resolution";
            }
            var feedqty =  {{ settings.instafeed_qty }};
            {% set userid = settings.instafeed_accesstoken|split('.')|first %}

            {% set instlink = '{{link}}' %}
            {% set instimg = '{{image}}' %}
            {% set instlike = '{{likes}}' %}
            var userFeed = new Instafeed({
            get: 'user',
                userId: '{{ userid }}',
                accessToken: '{{ settings.instafeed_accesstoken }}',
                resolution: resolution,
                template: '<div class="col-4"><a class="instafeed-link" href="{{instlink}}" target="_blank"><div class="instafeed-img lazyload" data-bg="{{instimg}}">{% if settings.instafeed_like %}<div class="instafeed-info"><span class="instafeed-info-item">{% include "snipplets/svg/heart.tpl" with {svg_custom_class: "icon-inline"} %} {{instlike}}</span></div>{% endif %}</div></a></div>',
                limit: feedqty
           });
           userFeed.run();
       {% endif %}
{% endif %}

2. Agora vamos precisar adicionar o plugin no arquivo external-no-dependencies.js.tpl ou no arquivo onde você tem os plugins do seu layout.

{% if settings.show_instafeed and (template == 'home') %}

{# /* Instafeed */ #}
(function(){var e;e=function(){function e(e,t){var n,r;this.options={target:"instafeed",get:"popular",resolution:"thumbnail",sortBy:"none",links:!0,mock:!1,useHttp:!1};if(typeof e=="object")for(n in e)r=e[n],this.options[n]=r;this.context=t!=null?t:this,this.unique=this._genKey()}return e.prototype.hasNext=function(){return typeof this.context.nextUrl=="string"&&this.context.nextUrl.length>0},e.prototype.next=function(){return this.hasNext()?this.run(this.context.nextUrl):!1},e.prototype.run=function(t){var n,r,i;if(typeof this.options.clientId!="string"&&typeof this.options.accessToken!="string")throw new Error("Missing clientId or accessToken.");if(typeof this.options.accessToken!="string"&&typeof this.options.clientId!="string")throw new Error("Missing clientId or accessToken.");return this.options.before!=null&&typeof this.options.before=="function"&&this.options.before.call(this),typeof document!="undefined"&&document!==null&&(i=document.createElement("script"),i.id="instafeed-fetcher",i.src=t||this._buildUrl(),n=document.getElementsByTagName("head"),n[0].appendChild(i),r="instafeedCache"+this.unique,window[r]=new e(this.options,this),window[r].unique=this.unique),!0},e.prototype.parse=function(e){var t,n,r,i,s,o,u,a,f,l,c,h,p,d,v,m,g,y,b,w,E,S,x,T,N,C,k,L,A,O,M,_,D;if(typeof e!="object"){if(this.options.error!=null&&typeof this.options.error=="function")return this.options.error.call(this,"Invalid JSON data"),!1;throw new Error("Invalid JSON response")}if(e.meta.code!==200){if(this.options.error!=null&&typeof this.options.error=="function")return this.options.error.call(this,e.meta.error_message),!1;throw new Error("Error from Instagram: "+e.meta.error_message)}if(e.data.length===0){if(this.options.error!=null&&typeof this.options.error=="function")return this.options.error.call(this,"No images were returned from Instagram"),!1;throw new Error("No images were returned from Instagram")}this.options.success!=null&&typeof this.options.success=="function"&&this.options.success.call(this,e),this.context.nextUrl="",e.pagination!=null&&(this.context.nextUrl=e.pagination.next_url);if(this.options.sortBy!=="none"){this.options.sortBy==="random"?M=["","random"]:M=this.options.sortBy.split("-"),O=M[0]==="least"?!0:!1;switch(M[1]){case"random":e.data.sort(function(){return.5-Math.random()});break;case"recent":e.data=this._sortBy(e.data,"created_time",O);break;case"liked":e.data=this._sortBy(e.data,"likes.count",O);break;case"commented":e.data=this._sortBy(e.data,"comments.count",O);break;default:throw new Error("Invalid option for sortBy: '"+this.options.sortBy+"'.")}}if(typeof document!="undefined"&&document!==null&&this.options.mock===!1){m=e.data,A=parseInt(this.options.limit,10),this.options.limit!=null&&m.length>A&&(m=m.slice(0,A)),u=document.createDocumentFragment(),this.options.filter!=null&&typeof this.options.filter=="function"&&(m=this._filter(m,this.options.filter));if(this.options.template!=null&&typeof this.options.template=="string"){f="",d="",w="",D=document.createElement("div");for(c=0,N=m.length;c<N;c++){h=m[c],p=h.images[this.options.resolution];if(typeof p!="object")throw o="No image found for resolution: "+this.options.resolution+".",new Error(o);E=p.width,y=p.height,b="square",E>y&&(b="landscape"),E<y&&(b="portrait"),v=p.url,l=window.location.protocol.indexOf("http")>=0,l&&!this.options.useHttp&&(v=v.replace(/https?:\/\//,"//")),d=this._makeTemplate(this.options.template,{model:h,id:h.id,link:h.link,type:h.type,image:v,width:E,height:y,orientation:b,caption:this._getObjectProperty(h,"caption.text"),likes:h.likes.count,comments:h.comments.count,location:this._getObjectProperty(h,"location.name")}),f+=d}D.innerHTML=f,i=[],r=0,n=D.childNodes.length;while(r<n)i.push(D.childNodes[r]),r+=1;for(x=0,C=i.length;x<C;x++)L=i[x],u.appendChild(L)}else for(T=0,k=m.length;T<k;T++){h=m[T],g=document.createElement("img"),p=h.images[this.options.resolution];if(typeof p!="object")throw o="No image found for resolution: "+this.options.resolution+".",new Error(o);v=p.url,l=window.location.protocol.indexOf("http")>=0,l&&!this.options.useHttp&&(v=v.replace(/https?:\/\//,"//")),g.src=v,this.options.links===!0?(t=document.createElement("a"),t.href=h.link,t.appendChild(g),u.appendChild(t)):u.appendChild(g)}_=this.options.target,typeof _=="string"&&(_=document.getElementById(_));if(_==null)throw o='No element with id="'+this.options.target+'" on page.',new Error(o);_.appendChild(u),a=document.getElementsByTagName("head")[0],a.removeChild(document.getElementById("instafeed-fetcher")),S="instafeedCache"+this.unique,window[S]=void 0;try{delete window[S]}catch(P){s=P}}return this.options.after!=null&&typeof this.options.after=="function"&&this.options.after.call(this),!0},e.prototype._buildUrl=function(){var e,t,n;e="https://api.instagram.com/v1";switch(this.options.get){case"popular":t="media/popular";break;case"tagged":if(!this.options.tagName)throw new Error("No tag name specified. Use the 'tagName' option.");t="tags/"+this.options.tagName+"/media/recent";break;case"location":if(!this.options.locationId)throw new Error("No location specified. Use the 'locationId' option.");t="locations/"+this.options.locationId+"/media/recent";break;case"user":if(!this.options.userId)throw new Error("No user specified. Use the 'userId' option.");t="users/"+this.options.userId+"/media/recent";break;default:throw new Error("Invalid option for get: '"+this.options.get+"'.")}return n=e+"/"+t,this.options.accessToken!=null?n+="?access_token="+this.options.accessToken:n+="?client_id="+this.options.clientId,this.options.limit!=null&&(n+="&count="+this.options.limit),n+="&callback=instafeedCache"+this.unique+".parse",n},e.prototype._genKey=function(){var e;return e=function(){return((1+Math.random())*65536|0).toString(16).substring(1)},""+e()+e()+e()+e()},e.prototype._makeTemplate=function(e,t){var n,r,i,s,o;{% raw %}r=/(?:\{{2})([\w\[\]\.]+)(?:\}{2})/,{% endraw %} n=e;while(r.test(n))s=n.match(r)[1],o=(i=this._getObjectProperty(t,s))!=null?i:"",n=n.replace(r,function(){return""+o});return n},e.prototype._getObjectProperty=function(e,t){var n,r;t=t.replace(/\[(\w+)\]/g,".$1"),r=t.split(".");while(r.length){n=r.shift();if(!(e!=null&&n in e))return null;e=e[n]}return e},e.prototype._sortBy=function(e,t,n){var r;return r=function(e,r){var i,s;return i=this._getObjectProperty(e,t),s=this._getObjectProperty(r,t),n?i>s?1:-1:i<s?1:-1},e.sort(r.bind(this)),e},e.prototype._filter=function(e,t){var n,r,i,s,o;n=[],r=function(e){if(t(e))return n.push(e)};for(i=0,o=e.length;i<o;i++)s=e[i],r(s);return n},e}(),function(e,t){return typeof define=="function"&&define.amd?define([],t):typeof module=="object"&&module.exports?module.exports=t():e.Instafeed=t()}(this,function(){return e})}).call(this);

{% endif %}

3. Como neste tutorial usamos a técnica de lazy load com o plugin Lazysizes, precisamos adicioná-lo. Para ver como fazer isso, você pode ler este pequeno artigo e continuar com este tutorial.

Configurações

No arquivo config/settings.txt vamos adicionar o checkbox para habilitar ou desabilitar o componente, assim como os campos para colocar o Access Token do Instagram, o número de publicações e se queremos tornar visível a quantidade de “Like” de cada publicação

title
        title = Publicaciones de Instagram
    description
        description = El Feed de Instagram muestra automáticamente tus últimas publicaciones en la página de inicio de tu tienda
    subtitle
        subtitle = Configurar cuenta de Instagram
    i18n_input
        name = instafeed_accesstoken
        description = Access Token (Necesario para validar tu cuenta)
    subtitle
        subtitle = <a target='_blank' href='https://ayuda.tiendanube.com/como-mostrar-mis-publicaciones-de-instagram-en-mi-tienda-nube'>¿Cómo obtener el Access Token?</a>
    checkbox
        name = show_instafeed
        description = Mostrar tus publicaciones de Instagram en la página de inicio de tu tienda
    subtitle
               subtitle = ¿Cuántas publicaciones querés mostrar?
    dropdown
                name = instafeed_qty
                values
                    3 = 3 publicaciones
                              6 = 6 publicaciones
                    9 = 9 publicaciones
    checkbox
        name = instafeed_like
        description = Mostrar la cantidad de <em>‘Me gusta’</em> de cada publicación

Tradução

Nesta etapa, adicionamos os textos para as traduções no arquivo config/translations.txt

es "Publicaciones de Instagram"
pt "Postagens do Instagram"
es_mx "Publicaciones de Instagram"

es "El Feed de Instagram muestra automáticamente tus últimas publicaciones en la página de inicio de tu tienda"
pt "O feed do Instagram exibe automaticamente suas últimas postagens na página inicial da sua loja."
es_mx "El Feed de Instagram muestra tus últimas publicaciones en la página de inicio."

es "Mostrar tus publicaciones de Instagram en la página de inicio de tu tienda"
pt "Exibir suas postagens do Instagram na página inicial da sua loja."
es_mx "Mostrar tus publicaciones de Instagram en la página de inicio de tu tienda online"

es "Configurar cuenta de Instagram"
pt "Configurar conta do Instagram"
es_mx "Configurar tu cuenta de Instagram"

es "<a target='_blank' href='https://ayuda.tiendanube.com/como-mostrar-mis-publicaciones-de-instagram-en-mi-tienda-nube'>¿Cómo obtener el Access Token?</a>"
pt "<a target='_blank' href='https://atendimento.nuvemshop.com.br/como-adicionar-o-feed-do-instagram'>Como obter o Access Token?</a>"
es_mx "<a target='_blank' href='https://ayuda.tiendanube.com/como-mostrar-mis-publicaciones-de-instagram-en-mi-tienda-nube'>¿Cómo obtener el Access Token?</a>"

es "Access Token (Necesario para validar tu cuenta)"
pt "Access Token (Necessário para validar sua conta)"
es_mx "Access Token (Necesario para validar tu cuenta)"

es "Imágenes en las publicaciones de Instagram"
pt "Imagens em posts do Instagram"
es_mx "Imágenes en las publicaciones de Instagram"

es "Imágenes en las publicaciones de Instagram"
pt "Imagens em posts do Instagram"
es_mx "Imágenes en las publicaciones de Instagram"

es "¿Cuántas publicaciones querés mostrar?"
pt "Quantos posts você deseja exibir?"
en "How many posts do you want to show?"
es_mx "¿Cuántas publicaciones quieres mostrar?"

es "3 publicaciones"
pt "3 posts"
en "3 posts"
es_mx "3 publicaciones"

es "6 publicaciones"
pt "6 posts"
en "6 posts"
es_mx "6 publicaciones"

es "9 publicaciones"
pt "9 posts"
en "9 posts"
es_mx "9 publicaciones"

es "Mostrar la cantidad de <em>‘Me gusta’</em> de cada publicación"
pt "Exibir quantidade de <em>“Likes”</em> de cada post"
es_mx "Mostrar los <em>‘Me gusta’</em> de cada publicación"

Ativação

Por fim, você pode ativar as postagens do Instagram no Administrador Nuvem, na seção ‘Personalizar seu layout atual’, dentro de ‘Redes sociais’:

Se você precisar de ajuda para configurar a conta do Instagram, você pode visitar este artigo com mais detalhes: Como mostrar as fotos do Instagram no layout?