Interagindo no . Após uma troca rápida e amigável, resolvi explorar mais o perfil dele e encontrei o . Mas uma coisa me incomodou: eu não conseguia compartilhar a data específica que uma notícia surgiu. Então, pensei: "por que não abrir um PR?"
Estrutura do site
O . Como um GitHub Pages clássico, é um SSG Jekyll.
Descobri mexendo nesse projeto que o GitHub pages agora tem a possibilidade de hospedar o resultado de uma GitHub Action:
! A opção se chama port!
Ok, em segunda olhada eu vi que também tem disponível facilmente na página web da própria , então vou ficar com ele. Portanto, passar a opção da porta para o rake.
Para isso, usei um padrão:
rule(/^run-[0-9]+$/) do |t|
port = t.name["run-".length() ..]
run_jekyll port: port
end
Eu pego o nome da task e dela a substring após run-. Então passo para a função run_jekyll com o parâmetro nomeado port:
def run_jekyll(port: nil)
# debugging
puts "port? #{port}"
require "jekyll"
opts = {
'show_drafts' => true,
'watch' => true,
'serving' => true
}
opts['port'] = port unless port.nil?
# mais debugging
puts opts
conf = Jekyll.configuration(opts)
Jekyll::Commands::Build.process conf
Jekyll::Commands::Serve.process conf
end
Essa função foi obtida a partir da task orginial run, que ficou assim:
task :run do |t|
run_jekyll
end
Fazendo isso, temos as APIs:
rake run # vai rodar na porta padrão
rake run-4001 # vai rodar na porta 4001
Bem, isso funciona e funciona bem. Mas o jeito, digamos, mais padrão de passar parâmetros para o rake é usando chaves. Vamos tentar? Estou seguindo a , o valor de location.search será "?status=true". Ok, então posso fazer um simples location.search = "?a=b", correto? Bem, na verdade, não...
Por que não? Porque isso muda o comportamento atual da página Genomics Daily, que é carregar o recurso dinamicamente sem haver recarga de página. Portanto, se eu quiser oferecer alguma alteração para permitir compartilhar a página do dia escolhida no archive, eu não posso escolher fazer assim. Mas, que outras opções eu tenho?
Descobri .
Ao clicar, você deve perceber que passou a aparecer na URL um query param com o valor marmota=1, e ao clicar novamente muda para marmota=2 e sai incrementando o valor associado à chave marmota para todo e qualquer clique.
A implementação foi assim:
function alteraQueryParam() {
const url = new URL(window.location.href);
if (!window.history) {
alert("Este browser aparenta não ter API de history")
return
}
const paramName = 'marmota'
let x = url.searchParams.get(paramName)
if (!!x) {
x = Number(x) + 1
} else {
x = 1
}
url.searchParams.set(paramName, x);
window.history.pushState(null, '', url.toString());
}
Habilitando o Genomics Daily localmente
Clonei o repositório e a primeira coisa que fiz foi copiar o Rakefile do Computaria para o meu clone local (sem commitar, claro). E quando dou um rake run... ele não deu certo! Por quê? Porque ele não encontrava o tal de minima. Mas onde estava esse minima?
), mas isso implicaria remover a localidade do código JS de dentro do HTML. Então, qual evento a mais eu consigo detectar? Bem, uma das alternativas (talvez não a melhor) é interceptar o evento load do objeto window:
<script>
window.addEventListener('load', () => {
console.log('oie')
})
</script>
Apertei F5 e lá estava a mensagem do console. Ok, satisfeito. Enquanto escrevia este post eu me questionei, "será que não poderia ter usado window.onload?"
<script>
window.onload = () => {
console.log('oie')
})
</script>
E funciona também, magnificamente bem. Nessa situação, quando termina de carregar aquilo que é necessário, podemos disparar a chamada para buscar as novas informações. Basicamente é extrair a data do query param date e, estando ele presente, chamar a mesma função que tem no evento de submissão do form. Para isso, primeiro extraí a função de carregamento de conteúdo do evento de submissão:
function loadSummary(date) {
const [year, month, day] = date.split('-');
const formattedDate = `${year.slice(2)}-${month}-${day}`;
fetch(`summary-${formattedDate}.md`)
.then(response => response.text())
.then(data => {
document.getElementById('result').innerHTML = marked.parse(data);
})
.catch(error => console.error('Error loading content:', error));
}
form.addEventListener('submit', (e) => {
e.preventDefault();
const date = document.getElementById('documentDate').value;
if (window.history) {
const url = new URL(window.location.href);
url.searchParams.set('date', date);
window.history.pushState(null, '', url.toString());
}
loadSummary(date)
});
Ficou no handler do form apenas a parte específica de resgatar o valor date e de empurrar na URL o query param. De resto, fica na função de carregar o conteúdo, loadSummary. E no carregamento:
window.onload = () => {
const url = new URL(window.location.href);
if (url.searchParams.get("date")) {
const queryDate = url.searchParams.get("date")
document.getElementById('documentDate').value = queryDate
loadSummary(queryDate)
}
}
Pronto, aqui eu estou carregando o conteúdo com loadSummary do mesmo jeito, mas também aproveitei e para evitar qualquer confusão coloquei o valor do componente do formulário para o valor correto.
Fiz alguns testes colocando a atribuição de função window.onload dentro de um setTimeout, e o resultado mostrou que o load não é disparado:
setTimeout(() => {
window.onload = () => {
const url = new URL(window.location.href);
if (url.searchParams.get("date")) {
const queryDate = url.searchParams.get("date")
document.getElementById('documentDate').value = queryDate
loadSummary(queryDate)
}
}
}, 0)
Mesmo com o intervalor de espera em 0ms. Para contornar isso, resolvi perguntar para o documento se ele já estava no estado completed. Se sim, chamava a função de carregamento, caso contrário botava o listener de evento.
setTimeout(() => {
function firstLoad() {
const url = new URL(window.location.href);
if (url.searchParams.get("date")) {
const queryDate = url.searchParams.get("date")
document.getElementById('documentDate').value = queryDate
loadSummary(queryDate)
}
}
if (document.readyState === 'complete') {
console.log("completed") // debug
firstLoad();
} else {
console.log("evento") // debug
window.onload = firstLoad
}
}, 0)
E passou pelo debugging de completed, não evento. Ok, feliz. E sem a gambiarra do setTimeout passou pelo outro ramo, perfeito.
SOCIAL SHARE CARD GENERATOR