When creating a language package for atom, it's possible to define a /snippets folder. Any files in here are automatically loaded when the package is active and the context (eg: ".source.js") is opened in the editor.
Now I'd like to contribute to the language-arma-atom package, where there's currently 3 snippet files: I want to add a checkbox option in the package settings to NOT load one of these files.
ie: I know how to add the option, but not how to exclude one of these snippet files.
The way I solved this was create a snippetsAvailable folder, put the files in there (and remove the snippets folder)*.
In your main package file, add to your config schema:
config:
optionalSnippets:
title: "My optional snippets"
description: "Adds optional snippets to autosuggestions"
type: "boolean"
default: true
And in your package's activation do something like this:
activate: ->
#subscriptions = new CompositeDisposable
# etc..
atom.config.observe 'my-package.optionalSnippets', (checked) ->
# For copyNewer, see note below *
copyNewer "my-snippets", "#{__dirname}/snippets", {
cwd: "#{__dirname}/snippetsAvailable"
}
* Note: I used the copyNewer package, because it allows me to remove the /snippets folder, ie: it will automatically create it again. More importantly, it won't overwrite the snippets file on each package activation; Except if you updated your package with new snippets.
Obviously you'll have to write copyNewer = require 'copy-newer' at the top of your main file.
Also, if you choose this method, don't forget to put /settings in .gitignore
Related
I am working on a drupal7 site.
In Dev, I have enabled and configured simplesamlphp_auth module.
I used features and strongarm to export the configuration to code.
The downloaded feature contain:
myfeature_sso.features.defaultconfig.inc
myfeature_sso.info
myfeature_sso.module
The .inc file contains the configuration values I had put in (admin/config/people/simplesamlphp_auth) correctly
Now, in a few places, I want to replace the hard coded values with variables that change based on the environment. I set the variables at the top of .inc file using variable_get $office_ou = variable_get('office_ou', NULL); ...and . A quick example is $base_url below:
$strongarm = new stdClass();
$strongarm->disabled = FALSE;
$strongarm->api_version = 1;
$strongarm->name = 'simplesamlphp_auth_logoutgotourl';
$strongarm->value = $base_url ;
$export['simplesamlphp_auth_logoutgotourl'] = $strongarm;
When I DPM these variables, they display correct values.
But on a fresh install when I enable myfeature_sso module the value of variables are missing.
missing value from $base_url variable
Can you please point me in the right direction?
Thank you.
I found the answer:
when in features ui, do not add fields relevant to simplesamle to the defaultconfig section. if you have any there remove them.
add fields relevant to simplesaml to storongarm section
export the feature
in your_feature_name.strongarm.inc add any additional php code to function your_feature_name_strongarm()
done
Is it possible to use template parameters in the content of a post with Hugo? E.g. if I have the following parameters:
[params.company]
name = "My Company"
Can I then do something like this in the content of a post?
This site, {{ .Site.BaseURL }} is operated by {{ params.company.name }}
I've tried, but it's literally printing the above instead of interpolating the variables.
1. Front matter way
As far as I'm aware, it's not possible* to put variables within the markdown file's content because MD parser would strip them, but it's possible to do it using custom variables on the front matter of each .md content file. The Hugo engine can target any fields you set in front matter. Front matter fields can be unique as well.
In your case, the template which is called to show the rendered .MD file has access to front matter parameters and you can change template's behaviour (like add classes of extra <div>'s) or even pull the content right from the parameter.
For example, on my .md files I have:
---
title: "Post about the front matter"
<more key pairs>
nointro: false
---
The key nointro: true would make my first paragraph to be normal size. Otherwise, if key is absent or false, first paragraph would be shown at larger font size. Technically, it's adding a custom class on a <div>.
In the template, I tap into the custom parameter nointro this way:
parent template which shows your markdown file, which has front matter parameters:
<div class="article-body {{ if .Params.nointro }} no_intro {{ end }}">
{{ .Content }}
</div><!-- .article-body -->
Notice I can't put variables within {{ .Content }}, but I can outside of it.
For posterity, that's piece of the content from a file hugo/themes/highlighter/layouts/partials/blog-single-content.html, it's a partial for single post content. You can arrange your partials any way you like.
Obviously, that's Boolean parameter flag, but equally it could be content which you could use directly:
MD file's top:
---
title: "One of our clients"
<more key pairs>
companyname: "Code and Send Ltd"
---
Text content is put here.
Then, reference it like this (extra insurance against blank value using IF):
Anywhere in Hugo template files:
{{ if .Params.companyname }}{{ .Params.companyname }}{{ end }}
2. Using config.(toml/yaml/json)
Now, looking at your example, "This site is operated by " would almost warrant a custom field in more global location, for example, hugo/config.toml. If I wanted to add a companyname into my config, I'd do it this way:
hugo/config.toml:
BaseURL = "_%%WWWPATH%%_"
languageCode = "en-uk"
title = "Code and Send"
pygmentsUseClasses = true
author = "Roy Reveltas"
theme = "Highlighter"
[params]
companyname = ""
Then I'd use it anywhere via {{ .Site.Params.headercommentblock }}.
I guess if you want your client pages to be static pages then single location might not be the best and you might want to tap into front-matter. Otherwise, if it's a site's footer, this way is better. Alternatively, you could even put this data even on data files.
3. Using custom placeholders and replacing via Gulp/npm scripts
I said not possible*, but it's possible, although unconventional and more risky.
I had such setup when I needed two builds for my website: 1) Prod and 2) Dev. Prod URL's were coming from two places: CDN and my server. Dev had to come from a single place in a static folder because I wanted to see images and was often working offline on a train.
To solve that, I used two custom variables in all my templates (including markdown content): _%%WWWPATH%%_ and _%%CDNPATH%%_. I came up with this unique pattern myself by the way, feel free to adapt it. Then, I put it also on hugo/config.toml as:
hugo/config.toml:
BaseURL = "_%%WWWPATH%%_"
After Hugo happily generated the website with those placeholders, I finished off the HTML's using a Grunt task:
grunt file:
replace: {
dev: {
options: {
patterns: [{
match: /_%%CDNPATH%%_+/g,
replacement: function () {
return 'http://127.0.0.1:1313/'
}
}, {
match: /_%%WWWPATH%%_+/g,
replacement: function () {
return 'http://127.0.0.1:1313/'
}
}...
For posterity, I recommend Gulp and/or npm scripts, I'd avoid Grunt. This is my older code example above from the days when Grunt was the best.
If you go this route, it's riskier than Hugo params because Hugo won't error-out when your placeholder values are missing or anything else wrong happens and placeholders might spill into the production code.
Going this route you should add multiple layers of catch-nets, ranging from simple following Gulp/Grunt/npm scripts step which searches for your placeholder pattern to pre-commit hooks ran via Husky on npm scripts that prevent from committing any code that has certain patterns (for example, %%_). For example, at a very basic level, you would instruct Husky to search for anything before allowing committing this way:
package.json of your repo:
"scripts": {
"no-spilled-placeholders": "echo \"\n\\033[0;93m* Checking for spilled placeholders:\\033[0m\"; grep -q -r \"%%_\" dist/ && echo \"Placeholders found! Stopping.\n\" && exit 1 || echo \"All OK.\n\"",
"precommit": "npm run no-spilled-placeholders"
},
Basically, grep for pattern %%_ and exit with error code if found. Don't forget to escape the code because it's JSON. I use similar (more advanced) setup in production and nothing slips through. In proper setup you should creatively look for anything mis-typed, including: %_, _%, %__, __% and so on.
Normal Go template is not supported in the markdown file, but shortcodes are:
{{< param "company.name" >}}
To access arbitrary other Go template values, create a custom shortcode for it and call that from your markdown file.
For your example, you need the site's baseUrl, so save this as layouts/shortcodes/base_url.html:
{{ .Site.BaseURL }}
And write this in your markdown file:
+++
[company]
name = "My Company"
+++
This site, {{< base_url >}} is operated by {{< param "company.name" >}}
There is also the shortcode param : {{< param "companyName" >}} : https://gohugo.io/content-management/shortcodes/#param
I am using Sencha Grid Exporter plugin, while it works perfectly fine when exported to Excel, I cant get it to export to CSV or any other types from my app.
It works fine as listed on the KitchenSink example.
KitchenSink Exporter Example
http://docs.sencha.com/extjs/6.2.1/classic/Ext.grid.plugin.Exporter.html
Ext.getCmp('grid').saveDocumentAs({
type: 'csv', // What other possible values can go here
title: globals.reportName,
fileName: 'myExport.csv'
});
Comes with an error as below:
Uncaught Error: [Ext.createByAlias] Unrecognized alias: exporter.CSV
at Ext.Inventory.instantiateByAlias (app.js?_dc=1481916938387:13520)
at Ext.Factory.create (app.js?_dc=1481916938387:23199)
at constructor.getExporter (app.js?_dc=1481916938387:204593)
at constructor.saveDocumentAs (app.js?_dc=1481916938387:204520)
at constructor.saveDocumentAs (app.js?_dc=1481916938387:5355)
at constructor.onMenuitemClick (app.js?_dc=1481916938387:255332)
at constructor.fire (app.js?_dc=1481916938387:19281)
at constructor.doFireEvent (app.js?_dc=1481916938387:20248)
at constructor.doFireEvent (app.js?_dc=1481916938387:65488)
at constructor.prototype.doFireEvent (app.js?_dc=1481916938387:56438)
You are missing a requires.
If you tell ExtJS to use type:'csv', it will try to instantiate exporter.csv. If you tell ExtJS to use type:'excel', it will try to instantiate exporter.excel. To get that one from the file system, you have to include the fully qualified name somewhere, e.g. in your requires section:
requires:[
'Ext.exporter.text.CSV'
]
The heading in the docs has two parts: First the full qualified class name, which is "Ext.exporter.text.CSV", and then, the short name ("exporter.csv"). If you haven't provided the full name anywhere, the file cannot be loaded, unless the framework itself already requires the exporter by full name. Which it, according to the error message, doesn't.
Background info, before you ask "Why doesn't it?": Since the plugin can work with any of the dozens of exporters, and you wouldn't want to load all just to create one type of export, you have to import the exporter manually.
I am creating an elixir project to search for patterns in files.
I want to store those patterns a config files to allow for easy changes in the app.
My first idea is storing those files as exs files in the config folder in the mix project.
So, the questions are:
Is there any easy way to store the config in the files a a keyword list?
How would I load it in the app?
I see there are modules like File to read the file, but is there no standard way to parse keyword lists in elixir? I was thinking something similar as the yml files in Rails.
You can read keyword lists stored in a *.exs file, using Mix.Config.read(path). For writing Elixir terms to a *.exs file, you can use Inspect.Algebra.to_doc(%Inspect.Opts{pretty: true}) and write the resulting string content to a file using File.write. It's not as well formatted as if you did it by hand, but it's definitely still readable.
If you don't mind using Erlang terms, you can read and write those easily using :file.consult(path) and :file.write_file(:io_lib.fwrite('~p.\n', [config]), path) respectively.
Using Code.eval_file
Adding another option, is to evaluate the file as a code file, using Code.eval_file and get in return the result as an elixir construct.
Config file config1.ex:
%{configKey1: "configValue1", configKey2: "configValue2"}
Reading the file:
{content, _} = Code.eval_file("config1.ex")
*evaluating a code file has security consideration needs to take in mind.
Regarding using Mix.Config.read! in #bitwalker correct answer
the config file needs to be in a specific format of:
[
appName: [key1: "val1", key2: "val2"]
]
In the Mix.Config.read code, it try to validate the contents and expect a main keyword list [ {}, {}.. ] which includes keys that has value of type keyword list also.
The code is not long:
def validate!(config) do
if is_list(config) do
Enum.all?(config, fn
{app, value} when is_atom(app) ->
if Keyword.keyword?(value) do
true
else
raise ArgumentError,
"expected config for app #{inspect app} to return keyword list, got: #{inspect value}"
end
_ ->
false
end)
else
raise ArgumentError,
"expected config file to return keyword list, got: #{inspect config}"
end
end
We can circumvent and use a first key which is not atom, and then the validate stops but does not throw:
[
{"mockFirstKey", "mockValue"},
myKey1: "myValue1",
myKey2: "myValue2"
]
I have the file "license.txt" in the root directory of my project. In the jar-task, I want to add this file to the (root folder of the) JAR file.
I tried
jar {
from '.' include 'license.txt'
}
but this replaces the other content (.class files) instead of adding a file.
And I do not want to add the license.txt to the resources folder, because I do not want to change my project structure just because of the build tool.
Who can help? Thank you!
To add a single file, you can simply do:
jar {
from "license.txt"
}
Your solution should also work if you scoped your include to your from by enclosing it in curly braces.
If you would like to add multiple files, you can do:
jar{
from{
["aaa.txt","bbb.txt"]
}
}
You would add multiple files to output jar as under:
jar {
// Update jar name according to Ascertia conventions
/**
* archiveFileName
* The archive name. If the name has not been explicitly set, the pattern for the name is:
* [archiveBaseName]-[archiveAppendix]-[archiveVersion]-[archiveClassifier].[archiveExtension]
*/
archiveFileName = 'database_postgresql.jar'
from(['build/classes/java/main','mappings/postgresql'])
}
All contents in below directories will be added:
build/classes/java
/main/mappings/postgresql