custom web development guide - restarone/violet_rails GitHub Wiki

Since Violet Rails uses ComfortableMexicanSofa as a CMS, This guide is based on: https://github.com/comfy/comfortable-mexican-sofa/

For custom web development using the included Ember.js framework, see here: https://github.com/restarone/violet_rails/wiki/Ember.js-on-Violet-Rails

The editor

The editor is powered by Redactor 2 (by Imperavi), and features 2 modes. WSIWYG for editing text, and code-mode for well-- code editing.

WSIWYG mode (default)

In this mode you can change text easily, but to make adjustments to the layout, colours or HTML/CSS/Javascript, you will need to click on the code button. Screen Shot 2022-04-02 at 11 49 48 AM

Switching to HTML/CSS/Javascript source

Clicking on the button pointed out below will toggle between HTML and WSIWYG modes Screen Shot 2022-04-02 at 11 49 55 AM

CSS and styling

Bootstrap 4 and jQuery are included out of the box. To override Bootstrap styles, use the default layout. To write custom CSS you can use <style> tags on pages where you need custom styling. So for example, you can set a custom CSS class like this below:

<style>
.bg-img{
	  background: url('{{ cms:file_link 30 }}');
	  background-repeat: no-repeat;
  	  background-position: center;
	  background-size: cover;
        }
</style>

This will set the background to a file that is in the CMS (notice the single quotes wrapping the snippet {{ cms:file_link 30 }}

Linking Assets

Images

Screen Shot 2022-04-02 at 11 44 34 AM

To safely link assets, without redactor -- well, redacting your code. Follow this pattern in your HTML (note the 5 is the ID of the file you want to link):

<div class="container">
  {{ cms:file_link 5, as: image, class:"img-fluid img1" }}
</div>

This will generate the following HTML:

<div class="container">
  <img src="https://dynamically-generated-url-here.com" class="img-fluid img1" alt="filename.file-extension"  />
</div>

Video backgrounds

These are always cool, as seen here. Credits go to Pralish Kayastha and his original gist.

General setup

  • Using the poster attribute causes the video to show up instantly after it finishes downloading.

  • Use both webm and mp4 format to support different browsers and devices

  • Convert your video to webm format. It reduces the size significantly

  • Wrap the video element with a container

    <div id="video-container">
	<video id="video" muted autoplay playsinline>
        	<source src=" {{ cms:file_link 38 }}" type="video/webm">
        	<source src="{{ cms:file_link 4 }}" type="video/mp4">
	</video>
    </div>
  • Add background image to the container
#video-container {
  background-image: url("{{ cms:file_link 34}}");
  background-size: cover;
}	
  • Set the video's opacity to 0 and add your desired transition ;
#video {
  opacity: 0;               
  transition: opacity 2s ease;    
}
  • Add an event listener for the play event (that is triggered automatically because of autoplay and playsinline). Change the opacity when the event is triggered.
$("#video").bind('play', function (e) {
   $("#video").css('opacity', 1.0);
});

making it work on Safari (desktop & mobile)

  • Safari might not autoplay the video. One of the workarounds would be to use the tag.

  • Note: No other browsers support video url in img tag.

  • Add an img tag with the video url as it's src inside the video container.

    <div id="video-container">
	      <video id="video" muted autoplay playsinline>
        	  <source src=" {{ cms:file_link 38 }}" type="video/webm">
        	  <source src="{{ cms:file_link 4 }}" type="video/mp4">
	      </video>
        <img id="img-tag" class="h-100 w-100" style="object-fit: cover;" src="{{ cms:file_link 4 }}">  
    </div>
  • Create a function to toggle between video and img based on the browser.
function browserDetection() {
    if (navigator.userAgent.search("Safari") >= 0 && navigator.userAgent.search("Chrome") < 0) {
        document.getElementById('video').style.display= "none";
    } else {
        document.getElementById('img-tag').style.display= "none";
    }     
}  
   
  browserDetection();

Call to Actions

These are built in templated form helpers with recapcha protection. See example here. In your HTML, you can render one of these forms by their ID (check the table under call to actions to copy the snippet specific to your application)

{{ cms:helper render_call_to_action, 1 }}

Searching website pages

  • To render a search field, use the following helper in your HTML.
{{ cms:helper render_search_field }}
  • next, add a search handler with an inline script or under the Javascript section in your layout
const onSearchFormSubmit = (e) => {
  e.preventDefault()
  query = $(e.target).find('input[type=text]').val()
  $.ajax({
    type: e.target.getAttribute('method'),
    url: e.target.getAttribute('action'),
    data: { query: query },
    dataType: 'json',
    success(data) {
      // handle the response from the endpoint
      console.log(data);
      return false;
    },
    error(data) {
      console.log(data);
    }
  })
 }
  • in the above example we are using the form to call the handler directly, if you'd like to be more adventurous you can skip the form and use ajax only:
$.ajax({
  type: 'POST',
  url: '/query',
  data: { query: "test" },
  dataType: 'json',
  success(data) {
    console.log(data);
    return false;
  },
  error(data) {
    console.log(data);
  }
})

styling search results

Each page has a preview content form. Enter your HTML markup there and the API will return it in the response Screenshot from 2021-08-23 20-12-46

Active links

Active links highlight the page the user is on in the navbar tab. Add this to your navbar snippet. Credits go to Pralish Kayastha and his original gist.

<script>
    var url = window.location.href;
    $('.nav-link').filter(function() {
        return this.href == url;
    }).addClass('current');
</script>

Update your css accordingly

.nav-link.current {
 color: #13aff0;
}

Integrating with Violet Rails Automation API:

Using API Namespace to deliver an animation

Our very own Restarone.com uses the API system to deliver a large file after page load. See it in action here (video): https://user-images.githubusercontent.com/35935196/168428398-7fc5fde4-40b4-4857-9127-0154b1c04ce7.mov

Lottie library can be used to parse and load JSON-based animation.

Create an API namespace for the animation that you want to render

create-api-namespace

In your Javascript (in the layout, or in a page), you can make an AJAX call to fetch that animation data. The GET API endpoint for an API namespace, my_awesome_animation, would be exposed in the layout/page as /api/1/my_awesome_animation/describe.

url-for-fetching-json-animation-data

async function loadAnimation() {
  try {
    const animationData = await getAnimationData(
      "/api/1/home_anim_data_desktop/describe"
    );

    const config = {
      container: document.querySelector(".animation-container"),
      renderer: "svg",
      loop: false,
      autoplay: false,
      rendererSettings: {
        progressiveLoad: true,
      },
      animationData: animationData,
    };

    lottie.loadAnimation(config);
  } catch (error) {
    console.error(error.message);
  }
}

async function getAnimationData(url) {
  try {
    const response = await fetch(url);
    const data = await response.json();
    return JSON.parse(data.properties.stringified_json_animation);
  } catch (error) {
     console.log(error);
  }
}
⚠️ **GitHub.com Fallback** ⚠️