Socket
Book a DemoInstallSign in
Socket

contents_core

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

contents_core

0.3.2
bundlerRubygems
Version published
Maintainers
1
Created
Source

ContentsCore Gem Version Build Status Dependency Status Test Coverage

A Rails gem which offer a structure to manage contents in a flexible way: blocks with recursive nested blocks + items as "leaves"

Disclaimer: this component is in ALPHA, major changes could happen

Goals:

  • attach the contents structure to a model transparently
  • add fields to blocks without migrations
  • offer helpers to render blocks in views
  • cache-ready

Install

  • Add to the Gemfile: gem 'contents_core'
  • Copy migrations (Rails 5.x syntax, in Rails 4.x use rake): rails contents_core:install:migrations
  • Execute migrations
  • Add the concern Blocks to your model (ex. Page): include ContentsCore::Blocks
  • Optionally add the blocks to a view (ex. page show): = render partial: 'contents_core/blocks', locals: { container: @page }

Usage

Working with blocks/items

  • Basic operations (example parent model: Page):
page = Page.first
page.create_block :slider, name: 'a-slider', create_children: 3  # Create a silder with 3 slides
page.current_blocks.map{ |block| block.name }  # current_blocks -> all published ordered blocks and query cached
block = page.get_block 'a-slider'
block.tree  # list all items of a block
block.get 'slide-2.title'  # get value of 'title' field of sub block with name 'slide-2' (name automatically generated at creation)
block.set 'slide-2.title'  # set field value
block.save
  • Other operations:
block = ContentsCore::Block.last
ContentsCore.create_block_in_parent block, :text  # create a sub block in a block
block.create_item :item_string, name: 'a-field'

Config

Edit the conf file: config/initializers/contents_core.rb

module ContentsCore
  @@config = {
    blocks: {
      text: {
        name: :text_only,       # used as reference / for translations
        children: {             # children: sub blocks & items
          title: :item_string,
          content: :item_text
        }
      },
      image: {
        name: :image_only,
        children: {
          img: :item_file
        }
      },
      slide: {
        name: :a_slide,
        child_only: true,       # used only as child of another block (slider)
        children: {
          img: :item_file,
          link: :item_string,
          title: :item_string
        }
      },
      slider: {
        name: :a_slider,
        new_children: :slide,   # block type used when creating a new child with default params
        children: {
          slide: :slide
        }
      },
    },
    items: {
      item_boolean: {},
      item_datetime: {},
      item_float: {},
      item_hash: {},
      item_file: {
        input: :file_image
      },
      item_integer: {},
      item_string: {},
      item_text: {
        input: :html
      },
    }
  }
end

Create the new view blocks: app/views/contents_core/_block_custom.html.slim

- if block
  .title = block.get( 'title' )
  .text == block.get( 'content' )
  .image = image_tag block.get( 'image' ).url( :thumb )

Images

To add support for images add CarrierWave gem to your Gemfile and execute: rails generate uploader Image and update che config file config/initializers/contents_core.rb with:

module ContentsCore
  ItemFile.class_eval do
    mount_uploader :data_file, ImageUploader

    def init
      self.data_file = File.open( Rails.root.join( 'public', 'images', 'original', 'missing.jpg' ) )
      self
    end
  end
end

Another way is to override the ItemFile model (app/models/contents_core/item_file.rb):

module ContentsCore
  class ItemFile < Item
    mount_uploader :data_file, ImageUploader

    alias_attribute :data, :data_file

    def init
      self.data_file = File.open( Rails.root.join( 'public', 'images', 'original', 'missing.jpg' ) )
      self
    end

    def self.type_name
      'file'
    end
  end
end

Customizations

To create a "free form" block just use: Page.first.create_block :intro, name: 'IntroBlock', schema: { intro: :item_string, subtitle: :item_string }

Then create a app/view/contents_core/_block_intro view.

To list the blocks of a page manually (but current_blocks method is the preferred way): Page.first.cc_blocks.pluck :name

To add a new field to an existing block (ex. to first Page, on the first Block):

block = Page.first.get_block 'text-1'
block.create_item( :item_string, name: 'new-field' ).set( 'A test...' ).save

Then add to the block view: block.get( 'new-field' )

To set a field value: block.set( 'new-field', 'Some value' )

ActiveAdmin

If you use ActiveAdmin as admin interface you can find a sample model configuration: page plus a js page

Notes

  • Blocks enum: ContentsCore::Block.enum
  • Blocks types: ContentsCore::Block.types
  • Default blocks here

Structure

  • Including the Blocks concern to a model will add has_many :cc_blocks relationship (the list of blocks attached to a container) and some utility methods
  • Block: UI component, a group of items (ex. a text with a title, a slider, a 3 column text widget, etc.); built with a list of sub blocks (for nested components) and a list of items
  • Item: a single piece of information (ex. a string, a text, a boolean, an integer, a file, etc.) with a virtual method named data

Contributors

FAQs

Package last updated on 07 Nov 2017

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.