Rails -- asset pipeline - identifying resource by directory - ruby-on-rails-3.1

Say in vendor/assets I have two subdirectories, /alpha and /beta, each with a file named temp.jpg. To my understanding, a GET request is made for /assets/temp.jpg, and I'm pretty sure the one from the alpha directory is served. But how can I distinguish between the two of them? I think it can be done with the asset_url helper but I'm not quite sure - if anyone can advise that would be great.

From the manual:
You can view the search path by inspecting Rails.application.config.assets.paths in the Rails console.
Additional (fully qualified) paths can be added to the pipeline in config/application.rb. For example:
config.assets.paths << Rails.root.join("app", "assets", "flash")
Sprockets will also look through the paths specified in config.assets.paths which includes the standard application paths and any path added by Rails engines.
Images can also be organized into subdirectories if required, and they can be accessed by specifying the directory’s name in the tag:
<%= image_tag "icons/rails.png" %>
If you're using the asset pipeline, I'm not sure which of your images would be supplied by a link that doesn't specify the url, if any. If one is being supplied, it's going to have to do with the order in which Sprockets recursively reads those directories. If it reads them in alpha order, then the "beta" image is going to be served. Or else it's just going to be random, I'm not sure how Sprockets reads the directories.
You're going to be better off putting an explicit path in there. If you are doing some sort of a test, like if you want the beta images to appear, I'd recommend some sort of paramaterized approach so that you can pass in "alpha" or "beta" to your path.

Check http://guides.rubyonrails.org/asset_pipeline.html#asset-organization and try execute Rails.application.config.assets.paths in the Rails console in order to debug your assets loading path.

Related

Organize Chef attributes in different directories

I am trying to organize my attributes files by directory with in the attributes directory. I would look like this:
attributes
-Production
-file1.rb
-file2.rb
-Stage
-file1.rb
-file2.rb
-Development
-file1.rb
-file2.rb
When putting the different attribute files in the directories, Chef doesnt pick them up. Is there a way to make Chef look in all directories?
This is not a thing, and even using multiple files might not do what you expect. Remember that all attribute files are always loaded. Segmenting them into multiple files is just for readability at best, and I don't recommend it. In fact if you're using Chef 13, we got rid of the directory entirely and you can just use mycookbooks/attributes.rb.

Automate Jekyll page.categories according to directory structure

Goal
Make Jekyll post have their own category according to directory structure.
e.g.) _post/category1/category2/post-content.md must have categories of ['category1', 'category2'](I guess Jekyll deals with categories as an array).
The point is, making 1) no need to specify category in Front Matter and 2) auto categorize every posts by directory structure .
Description
Official Jekyll document says Categories are derived from the directory structure above the _post directory. For example, a post at /work/code/_posts/2008-12-24-closures.md would have this field set to ['work', 'code'].
https://jekyllrb.com/docs/variables/
If it is possible, I would joyfully use this function. The problem is, I have no idea how to make _post dir to be located in other directories. I thought _post dir have to be in root dir, so for me positioning post in path like /work/code/_posts/2008-12-24-closures.md seems impossible. Is it possible? or not possible?
If 1. is impossible, how can I match categories and dir-struct for every post? I don't want to do it manually for every posts.
I tried to use {{ page.path }} to make it automated, but 2 problem I faced. 1) not sure Liquid(template engine) support full ruby functionality like File.basename for parsing. 2) not sure if codes like parsing can be done in Front Matter. For instance, I tried categories: {{ page.path | array_to_sentence_string }} in Front Matter but it ended up in an error.
any solution for these issues? Or there is no way?
You're following the directions properly: you can use either folder structure, though the latter is preferred.
The problem is that the special directory is _posts PLURAL, not _post singular.

Is there a way to include/render a file from outside `src` in DocPad?

I have a project which have a lot of useful docs outside of the src directory which I'd like to render as usual DocPad documents.
Examples:
Files at the root of the project: README.md, LICENSE, Contributing.md and similar, which are already there and can be used in things like GitHub. I would like to reuse the content from those files to create the corresponding readme, license and contributing pages, or to include the contents from those files somewhere in layout or a document.
I have a project that have some docs inside, and I'd like to render the .md files as DocPad documents from it by including it in package.json, so those files would be in node_modules at root.
In both those cases there are files outside of the src/documents that I'd like to use as partials or documents, and it seems that the partial plugin can't help me (or I couldn't find a way to make it do what I need), and the #getCollection can only get things from the src/documents.
So, the question is: Is there a way I can tell DocPad to treat some of the files/folders from the outside of the src folder? Do I miss something?
If not, then what would be the best way to do it as a plugin, which direction should I dig?
DocPad natively supports storing documents outside of the default src folder. The way you do this is via the documentsPaths config option in the DocPad Configuration File (e.g. docpad.coffee). Something like this:
path = require('path')
docpadConfig = {
documentsPaths: [
'documents'
path.resolve('..','data','documents')
]
....
Of course, where this will fall down is if you want to just include arbitrary, individual files somewhere on the file system. In such cases symlinks would be the way to go.
Template helpers can also be used for this, as they can do whatever you want.
For instance, the Bevry Learning Centre website uses template helpers to render arbitrary files by relative paths as code examples:
Template Helper: https://github.com/bevry/learn/blob/6e202638f2321eec2633d1dbeaf1078bdb953562/docpad.coffee#L244-L257
Tempalte using the Template Helper: https://github.com/bevry/documentation/blob/f24901251d19ec1cfa56fcee14c2c6836c0a995c/node/handsonnode/03-server.html.md.eco
If you would also like to render them, you could combine such a solution with the Text Plugin.
The combination would be like so:
Template Helper in DocPad Configuration File:
docpadConfig =
templateData:
readProjectPath: (relativePath) ->
fullPath = require('path').join(__dirname, relativePath)
return #readFullPath(fullPath)
readRelativePath: (relativePath) ->
fullPath = #getPath(relativePath)
return #readFullPath(fullPath)
readFullPath: (fullPath) ->
result = require('fs').readFileSync(fullPath)
if result instanceof Error
throw result
else
return result.toString()
Usage of Template Helper with Text Plugin using Eco as templating engine:
<t render="markdown"><%- #readProjectPath('README.md') %></t>
The answer would be a rather simple one: relative symbolic links. Docpad handles them perfectly.
This way, to have a symlink of README.md inside your documents, you should do this (with pwd of src/documents):
ln -s ../../README.md readme.html.md
Or, in case of a docs from inside one of the project's modules:
ln -s ../../node_modules/foobar/docs/ docs
Both those variants work perfectly.
Note: Symlinks can be tricky. Refer to these for some common gotchas:
https://github.com/docpad/docpad/issues/878#issuecomment-53197720
https://github.com/docpad/docpad/issues/878#issuecomment-53209674
Just as a comparison between the different answers:
Use the paths solution when you want to add entire extra directories to be included inside the DocPad database to be treated as normal by DocPad.
Use the sym/hard link solution when you want to include specific documents or files that you would like to be treated as a DocPad document or file, with all the intelligent file parsing and document rendering, including layout, database, and caching features.
Use the template helper solution when you want to include specific files that you do not want included in the DocPad database for whatever reason.
Made this answer a community wiki one, so it can be updated accordingly for new answers and better details.

Is there an efficient way in docpad to keep static and to-be-rendered files in the same directory?

I am rebuilding a site with docpad and it's very liberating to form a folders structure that makes sense with my workflow of content-creation, but I'm running into a problem with docpad's hard-division of content-to-be-rendered vs 'static'-content.
Docpad recommends that you put things like images in /files instead of /documents, and the documentation makes it sound as if otherwise there will be some processing overhead incurred.
First, I'd like an explanation if anyone has it of why a file with a
single extension (therefore no rendering) and no YAML front-matter,
such as a .jpg, would impact site-regeneration time when placed
within /documents.
Second, the real issue: is there a way, if it does indeed create a
performance hit, to mitigate it? For example, to specify an 'ignore'
list with regex, etc...
My use case
I would like to do this for posts and their associated images to make authoring a post more natural. I can easily see the images I have to work with and all the related files are in one place.
I also am doing this for an artwork I am displaying. In this case it's an even stronger use case, as the only data in my html.eco file is yaml front matter of various meta data, my layout automatically generates the gallery from all the attached images located in a folder of the same-name as the post. I can match the relative output path folder in my /files directory but it's error prone, because you're in one folder (src/files/artworks/) when creating the folder of images and another (src/documents/artworks/) when creating the html file -- typos are far more likely (as you can't ever see the folder and the html file side by side)...
Even without justifying a use case I can't see why docpad should be putting forth such a hard division. A performance consideration should not be passed on to the end user like that if it can be avoided in any way; since with docpad I am likely to be managing my blog through the file system I ought to have full control over that structure and certainly don't want my content divided up based on some framework limitation or performance concern instead of based on logical content divisions.
I think the key is the line about "metadata".Even though a file does NOT have a double extension, it can still have metadata at the top of the file which needs to be scanned and read. The double extension really just tells docpad to convert the file from one format and output it as another. If I create a straight html file in the document folder I can still include the metadata header in the form:
---
tags: ['tag1','tag2','tag3']
title: 'Some title'
---
When the file is copied to the out directory, this metadata will be removed. If I do the same thing to a html file in the files directory, the file will be copied to the out directory with the metadata header intact. So, the answer to your question is that even though your file has a single extension and is not "rendered" as such, it still needs to be opened and processed.
The point you make, however, is a good one. Keeping images and documents together. I can see a good argument for excluding certain file extensions (like image files) from being processed. Or perhaps, only including certain file extensions.

What is a good way to share templates across apps with separate codebases?

We have one Sinatra app and one Backbone app.
I saw Sharing the same codebase across multiple apps but didn't understand it or how I could implement it.
This question is not really specific to Sinatra or Backbone; it could be pretty much any apps. Using Heroku and Git
One idea is to put the HTML on S3, but we aren't using S3 to store HTML. And how would you get it from Git onto S3? It seems very convoluted.
So, is there a good way of sharing HTML templates between the apps?
We do it by having a containing parent directory, and well-defined paths to the common files, and by having a common YAML file used to tell different apps where to look.
Create a common YAML file that contains a Hash, with the keys being a common-name for a particular resource or path to resources, and the value being the absolute path to that on the disk.
For instance:
---
html: /absolute/path/to/shared/html
images: /absolute/path/to/shared/images
main_css: /absolute/path/to/shared/styles.css
Load that using Ruby with:
require 'yaml'
SHARED_RESOURCES = YAML.load_file('/absolute/path/to/shared_resources.yaml')
# => {"html"=>"/absolute/path/to/shared/html", "images"=>"/absolute/path/to/shared/images", "main_css"=>"/absolute/path/to/shared/styles.css"}
Use the resulting SHARED_RESOURCES hash to retrieve the information you need:
main_css = SHARED_RESOURCES['main_css']
# => "/absolute/path/to/shared/styles.css"
You can use that same YAML file from ANY language that can read YAML, or where you can open that file and parse its contents. At that point, all your code-bases can play from the same sheet of music, and will know how to access the common files when necessary.
For instance, from Perl:
use YAML;
$SHARED_RESOURCES = Load('
---
html: /absolute/path/to/shared/html
images: /absolute/path/to/shared/images
main_css: /absolute/path/to/shared/styles.css
');
print $SHARED_RESOURCES->{'main_css'}, "\n";
>> /absolute/path/to/shared/styles.css
If you want to get fancier, use a database to hold those shared resources. Either way, the idea is there's just one place for the code to look for a particular resource/file.

Resources