datocms / ruby-datocms-client

Ruby client for the DatoCMS API.
https://www.datocms.com/docs/content-management-api/using-the-ruby-client
MIT License
20 stars 14 forks source link

Access other locales when creating a post #9

Closed andresgutgon closed 7 years ago

andresgutgon commented 7 years ago

Hi I don't find how to do this. I want to have an array on my yaml file of my item with all posible slugs in all locales. This way then in my layout I can print a Language selector in this fashion:

Imagine we're on http://www.example.com/es/articulos/la-url-de-mi-articulo So I would like to give user the oportunity to switch to the same article but in English:

// Fake HTML select
Language Selector:
  - Chose Language
  - English (/en/posts/my-blog-post-url)
  - Spanish (/es/articulos/la-url-de-mi-articulo)

I'm generating content for my Jekyll in this way:

directory "src/posts" do
  I18n.available_locales.each do |locale|
    I18n.with_locale(locale) do
      dato.posts.each do |post|

        ## HOW I can access all the `slug` fields of this post? 
        ## I mean, the same slug but in all language
        create_post "#{locale.to_s}_#{post.slug}.yaml" do
          frontmatter :yaml,
            layout: 'post',
            title: play.title,
            language: locale.to_s,
            permalink: "#{locale.to_s}/posts/#{post.slug}/index.html"
        end
      end
    end
  end
end

I hope my question is clear, If no, please let me know

andresgutgon commented 7 years ago

This is working but feels weird:

  I18n.available_locales.each do |locale|
    I18n.with_locale(locale) do
      dato.posts.each do |play|
        slugs_18n = I18n.available_locales.map do |locale|
          I18n.with_locale(locale) do
            post.slug
          end
        end
...
stefanoverna commented 7 years ago

Hi @andresgutgon, yes, this is the current solution :) you can make it less weird extracting the pattern into a separate method:

  def field_in_all_locales(record, field_name)
    I18n.available_locales.map do |locale|
      I18n.with_locale(locale) { record.send(field_name) }
    end
  end

  I18n.available_locales.each do |locale|
    I18n.with_locale(locale) do
      dato.posts.each do |post|
        slugs = field_in_all_locales(post, :slug)
andresgutgon commented 7 years ago

I'm trying your idea of moving it to helper methods. I love it. Even I can move to other file. But I'm having issues.

The scope issue with instance_eval

This issue is that I'm wrapping my Dato content inside a directory. Which is using instance_eval. I'm reading here that methods outside of instance are not accessible

Here is what I'm trying to do:

# root of my dato_config.rb
def my_helper_method
  puts "Awesome"
end

directory 'src/posts' do
   I18n.available_locales.each do |locale|
    I18n.with_locale(locale) do
      # This will fail
      my_helper_method
     # NameError: undefined local variable or method `my_helper_method' for #<Dato::Dump::Dsl::Directory:0x007fa5cf5c2b60>
   end
  end
end

In the same article recommends doing something like this:

class Directory
  def initialize(&block)
    @self_before_instance_eval = eval "self", block.binding
    instance_eval &block
  end
  def method_missing(method, *args, &block)
    @self_before_instance_eval.send method, *args, &block
  end
end

I did that change in a PR. Let me know what you think https://github.com/datocms/ruby-datocms-client/pull/10

Thanks!

andresgutgon commented 7 years ago

I think we can close this one. This https://github.com/datocms/ruby-datocms-client/pull/10 was merged

stefanoverna commented 7 years ago

@andresgutgon released v0.3.15