Oops, quebrei o about, e agora?
Novo capítulo: guerra das tags
Após a publicação Usando as tags - Parte 1: página de tags,
as tags passaram a ser publicadas no hamburguer, e isso passou despercebido. Com isso, passei a adotar
um novo/velho padrão para mostrar as páginas: apenas mostrar o que está com show: true
,
tal qual em Criando páginas discretas.
Mas agora as motivações são distintas, bem distintas. Não pretendo mais evitar exibir
coisas na barra superior e mostrar no hamburguer: quero mostrar em ambos. Então, como
novo protocolo, vou mostrar na barra de navegação se tiver título e tiver show == true
,
portanto alterando o header.html
assim:
<div class="trigger">
{% for my_page in site.pages %}
- {% if my_page.title %}
- <a class="page-link{% unless my_page.show %} large-hidden{% endunless %}" href="{{ my_page.url | prepend: site.baseurl }}">{{ my_page.title }}</a>
+ {% if my_page.title and my_page.show %}
+ <a class="page-link" href="{{ my_page.url | prepend: site.baseurl }}">{{ my_page.title }}</a>
{% endif %}
{% endfor %}
</div>
Abaixo a publicação original:
Fui colocar no ar o carregador de pipeline, e acabei fazer algumas bagunças com o Sobre. “Quão bagunçado?” você pode se perguntar. Bem, deixe eu mostrar:
Porém o que eu queria mesmo era algo assim, como estava antes:
Bem, com isso, sabe o que consegui? Basicamente tornar tudo feito no Criando páginas discretas pouco útil.
A intenção original das “páginas discretas” foi não enfeiar a parte ao redor do “Sobre”. Aproveitei essa ocasião então para deixar esses outros links dento do hamburguer:
Ajeitando o Rakefile para gerar pasta de assets
Eu comecei como normalmente começo a escrever artigo:
rake _drafts/oops-about.md
Porém só com um pouquinho do artigo preenchido e eu percebi um erro que eu cometi: ainda não havia criado a pasta de assets. Então, para minimamente automatizar isso, resolvi criar minha própria pasta de assets para quando eu precisar. E automatizar isso.
Então, minha primeira reação foi correr atrás de um padrão de diretório. Porém
as tasks do tipo directory
só aceitam strings. Para aceitar padrões, preciso
invariavelmente usar rule
. Então criei a rule
adequada para refletir o
formato do diretório:
rule(/^assets\/[^\/]+\/?$/) do |t|
puts "criando diretório de assets #{t.name}"
mkdir t.name
end
Aparentemente, tudo bem, com isso o diretório passou a ser criado. Mas e para
chamar a task dentro da outra? Achei
essa resposta e fui tentar. Isolei
em uma task de teste chamada de t
:
task :t do |t|
Rake::Task["/assets/lala"].invoke
end
E, bem, no primeiro momento eu ainda não havia percebido que estava tentando criar a partir da raiz… mas, quer saber de algo? Esse teste ter falhado me fez aprender mais coisas em Ruby!
Pois bem, cheguei a conclusão que eu precisaria invocar uma task
e passar parâmetros pra ela. E para evitar duplicar código, eu só
teria uma única task :assets_dir
que iria receber como argumento
o novo caminho. Com isso, finalmente chegou a oportunidade de
praticar
tasks que recebem parâmetros.
Então declarei a task com o argument :new_dir
e organizei t
para
chamar essa nova task.
Para invocar uma task programaticamente com argumentos, me baseei
nessa resposta:
basicamente se chama .invoke
com os arugmentos. Por exemplo:
Rake::Task[:assets_dir].invoke "assets/lala"
E as regras adaptadas para isso:
task :assets_dir, [:new_dir] do |t, args|
puts "criando diretório de assets #{args.new_dir}"
mkdir args.new_dir
end
task :t do |t|
Rake::Task[:assets_dir].invoke "/assets/lala"
end
Uma task com parâmetros é declarada como uma task, e após seu
identificador de nome vem um vetor com os nomes dos argumentos.
Para acessar os argumentos, é necessário passar um bloco de código
que receba a task de trabalho e os argumentos, por conveniência
denotados como |t, args|
.
Aqui eu finalmente consegui enxergar que tinha algo estranho com o
argumento, ele estava recebendo uma barra /
a mais do que deveria
logo no começo da palavra. Existia a solução de remover essa /
via Ruby chamando args.new_dir[1..]
, ou simplesmente corrigindo o
texto. Optei pelo segundo, mais fácil. Aproveitei e fiz a task
baseada no nome do diretório chamar o :assets_dir
:
rule(/^assets\/[^\/]+\/?$/) do |t|
Rake::Task[:assets_dir].invoke t.name
end
task :assets_dir, [:new_dir] do |t, args|
puts "criando diretório de assets #{args.new_dir}"
mkdir args.new_dir
end
task :t do |t|
Rake::Task[:assets_dir].invoke "assets/lala"
end
Bem, agora eu me toquei do erro do começo da experiência: /assets/lala
,
com /
no começo. E se eu remover a barra? Será que invoca?
Aqui eu adaptei t
para chamar corretamente:
task :t do |t|
Rake::Task["assets/lala"].invoke
end
E assim funcionou, PERFEITAMENTE! Corri atrás de coisas mais complexas e, já que eu as colhi, aproveitei e deixei aqui para conhecimento futuro.
Na task rule(/^_drafts\/.*\.md$/)
, coloquei o diretório destino de
assets como assetsDir = "/assets/#{radix}/"
e invoquei
Rake::Task[assetsDir[1..]].invoke
.
Correção no about
Para começar, eu quero sumir com tudo que não seja de interessante
de dentro da listagem do /about
. Bem, o jeito
foi criando um novo campo no frontmatter. Adicionado o campo interesting
que, se tiver
com o valor true
, vai ser listado no about. Toda a questão de quebrar a string
em partes agora não se faz mais necessária:
{% for my_page in site.pages %}
- {%- assign my_page_parts = my_page.url | downcase | split: "." -%}
- {%- unless
- my_page_parts[-1] == "css" or
- my_page_parts[-1] == "xml" or
- my_page_parts[0] == "/" or
- my_page.url == page.url %}
+ {%- if my_page.interesting %}
- [{% if my_page.title %}{{my_page.title}}{% else %}`{{my_page.url}}`{% endif %}]({{ my_page.url | prepend: site.baseurl }})
{%- endif -%}
{% endfor %}
E para exibir apenas o que se deseja bastou um simples interesting: true
no frontmatter.
Ajeitando o hamburguer
Ok, resolvido o problema da exibição em tela grande, e agora, para lidar em telas pequenas, como as de celular?
Bem, a primeira dica que eu tive foi analisando a página gerada: existe uma <div>
que engloba
o <a>Sobre</a>
. E essa <div>
tem a classe trigger
.
Cheguei no arquivo que ainda muito pouco havia mexido:
/_sass/_layout.scss
. Por sinal,
apenas nele que se tem declaração CSS para essa classe. Logo, deve estar aí o segredo
do hamburguer. E, bem? Meio que estava lá sim. Quando se chega no nível que está
indicado no scss
como sendo @include media-query($on-palm)
, o .trigger
ficava assim:
.trigger {
clear: both;
display: none;
}
&:hover .trigger {
display: block;
padding-bottom: 5px;
}
.page-link {
display: block;
padding: 5px 10px;
&:not(:last-child) {
margin-right: 0;
}
margin-left: 20px;
}
Para mim isso significou que, ao estar em um tamanho pequeno, o
bloco trigger
fica invisível (.trigger { display: none; }
),
mas se tiver o efeito de onhover
ele passa a expandir o hamburger.
&:hover .trigger {
display: block;
padding-bottom: 5px;
}
Com essa informação em mãos, vamos atacar o problema. Eu quero que
os links existam no hamburguer porém não fora. Posso resolver isso
com CSS, adicionando uma nova class: .large-hidden
. Para ser
exatamente o que se pretendia usar, vou declarar para elementos
que possuam ambos .large-hidden
e também para .page-link
.
Para atender duas classes ao mesmo tempo, me baseei nessa resposta:
.page-link.large-hidden {
display: none;
}
@include media-query($on-palm) {
//....
.page-link.large-hidden {
display: block;
}
}
Ok, agora isso acontece do jeitinho que havia imaginado. Só falta preencher as classes adequadamente.
Agora, parto para /_includes/header.html
.
Ele estava gerando assim os links:
<div class="trigger">
{% for my_page in site.pages %}
{% if my_page.title and my_page.show %}
<a class="page-link" href="{{ my_page.url | prepend: site.baseurl }}">{{ my_page.title }}</a>
{% endif %}
{% endfor %}
</div>
Isso evitava completamente de ser exibido. Agora, eu poderia pegar esse mesmo mecanismo
que a não presença do title
e construir em cima dele a adição da classe:
<div class="trigger">
{% for my_page in site.pages %}
{% if my_page.title %}
<a class="page-link{% unless my_page.show %} large-hidden{% endunless %}" href="{{ my_page.url | prepend: site.baseurl }}">{{ my_page.title }}</a>
{% endif %}
{% endfor %}
</div>