diff --git a/.editorconfig b/.editorconfig index 5438c99..697a547 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,5 +1,6 @@ -[*] root = true + +[*] charset = utf-8 end_of_line = lf indent_size = 2 diff --git a/.github/workflows/languagetool.yml b/.github/workflows/languagetool.yml deleted file mode 100644 index 9136a02..0000000 --- a/.github/workflows/languagetool.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Language Tool - -on: - pull_request: - branches: - - main - types: - - opened - - reopened - - synchronize - - ready_for_review - -jobs: - en_US: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: reviewdog/action-languagetool@v1 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - reporter: github-pr-review - level: info - patterns: '**/*.md' diff --git a/.github/workflows/live.yml b/.github/workflows/live.yml index 54e6c28..3cba291 100644 --- a/.github/workflows/live.yml +++ b/.github/workflows/live.yml @@ -9,7 +9,7 @@ jobs: build: runs-on: ubuntu-latest env: - HUGO_VERSION: 0.111.3 + HUGO_VERSION: 0.121.1 steps: - uses: actions/setup-node@v3 with: diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 37b7a7f..3f7140c 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -14,7 +14,7 @@ jobs: build: runs-on: ubuntu-latest env: - HUGO_VERSION: 0.111.3 + HUGO_VERSION: 0.121.1 steps: - uses: actions/setup-node@v3 with: diff --git a/assets/js/index.js b/assets/js/index.js index 440ff59..7c5c78b 100644 --- a/assets/js/index.js +++ b/assets/js/index.js @@ -62,4 +62,21 @@ function handleScroll() { } } +function toggleI18nMenu(e) { + const i18nMenu = document.getElementById('i18n-menu'); + + if (e.type === 'focusout' && i18nMenu.contains(e.relatedTarget)) { + return; + } + + i18nMenu.classList.toggle('hidden'); +} + +const i18nButton = document.getElementById('i18n-btn'); + +if (i18nButton) { + i18nButton.addEventListener('click', toggleI18nMenu); + i18nButton.addEventListener('focusout', toggleI18nMenu); +} + window.addEventListener('DOMContentLoaded', main); diff --git a/config.pr.toml b/config.pr.toml index 7e806a1..427d84c 100644 --- a/config.pr.toml +++ b/config.pr.toml @@ -1,5 +1,5 @@ baseURL = '/' -languageCode = 'en-us' +defaultContentLanguage = 'en' title = 'Leonardo Prado' sectionPagesMenu = "main" disableKinds = ['taxonomy', 'term'] @@ -8,20 +8,45 @@ summaryLength = 40 [params] dateFormat = 'Jan 02, 2006' iconSize = '40px' + [menu] -[[menu.main]] - identifier = 'blog' - name = 'Blog' - title = 'Blog' - pageref = '/blog' - weight = -110 -[[menu.main]] - identifier = 'about' - name = 'About' - title = 'About' - pageref = '/about' - weight = -100 + [[menu.main]] + identifier = 'blog' + name = 'Blog' + title = 'Blog' + pageref = '/blog' + weight = -110 + [[menu.main]] + identifier = 'about' + name = 'About' + title = 'About' + pageref = '/about' + weight = -100 [markup] [markup.highlight] noClasses = false + +[languages] + [languages.en] + languageCode = 'en' + languageName = 'English' + weight = 1 + [languages.pt] + languageCode = 'pt' + languageName = 'Português' + weight = 2 + [languages.pt.permalinks] + [languages.pt.permalinks.section] + about = 'sobre' + [languages.pt.menus] + [[languages.pt.menus.main]] + identifier = 'blog' + name = 'Blog' + title = 'Blog' + pageref = '/blog' + [[languages.pt.menus.main]] + identifier = 'about' + name = 'Sobre' + title = 'Sobre' + pageref = '/about' diff --git a/config.toml b/config.toml index 458a8eb..cf73ea3 100644 --- a/config.toml +++ b/config.toml @@ -1,5 +1,5 @@ baseURL = '/' -languageCode = 'en-us' +defaultContentLanguage = 'en' title = 'Leonardo Prado' sectionPagesMenu = "main" disableKinds = ['taxonomy', 'term'] @@ -9,20 +9,45 @@ summaryLength = 40 dateFormat = 'Jan 02, 2006' iconSize = '40px' googleAnalyticsTag = 'G-C6FZCFZCC4' + [menu] -[[menu.main]] - identifier = 'blog' - name = 'Blog' - title = 'Blog' - pageref = '/blog' - weight = -110 -[[menu.main]] - identifier = 'about' - name = 'About' - title = 'About' - pageref = '/about' - weight = -100 + [[menu.main]] + identifier = 'blog' + name = 'Blog' + title = 'Blog' + pageref = '/blog' + weight = -110 + [[menu.main]] + identifier = 'about' + name = 'About' + title = 'About' + pageref = '/about' + weight = -100 [markup] [markup.highlight] noClasses = false + +[languages] + [languages.en] + languageCode = 'en' + languageName = 'English' + weight = 1 + [languages.pt] + languageCode = 'pt' + languageName = 'Português' + weight = 2 + [languages.pt.permalinks] + [languages.pt.permalinks.section] + about = 'sobre' + [languages.pt.menus] + [[languages.pt.menus.main]] + identifier = 'blog' + name = 'Blog' + title = 'Blog' + pageref = '/blog' + [[languages.pt.menus.main]] + identifier = 'about' + name = 'Sobre' + title = 'Sobre' + pageref = '/about' diff --git a/content/_index.pt.md b/content/_index.pt.md new file mode 100644 index 0000000..72179c6 --- /dev/null +++ b/content/_index.pt.md @@ -0,0 +1,13 @@ +--- +title: "Leonardo Prado" +date: 2023-01-04T17:08:40-03:00 +command: cd ~ +translatedBy: amanda-sato +--- + +# Olá 👋 + +Eu sou Leo, e este é o meu blog, meu espaço pessoal na web. Em breve, estarei escrevendo sobre tecnologia e alguns outros tópicos interessantes. + +Espero que você goste da leitura! + diff --git a/content/about/_index.pt.md b/content/about/_index.pt.md new file mode 100644 index 0000000..2e09a88 --- /dev/null +++ b/content/about/_index.pt.md @@ -0,0 +1,17 @@ +--- +title: Sobre +slug: sobre +date: 2023-03-11T15:43:00-00:00 +command: whoami +translatedBy: amanda-sato +--- + +# Eu 👨‍💻 + +Olá, meu nome é Leonardo Cavalcante do Prado, sou um Engenheiro DevOps brasileiro, vindo da região Nordeste do País. + +Minha paixão por trabalhos criativos remonta aos meus primeiros anos, e inicialmente a expressei através do desenho. Até tenho algumas de minhas obras publicadas online, e posso compartilhá-las aqui no futuro. Depois, eu me graduei em Engenharia da Computação pela Universidade Federal do Vale do São Francisco (UNIVASF). Embora eu tenha inclinação para artes, eu também sempre tive um grande interesse nas matérias [CTEM](https://pt.wikipedia.org/wiki/STEM) - ou [STEAM](https://en.wikipedia.org/wiki/Science,_technology,_engineering,_and_mathematics), em inglês. Eu, particularmente, acho fascinantes as maneiras criativas pelas quais a abstração é usada para resolver problemas complexos e dar sentido ao desconhecido. + +Programação, resolução de problemas, GNU Linux, desenvolvimento web, DevOps, automação e Agile são todas áreas que capturaram minha atenção ao longo dos anos. Fui incentivado por colegas, postagens em blogs e especialmente por minha esposa a compartilhar meu conhecimento e experiências, sendo uma das razões pelas quais criei este blog. Escrever também me ajuda a manter-me atualizado e alimenta minha curiosidade e vontade de aprender. + +Espero que você aprecie a leitura do meu blog tanto quanto eu aprecio escrevê-lo 😁. diff --git a/content/blog/_index.pt.md b/content/blog/_index.pt.md new file mode 100644 index 0000000..53219f2 --- /dev/null +++ b/content/blog/_index.pt.md @@ -0,0 +1,10 @@ +--- +title: "Blog" +date: 2023-01-04T17:08:40-03:00 +command: "ls -la" +translatedBy: amanda-sato +--- + +Olá👋, eu estou escrevendo sem um calendário específico, e sobre coisas que, no momento da escrita, me interessem mais. A ideia é que eu possa aprender ao mesmo tempo em que compartilho conhecimento. **_Aprenda em público_** é o que eles dizem. + + diff --git a/content/blog/hugo-tailwind-cf-pages--and-gh-actions.pt.md b/content/blog/hugo-tailwind-cf-pages--and-gh-actions.pt.md new file mode 100644 index 0000000..8e26230 --- /dev/null +++ b/content/blog/hugo-tailwind-cf-pages--and-gh-actions.pt.md @@ -0,0 +1,115 @@ +--- +title: "Hugo, Tailwind, Cloudflare Pages e GitHub Actions" +slug: hugo-tailwind-cloudflare-pages-e-gitHub-actions +date: 2023-03-14T19:14:47Z +language: pt +translatedBy: amanda-sato +--- + + +Neste post, discuto a tech stack deste blog e as decisões por trás dela. É meu primeiro conteúdo em um bom tempo, espero que você o ache útil. + + + +A vida e a carreira mudaram bastante desde a minha última [presença](https://medium.com/sysvale/iac-infraestrutura-como-c%C3%B3digo-c514a869b88d) na web três anos atrás. Fiz a transição completa para o mundo DevOps e comecei a trabalhar com CI/CD, IaC, automação e toneladas de YAML diariamente. No entanto, o mundo da tecnologia está em constante movimento, e senti a necessidade de uma forma de continuar aprendendo e me mantendo atualizado. Por isso, este blog foi criado, sendo também uma das razões para escolher cada uma das tecnologias discutidas nas seções seguintes. + +## Hugo + +Além de sua popularidade e velocidade, o Hugo utiliza Go e seus modelos de templates. Tenho experiência prática com o Helm, que também utiliza essa mesma stack. Portanto, escolher o Hugo me permitiria intercambiar habilidades entre essas ferramentas. Ao utilizá-lo, eu aprimoraria minhas habilidades no Helm e vice-versa. + +Algumas pessoas poderiam listar os modelos de Go como a razão para não escolher o Hugo, curiosamente, foi isso que me atraiu para ele. No entanto, tenho que concordar que, à primeira vista, não é tão intuitivo quanto outros motores de templates, como [jinja2](https://jinja.palletsprojects.com/en/3.1.x/templates/). Para ter um vislumbre de como é, o trecho abaixo mostra o código Hugo para a [página](/blog) deste post no blog. + +```html +{{ define "main" }} +{{ $shouldCenter := cond (gt (len .Pages) 0) "text-center" "" }} +
+ {{ .Content }} +
+ +{{ if len .Pages }} +
+

All articles

+ + +
+{{ end }} +{{ end }} +``` + +## Tailwind + +O Tailwind é um framework muito popular, e sua abordagem baseada em utilitários afirma exigir praticamente nenhuma escrita de CSS personalizado. Isso parecia muito persuasivo, já que a popularidade facilitaria encontrar recursos online, e sua abordagem se alinharia ao meu conhecimento prévio -- Não tenho muita experiência em frontend, então escrever CSS personalizado levaria mais tempo do que eu gostaria. + +As alegações mostraram-se verdadeiras, e você pode verificar abaixo um trecho mostrando todo o CSS personalizado usado neste blog. + +```scss +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer components { + /* Isso apenas fornece um alias para um conjunto de classes + do Tailwind comumente usadas juntas. */ + .anchor { + @apply + font-medium + text-indigo-700 + dark:text-indigo-400 + hover:underline; + } +} + +/* CSS personalizado começa aqui :D */ +.terminal-cursor { + animation: cursor .8s infinite; +} + +@keyframes cursor { + from { + opacity: 0; + } + + 50% { + opacity: 1; + } + + to { + opacity: 0; + } +} +``` + +## Cloudflare Pages + +Eu precisava de uma maneira fácil de obter o máximo da hospedagem estática integrada. Algumas opções estavam disponíveis, como [GitHub pages](https://pages.github.com/), [Netlify](https://www.netlify.com/) e outros. Como eu hospedo a configuração do meu domínio no Cloudflare, a solução deles pareceu interessante, pois as coisas poderiam ser mantidas em um único lugar. Ter um [cli](https://developers.cloudflare.com/workers/wrangler/) para automatizar o fluxo de trabalho por conta própria, também parecia uma boa ideia, pois, dessa forma, eu poderia adicionar quaisquer passos personalizados que desejasse, por exemplo: + +- [limpar o cache DNS após implantações.](https://github.com/o-leolleo/blog/blob/main/.github/workflows/cicd.yml#L85) +- [ter suporte para ambientes de recursos com limpeza automática em pull requests.](https://github.com/o-leolleo/blog/blob/main/.github/workflows/clean-up.yml) +- quaisquer verificações automatizadas futuras. + +O Wrangler (a CLI) também possui uma biblioteca oficial [GitHub action](https://github.com/marketplace/actions/deploy-to-cloudflare-workers-with-wrangler) com boa documentação e que eu uso para implantar este blog. + +## GitHub Actions + +Esta é a ferramenta CI/CD integrada ao GitHub. Além de ser uma solução nativa, é uma ferramenta muito fácil de usar com uma comunidade extensa ao seu redor. Você pode encontrar uma ação para praticamente tudo e também criar a sua própria quando as existentes não se encaixam. +Tem uma documentação muito boa e uma estrutura muito clara. Não precisei pensar muito e fui direto usá-la. + +## Conclusão + +Finalmente, reuni as ferramentas e consegui arranjar tempo para escrever este primeiro post em muito tempo. As ferramentas escolhidas tornaram todo o processo tranquilo, especialmente devido ao conteúdo e à comunidade ao seu redor. Com o tempo, posso preencher este espaço na web com mais e mais conteúdo 😄. Espero que tenha gostado deste primeiro! diff --git a/content/blog/wiping-your-aws-account-with-aws-nuke-and-gitlab-ci.pt.md b/content/blog/wiping-your-aws-account-with-aws-nuke-and-gitlab-ci.pt.md new file mode 100644 index 0000000..b6dd06a --- /dev/null +++ b/content/blog/wiping-your-aws-account-with-aws-nuke-and-gitlab-ci.pt.md @@ -0,0 +1,207 @@ +--- +title: "Limpando sua conta AWS com o AWS Nuke e o Gitlab CI" +slug: limpando-sua-conta-aws-com-aws-nuke-e-gitlab-ci +date: 2023-07-10T21:54:55+01:00 +draft: false +language: pt +translatedBy: amanda-sato +--- + +Apagar, limpar sua conta AWS, parece uma ação muito perigosa e destrutiva, e de fato é. Especialmente quando alguém diz que isso pode ser feito automaticamente e em um cronograma. Problemas surgem mesmo se você não mexer na sua infraestrutura, então por que destruí-la de tempos em tempos e de propósito? + + + +## Por que? + +Bem, existem alguns casos de uso válidos para esse tipo de ferramenta. **Esperançosamente, nenhum deles em ambientes ao vivo, de produção ou voltados para o usuário**. Por exemplo: +- Você possui uma conta de nuvem pessoal ou de desenvolvimento, e não deseja receber uma fatura cara da AWS quando apenas deseja testar alguma coisa. +- Você executa testes para Infraestrutura como Código (IaC), o que exige que você crie recursos e os destrua, muitas vezes deixando recursos pendentes para trás. +- Você tem uma equipe em que cada membro possui sua própria conta AWS, na qual eles podem fazer -- virtualmente -- qualquer coisa. No entanto, assim como no primeiro caso de uso, você não deseja uma fatura cara quando as pessoas estão apenas desenvolvendo e testando coisas! + + +Em tais cenários, essas contas hospedam apenas recursos que não têm a intenção de serem utilizados pelo público. Seja esse público composto por usuários de aplicativos, desenvolvedores ou qualquer pessoa além da pessoa que criou esses recursos e potencialmente seus colegas aos quais ela está apresentando as funcionalidades. Além disso, esses recursos são mais adequados para serem temporários, pois têm uma vida útil muito curta: você cria os recursos, confirma se eles funcionam conforme o esperado e, em seguida, os destrói -- os quais você frequentemente/às vezes esquece. + +Esses casos de uso são abordados pelo [aws-nuke](https://github.com/rebuy-de/aws-nuke). Ele destrói todos os seus recursos AWS nas contas especificadas 💣. _Descobri isso ao procurar por algo semelhante depois de esquecer um cluster EKS rodando por uma semana na minha conta pessoal da AWS_ 😅. Isso não me custou mais do que $50.00, pelo que me lembro, mas é útil economizar dinheiro sempre que possível e evitar custos desnecessários, especialmente porque da próxima vez eu posso não ter tanta sorte. + +O AWS Nuke pode ser executado de várias maneiras. Para ter um melhor controle e gerenciabilidade, eu prefiro executá-lo em um pipeline de integração contínua (CI). As próximas seções exploram um pouco mais essa abordagem, onde mostro como implementei isso usando o GitLab CI para destruir diariamente todos os recursos da minha conta pessoal da AWS - mantendo apenas os necessários. + +## Configurando aws-nuke + +A primeira coisa é se familiarizar com o funcionamento da ferramenta. O trecho a seguir mostra como eu o configurei com o arquivo `nuke-config.yml` --- ID da conta e nome de usuário omitidos. + +```yaml +# nuke-config.yml +regions: +- eu-north-1 +- ap-south-1 +- eu-west-3 +- eu-west-2 +- eu-west-1 +- ap-northeast-3 +- ap-northeast-2 +- ap-northeast-1 +- sa-east-1 +- ca-central-1 +- ap-southeast-1 +- ap-southeast-2 +- eu-central-1 +- us-east-1 +- us-east-2 +- us-west-1 +- us-west-2 +- global + +resource-types: + excludes: + - EC2DefaultSecurityGroupRule + +accounts: + "": + filters: + IAMUser: + - "" + IAMUserPolicyAttachment: + - " -> AdministratorAccess" + IAMVirtualMFADevice: + - "arn:aws:iam:::mfa/" + IAMUserGroupAttachment: + - " -> Admin" + IAMLoginProfile: + - "" + IAMGroup: + - "Admin" + IAMGroupPolicyAttachment: + - "Admin -> AdministratorAccess" + IAMUserAccessKey: + - " -> {{AWS_ACCESS_KEY_ID}}" + EC2KeyPair: + - "" + EC2Subnet: + - property: DefaultVPC + value: "true" + EC2DHCPOption: + - property: DefaultVPC + value: "true" + EC2InternetGateway: + - property: DefaultVPC + value: "true" + EC2RouteTable: + - property: DefaultVPC + value: "true" + EC2InternetGatewayAttachment: + - property: DefaultVPC + value: "true" + EC2VPC: + - property: IsDefault + value: "true" + CloudWatchDashboard: + - "Main" + +``` + +Aprofundando um pouco: +- Primeiro, eu declaro todas as regiões que desejo limpar. No meu caso, essas são todas as `regions` da AWS, incluindo a global --- Para recursos globais, como usuários IAM. +- Segundo, eu excluo da destruição todos os grupos de segurança padrão da AWS com `resource-types.excludes`. +- Terceiro, eu defino todos os recursos que não quero destruir na minha conta dentro da propriedade `accounts`. Basicamente, esses são os elementos essenciais necessários para realizar qualquer coisa útil nela, como fazer login, manter as configurações de administrador, minhas chaves de acesso, chaves SSH do EC2, etc. + +Eu substituo `{{AWS_ACCESS_KEY_ID}}` pela chave de acesso usada pela pipeline de CI para realizar as ações na AWS --- caso contrário, eu só poderia executá-lo uma vez 🤷. + +## Executando aws-nuke + +Com o arquivo `nuke-config.yml` configurado, podemos executar os comandos mostrados no trecho abaixo. Enquanto aqui eu passo explicitamente a chave de acesso (access key) e o segredo (secret), existem outras [opções](https://github.com/rebuy-de/aws-nuke#aws-credentials). + +```bash +# dry run // teste passo a passo +aws-nuke \ + --access-key-id "" \ + --secret-access-key "" \ + --config nuke-config.yml + +# Execute as ações de destruição, mas peça confirmação primeiro. +aws-nuke \ + --access-key-id "" \ + --secret-access-key "" \ + --no-dry-run \ + --config \ + nuke-config.yml + +# Execute as ações de destruição sem pedir confirmação prévia. +aws-nuke \ + --access-key-id "" \ + --secret-access-key "" \ + --no-dry-run \ + --force \ + --config \ + nuke-config.yml +``` + +O último passo é organizar essas tarefas e programá-las para serem executadas em um cronograma, no nosso caso, utilizando uma [pipeline agendada do GitLab CI](https://docs.gitlab.com/ee/ci/pipelines/schedules.html). + +## A pipeline agendada + +Primeiro, nós precisamos de um arquivo `gitlab-ci.yml`. Está detalhada abaixo, com comentários para explicar o que cada bloco faz. + +```yaml +# Declara as etapas da pipeline. +stages: + - dry-run + - nuke + +# Declara a imagem padrão utilizada nos trabalhos da pipeline, +# também substitui o ponto de entrada (entrypoint) da imagem, +# para evitar conflitos com o comportamento padrão do GitLab. +image: + name: quay.io/rebuy/aws-nuke:v2.17.0 + entrypoint: [""] + +# Aqui definimos um modelo de trabalho que executará o aws-nuke +# em modo simulado (dry-run) ou execução real, dependendo do valor da variável de ambiente NO_DRY_RUN. +# Preste atenção na substituição realizada no início, ela substitui +# o {{AWS_ACCESS_KEY_ID}} pelo valor da chave de acesso usada pela pipeline +# para destruir os recursos. +.nuke-run: + script: + - sed -i "s/{{AWS_ACCESS_KEY_ID}}/${AWS_ACCESS_KEY_ID}/g" nuke-config.yml + - | + aws-nuke \ + --force \ + --access-key-id "${AWS_ACCESS_KEY_ID}" \ + --secret-access-key "${AWS_SECRET_ACCESS_KEY}" \ + ${NO_DRY_RUN:+--no-dry-run} \ + --config nuke-config.yml + +# O trabalho de simulação (dry-run) +# sempre é executado - útil para garantir que MRs e commits estejam corretos - +# e é sempre "interruptível" (interruptible) (veja https://docs.gitlab.com/ee/ci/yaml/#interruptible). +dry-run: + stage: dry-run + extends: .nuke-run + interruptible: true + +#Executa o comando aws nuke +#Somente é executado em agendamentos que rodam na branch padrão. +nuke: + stage: nuke + extends: .nuke-run + variables: + NO_DRY_RUN: "yes" + rules: + - if: > + $CI_PIPELINE_SOURCE == 'schedule' + && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH +``` + +Com a pipeline configurada, a última parte necessária é adicionar o próprio agendamento. Isso pode ser feito a partir da interface do usuário do projeto no GitLab, em Build -> Pipeline schedules -> New schedule. O agendamento aceita a notação cron, que você pode validar em https://crontab.guru/. Uma vez concluído, você deve obter algo semelhante à imagem abaixo. + +[![AWS Nuke schedule pipeline](/images/aws-nuke-gl-schedule.png)](/images/aws-nuke-gl-schedule.png) + +Pressionar o botão de play (play button) acionará a pipeline da mesma forma que o agendamento fará, então você pode testar se tudo está funcionando corretamente. + +## Conclusão + + +Isso é tudo, agora sua conta será apagada conforme especificado no arquivo `nuke-config.yml` e com base no cronograma que você configurar. Novamente, tenha em mente que **Esta é uma solução muito perigosa, então não posso enfatizar o suficiente o quão cuidadoso você deve ser ao configurá-la. Preste atenção extra e cuide para confirmar que você sabe o que está fazendo**. O resultado é que agora você tem uma conta na qual pode realizar praticamente qualquer laboratório e teste, sem o medo de uma grande fatura da AWS. + +💡 Dito isso, esteja ciente de que pode haver recursos não deletados pelo aws-nuke, conforme mostrado em sua [documentação](https://github.com/rebuy-de/aws-nuke/issues). + +Espero que você tenha apreciado a leitura 😁. diff --git a/i18n/en.toml b/i18n/en.toml new file mode 100644 index 0000000..87e119b --- /dev/null +++ b/i18n/en.toml @@ -0,0 +1,8 @@ +findMeOn = 'You can also find me on' +allArticles = 'All articles' +readMore = 'Read more' +backToList = 'Back to list' +inThisArticle = 'In this article' +poweredBy = 'Powered by' +and = 'and' +translatedBy = 'Translated by' diff --git a/i18n/pt.toml b/i18n/pt.toml new file mode 100644 index 0000000..6ba0c74 --- /dev/null +++ b/i18n/pt.toml @@ -0,0 +1,8 @@ +findMeOn = 'Você também pode me encontrar em' +allArticles = 'Todos os artigos' +readMore = 'Leia mais' +backToList = 'Voltar para a lista' +inThisArticle = 'Neste artigo' +poweredBy = 'Feito com' +and = 'e' +translatedBy = 'Traduzido por' diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html index b1219d1..b3d7a1a 100644 --- a/layouts/_default/baseof.html +++ b/layouts/_default/baseof.html @@ -8,6 +8,12 @@ + {{ if .IsTranslated }} + {{ range .Translations }} + + {{ end }} + {{ end }} + {{ $styles := resources.Get "css/index.css" | resources.PostCSS }} {{ if .Site.IsServer }} @@ -53,9 +59,9 @@