Go: embed JS files with bindata - go

This question is a follow up to an earlier question of mine. I've closed the question so I hope its okay that I ask a fresh but related question here. Go: embed static files in binary
How do I serve JS files with go-bindata? Do I pass it into html like this
hi.html
<script>{{.Bindata}}></script>
Doesn't seem to work even though I have no compile or JS errors.

Using https://github.com/elazarl/go-bindata-assetfs
Assuming you have the following structure:
myprojectdirectory
├───api
├───cmd
├───datastores
└───ui
├───css
└───js
Where ui is the directory structure you'd like to wrap up and pack into your app...
Generate a source file
The go-bindata-assetfs tool is pretty simple. It will look at the directories you pass to it and generate a source file with variables that can contain the binary data in those files. So make sure your static files are there, and then run the following command from myprojectdirectory:
go-bindata-assetfs ./ui/...
Now, by default, this will create a source file in the package main. Sometimes, this is ok. In my case, it isn't. You can generate a file with a different package name if you'd like:
go-bindata-assetfs.exe -pkg cmd ./ui/...
Put the source file in the correct location
In this case, the generated file bindata_assetfs.go is created in the myprojectdirectory directory (which is incorrect). In my case, I just manually move the file to the cmd directory.
Update your application code
In my app, I already had some code that served files from a directory:
import (
"net/http"
"github.com/gorilla/mux"
)
// Create a router and setup routes
var Router = mux.NewRouter()
Router.PathPrefix("/ui").Handler(http.StripPrefix("/ui", http.FileServer(http.Dir("./ui"))))
// Start listening
http.ListenAndServe("127.0.0.1:3000", Router)
Make sure something like this works properly, first. Then it's trivial to change the FileServer line to:
Router.PathPrefix("/ui").Handler(http.StripPrefix("/ui", http.FileServer(assetFS())))
Compile the app
Now you have a generated source file with your static assets in them. You can now safely remove the 'ui' subdirectory structure. Compile with
go install ./...
And you should have a binary that serves your static assets properly.

Use https://github.com/elazarl/go-bindata-assetfs
From the readme:
go-bindata-assetfs data/...
In your code setup a route with a file server
http.Handle("/", http.FileServer(assetFS()))

Got my answer here: Unescape css input in HTML
var safeCss = template.CSS(`body {background-image: url("paper.gif");}`)

Related

Writing .cargo/config.toml to allow rust code to be imported by python

I'm using rust-cpython to make a python module in rust. I've run my code on a linux os and it runs just fine but I get the familiar "linking with cc failed:exit code 1 error". I've gathered from this that I need to add the .cargo/config file to my project as suggested at the bottom of this:
https://github.com/dgrunwald/rust-cpython
I've copied and pasted their code into a file, config.toml, and place there in a directory, .cargo. I've tried nesting this in my src directory and my project directory with no success, what am I missing?
Solution found: Thought I'd post it as this gave me grief.
Everything with this setup is fine except the config file can't have the extension .toml despite being written in a toml format

Get project root path on runtime to read config file

I have a Go project with the following structure and Im struggling to read config file which is located in my project,I need to read the config yaml (which inside the root project) and I should read it inside other package under sub root directory and I got error of not found
myproject
- config.yaml
- cmd
--com
---ftp
----fs.go
Inside the fs.go I need to read the config.yaml and in not having success with it. I try with os.Getwd and also ex, err := os.Executable() and also "../../../" without success, any idea ?
#VonC - suggested to use https://github.com/gobuffalo/packr which can help I guess but the problem is that I need to call it inside the fs.go file and I need to pass this as parameter from the main.go file, is there a better approach ? because I need to pass this parameter in lots of functions...
does viper can help? https://github.com/spf13/viper
My program is CLI program which will be used as bin.
2018: If the binary is built in GOPATH/bin, while your sources are in GOPATH/src, then the relative path would be (at runtime) ../src/myproject.
But a cleaner way would be to embed that file in your binary.
See for instance gobuffalo/packr.
Update Q1 2021: with Go 1.16, you would use the embed package
Go source files that import "embed" can use the //go:embed directive to initialize a variable of type string, []byte, or FS with the contents of files read from the package directory or subdirectories at compile time.
//go:embed hello.txt
var f embed.FS
data, _ := f.ReadFile("hello.txt")
print(string(data))

Go install exclude file

I have created a go script that compiles, starts, checks the status, and ends a web service I created (that is also in go). However, I have come to a road block.
With the compile feature I run the following command:
go install .
Which gives the following error:
./script.go:55: main redeclared in this block
previous declaration at ./hello.go:8
Which makes sense as I have two different files, both with the main func and main package. I also tried moving the script to another folder and then changing the command ran to:
go install {path}
Where {path} is equal to the path I want installed/compiled. Which I then got the following error:
exit status 1: can't load package: package /var/www/test.com/go: import "/var/www/test.com/go": cannot import absolute path
So in conclusion I have thought of only one solution (and I am up to hear others if mine isn't the best approach). My idea is to exclude the script file from compiling with the rest of the files, but I am unsure how to.
I did some research and couldn't find an easy way to do it (such as an --exclude flag with the go install command). Does anybody know how to accomplish what I am trying to achieve?
Thank you.
you could give the hello.go a different package name, that should work. Or i am missing something?
Regards
Tim

How do you serve simple documentation for go programs using godoc as a webpage?

I was trying to serve a specific local go file as a documentation web page, but was not able to do it.
The official godoc documentation says:
With the -http flag (i.e. the godoc command), it runs as a web server and presents the documentation as a web page.
user_me$ godoc -http=:6060
This does create something similar as the go page but it does not render the specific file that I want to render. So I tried to provide the name of the file I wanted:
user_me$ godoc -http=:6000 hello.go
However, it just replies with:
usage: godoc package [name ...]
godoc -http=:6060
-ex=false: show examples in command line mode
-goroot="/usr/local/go": Go root directory
-html=false: print HTML in command-line mode
-http="": HTTP service address (e.g., ':6060')
-httptest.serve="": if non-empty, httptest.NewServer serves on this address and blocks
-index=false: enable search index
-index_files="": glob pattern specifying index files;if not empty, the index is read from these files in sorted order
-index_throttle=0.75: index throttle value; 0.0 = no time allocated, 1.0 = full throttle
-links=true: link identifiers to their declarations
-maxresults=10000: maximum number of full text search results shown
-notes="BUG": regular expression matching note markers to show
-play=false: enable playground in web interface
-q=false: arguments are considered search queries
-server="": webserver address for command line searches
-src=false: print (exported) source in command-line mode
-tabwidth=4: tab width
-templates="": directory containing alternate template files
-timestamps=false: show timestamps with directory listings
-url="": print HTML for named URL
-v=false: verbose mode
-write_index=false: write index to a file; the file name must be specified with -index_files
-zip="": zip file providing the file system to serve; disabled if empty
I also tried:
user_me$ godoc -url="localhost:8080" hello.go
but it didn't work.
I also tried:
godoc -server=localhost:8080 hello.go
but it replied with:
2014/07/01 10:45:56 open /usr/local/go/src/pkg/hello.go: no such file or directory
I even tried just generating the html thing itself:
godoc -html hello.go > hello.html
same error as above.
I also tried (since it was complaining that there was no file in the pkg dir):
godoc -html -goroo=$GOPATH hello.go > hello.html
At the end, I gave up. I don't know how this godoc thing works. I installed the hello.go program so that I there was something in the pkg file in the workspace. How do you generate a webpage with your documentation for your code?
godoc operates on package and type names, not filenames.
For example, to learn about io/ioutil package:
text output: godoc io/ioutil
just the ReadAll function: godoc io/ioutil ReadAll
in HTML: godoc -html io/ioutil ReadAll
in the browser:
godoc -http=:6060
click Packages and navigate from there
or go directly to http://localhost:6060/pkg/io/ioutil#ReadAll
To view documentation for your own code, it has to be included in your GOPATH.
Suppose your GOPATH includes $HOME/go/src, and the file you are interested in is $HOME/go/src/hey/world/doc.go, you would run:
godoc hey/world
...or start godoc in HTTP mode and browse to http://localhost:6060/pkg/hey/world
By default, godoc looks at the packages it finds via $GOROOT and $GOPATH. So given that your package is in Go workspace i.e in GOPATH, you can run
godoc fmt
which prints out documentation for fmt package.
If you want to generate docs for your package foo which is in $GOPATH/src/github.com/abcd/foo location, you should run
godoc github.com/abcd/foo
With the -http flag, godoc runs as a web server and presents the documentation as a web page.
godoc -http=:6060
Now navigate to http://localhost:6060/pkg/github.com/abcd/foo in browser to find docs as web page.
The -play flag can be used to enable playground in web interface.
To show HTML doc generated for your own code
Step 1) At command line start up the document web server, that is:
C:\>godoc -http=:6060
Step 2) Open a browser and use an explicit url the folder your code is.
The URL structure comes from the folder names under your GOPATH.
For example:
If my GOPATH is c:\go and I have code in c:\go\src\myfolder\mysubfolder
The URL I would uses is http://localhost:6060/pkg/myfolder/mysubfolder and this would show an HTML page for the .go files in there
Also you can use URL http://localhost:6060/pkg/myfolder, which will have a link to mysubfolder
Notes:
I'm not sure how to see your local code at the the http://localhost:6060/pkg level, maybe you can't
It is possible to "specify additional paths" so I don't think it has to be the src folder, see https://blog.golang.org/godoc-documenting-go-code
Running godoc on its own worked for me, but was really slow because it
generates docs for every single package in the standard library, while I only
care about the local package that I am working on. To that end, if your package is in a folder called something, you can move
the folder so that it looks like this:
godoc/src/something
Then, go to the godoc folder, and run
godoc -goroot .
Then, browse to localhost:6060.
On linux, and assuming you have cd'd into the package of which you want to read the documentation.
if you are using go modules, you can run below command
godoc -http=:6060 & xdg-open http://localhost:6060/pkg/$(go list -m)
It uses the -m flag to get the package path even though the root module directory does not contain any .go file.
If you are not yet using modules, you can run,
godoc -http=:6060 & xdg-open http://localhost:6060/pkg/$(go list -f "{{.ImportPath}}")
Note that unlike -m this command will not work appropriately if there is no .go files into the directory.
Check the go list subcommand help at https://golang.org/pkg/cmd/go/internal/list/

Dajaxice not found on production server

I have a Django 1.4 project, running on Python 2.7 in which I'm using Dajaxice 0.5.4.1. I have set it up on my development machine (Windows 7) and everything works perfectly. However when I deploy my app to production server (Ubuntu 12.04) I get 404 error for dajaxice.core.js file and cannot resolve this problem no matter what. Production server works with exactly the same versions of all software.
My project structure looks like this:
/myproject
/myproject/myproject-static/ <-- all the static files are here
/myproject/myproject-static/css/
/myproject/myproject-static/img/
/myproject/myproject-static/js/
/myproject/templates/
/myproject/myproject/
/myproject/main/
/myproject/app1/
/myproject/app2/
/myproject/app3/
etc.
I was following the Dajaxice installation steps here and put everything in its place (in settings.py, ˙urls.pyandbase.html` files).
My settings.py file has also these values:
from unipath import Path
PROJECT_ROOT = Path(__file__).ancestor(3)
STATIC_ROOT = ''
STATIC_URL = '/myproject-static/'
STATICFILES_DIRS = (
PROJECT_ROOT.child('myproject-static'),
)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
'dajaxice.finders.DajaxiceFinder',
)
DAJAXICE_MEDIA_PREFIX = "dajaxice"
DAJAXICE_DEBUG = True
I have an Alias directive in my django.conf file which looks like this:
Alias /myproject-static/ "/path/to/myproject/myproject-static/"
I did collectstatic on my production server and got all static files collected within few folders in the root of my project. So, now when I look at my deployed web site, I can see that CSS is properly applied, JavaScript is working fine and navigation around the site works as intended. Everything is fine except Ajax is totally broken since dajaxice.core.js is never included.
My project folder structure after collecting static looks like this:
/myproject
/myproject/myproject-static/ <-- all the static files are originally here
/myproject/myproject-static/css/
/myproject/myproject-static/img/
/myproject/myproject-static/js/
/myproject/templates/
/myproject/admin/ <-- folder created with 'collectstatic' command
/myproject/css/ <-- folder created with 'collectstatic' command
/myproject/dajaxice/ <-- dajaxice.core.js is located here
/myproject/django_extensions/ <-- folder created with 'collectstatic' command
/myproject/img/ <-- folder created with 'collectstatic' command
/myproject/js/ <-- folder created with 'collectstatic' command
/myproject/myproject/
/myproject/main/
/myproject/app1/
/myproject/app2/
/myproject/app3/
etc.
Am I doing something completely wrong with my static files here?
What else should I try to fix this simple error?
Have you check if as the rest of the assets, dajaxice.core.js is inside your static/dajaxice folder? If not, the issue could be related with a miss configuration of the STATICFILES_FINDERS, check Installing dajaxice again
Another usual issue with collectstatic and dajaxice is to run the first using --link Are you using this option?
Hope this helps
I spend several hours grappling with this problem. It was crazy because everything worked great on my dev environment, but not on the test server even though all the dajax and dajaxice settings were on a common base settings file. I never got it to work using the standard route. But this is a very easy fix:
1) Download dajaxice.core.js into whatever static directory pleases you. You can find the js in your the dajaxice directory in your project root:
project/dajaxice/dajaxice.core.js
In my case, I put the file in static/js alongside all my other js libraries.
2) On your web page, replace this:
{% dajaxice_js_import %}
with a normal, everyday link to the js library. In my case:
<script src="/static/js/dajaxice.core.js" type="text/javascript"></script>
Unfortunately, this patch only works for developed code. If you usedo it in the development environment, new dajaxice code will be registered in the original project/dajaxice/ location and so the file will have to be copied to static after any new code is developed.

Resources