Stable APIs for Go. https://go.code.as
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

234 lines
5.8 KiB

  1. package main
  2. import (
  3. "fmt"
  4. "html/template"
  5. "log"
  6. "net/http"
  7. "os"
  8. "sort"
  9. )
  10. const packageTemplateString = `<!DOCTYPE html>
  11. <html >
  12. <head>
  13. <meta charset="utf-8">
  14. <title>{{.Repo.PackageName}}.{{.Repo.MajorVersion}}{{.Repo.SubPath}} - {{.Repo.GopkgPath}}</title>
  15. <link href='//fonts.googleapis.com/css?family=Ubuntu+Mono|Ubuntu' rel='stylesheet' >
  16. <link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet" >
  17. <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet" >
  18. <style>
  19. html,
  20. body {
  21. height: 100%;
  22. }
  23. @media (min-width: 1200px) {
  24. .container {
  25. width: 970px;
  26. }
  27. }
  28. body {
  29. font-family: 'Ubuntu', sans-serif;
  30. }
  31. pre {
  32. font-family: 'Ubuntu Mono', sans-serif;
  33. }
  34. .main {
  35. padding-top: 20px;
  36. }
  37. .getting-started div {
  38. padding-top: 12px;
  39. }
  40. .getting-started p {
  41. font-size: 1.3em;
  42. }
  43. .getting-started pre {
  44. font-size: 15px;
  45. }
  46. .versions {
  47. font-size: 1.3em;
  48. }
  49. .versions div {
  50. padding-top: 5px;
  51. }
  52. .versions a {
  53. font-weight: bold;
  54. }
  55. .versions a.current {
  56. color: black;
  57. font-decoration: none;
  58. }
  59. /* wrapper for page content to push down footer */
  60. #wrap {
  61. min-height: 100%;
  62. height: auto !important;
  63. height: 100%;
  64. /* negative indent footer by it's height */
  65. margin: 0 auto -40px;
  66. }
  67. /* footer styling */
  68. #footer {
  69. height: 40px;
  70. background-color: #eee;
  71. padding-top: 8px;
  72. text-align: center;
  73. }
  74. /* footer fixes for mobile devices */
  75. @media (max-width: 767px) {
  76. #footer {
  77. margin-left: -20px;
  78. margin-right: -20px;
  79. padding-left: 20px;
  80. padding-right: 20px;
  81. }
  82. }
  83. </style>
  84. </head>
  85. <body>
  86. <script type="text/javascript">
  87. // If there's a URL fragment, assume it's an attempt to read a specific documentation entry.
  88. if (window.location.hash.length > 1) {
  89. window.location = "http://godoc.org/{{.Repo.GopkgPath}}" + window.location.hash;
  90. }
  91. </script>
  92. <div id="wrap" >
  93. <div class="container" >
  94. <div class="row" >
  95. <div class="col-sm-12" >
  96. <div class="page-header">
  97. <h1>{{.Repo.GopkgPath}}</h1>
  98. </div>
  99. </div>
  100. </div>
  101. <div class="row" >
  102. <div class="col-sm-12" >
  103. <a class="btn btn-lg btn-info" href="https://{{.Repo.GitHubRoot}}/tree/{{if .Repo.AllVersions}}{{.FullVersion}}{{else}}master{{end}}{{.Repo.SubPath}}" ><i class="fa fa-github"></i> Source Code</a>
  104. <a class="btn btn-lg btn-info" href="http://godoc.org/{{.Repo.GopkgPath}}" ><i class="fa fa-info-circle"></i> API Documentation</a>
  105. </div>
  106. </div>
  107. <div class="row main" >
  108. <div class="col-sm-8 info" >
  109. <div class="getting-started" >
  110. <h2>Getting started</h2>
  111. <div>
  112. <p>To get the package, execute:</p>
  113. <pre>go get {{.Repo.GopkgPath}}</pre>
  114. </div>
  115. <div>
  116. <p>To import this package, add the following line to your code:</p>
  117. <pre>import "{{.Repo.GopkgPath}}"</pre>
  118. {{if .CleanPackageName}}<p>Refer to it as <i>{{.Repo.PackageName}}</i>.{{end}}
  119. </div>
  120. <div>
  121. <p>For more details, see the API documentation.</p>
  122. </div>
  123. </div>
  124. </div>
  125. <div class="col-sm-3 col-sm-offset-1 versions" >
  126. <h2>Versions</h2>
  127. {{ if .LatestVersions }}
  128. {{ range .LatestVersions }}
  129. <div>
  130. <a href="//{{gopkgVersionRoot $.Repo .}}{{$.Repo.SubPath}}" {{if eq .Major $.Repo.MajorVersion.Major}}class="current"{{end}} >v{{.Major}}</a>
  131. &rarr;
  132. <span class="label label-default">{{.}}</span>
  133. </div>
  134. {{ end }}
  135. {{ else }}
  136. <div>
  137. <a href="//{{$.Repo.GopkgPath}}" class="current">v0</a>
  138. &rarr;
  139. <span class="label label-default">master</span>
  140. </div>
  141. {{ end }}
  142. </div>
  143. </div>
  144. </div>
  145. </div>
  146. <div id="footer">
  147. <div class="container">
  148. <div class="row">
  149. <div class="col-sm-12">
  150. <p class="text-muted credit"><a href="https://gopkg.in">gopkg.in<a></p>
  151. </div>
  152. </div>
  153. </div>
  154. </div>
  155. <!--<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>-->
  156. <!--<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>-->
  157. </body>
  158. </html>`
  159. var packageTemplate *template.Template
  160. func gopkgVersionRoot(repo *Repo, version Version) string {
  161. return repo.GopkgVersionRoot(version)
  162. }
  163. var packageFuncs = template.FuncMap{
  164. "gopkgVersionRoot": gopkgVersionRoot,
  165. }
  166. func init() {
  167. var err error
  168. packageTemplate, err = template.New("page").Funcs(packageFuncs).Parse(packageTemplateString)
  169. if err != nil {
  170. fmt.Fprintf(os.Stderr, "fatal: parsing package template failed: %s\n", err)
  171. os.Exit(1)
  172. }
  173. }
  174. type packageData struct {
  175. Repo *Repo
  176. LatestVersions VersionList // Contains only the latest version for each major
  177. FullVersion Version // Version that the major requested resolves to
  178. CleanPackageName bool
  179. }
  180. func renderPackagePage(resp http.ResponseWriter, req *http.Request, repo *Repo) {
  181. data := &packageData{
  182. Repo: repo,
  183. }
  184. latestVersionsMap := make(map[int]Version)
  185. for _, v := range repo.AllVersions {
  186. v2, exists := latestVersionsMap[v.Major]
  187. if !exists || v2.Less(v) {
  188. latestVersionsMap[v.Major] = v
  189. }
  190. }
  191. data.FullVersion = latestVersionsMap[repo.MajorVersion.Major]
  192. data.LatestVersions = make(VersionList, 0, len(latestVersionsMap))
  193. for _, v := range latestVersionsMap {
  194. data.LatestVersions = append(data.LatestVersions, v)
  195. }
  196. sort.Sort(sort.Reverse(data.LatestVersions))
  197. data.CleanPackageName = true
  198. for i, c := range repo.PackageName {
  199. if c < 'a' || c > 'z' {
  200. if i == 0 || c != '_' && (c < '0' || c > '9') {
  201. data.CleanPackageName = false
  202. break
  203. }
  204. }
  205. }
  206. err := packageTemplate.Execute(resp, data)
  207. if err != nil {
  208. log.Printf("error executing tmplPackage: %s\n", err)
  209. }
  210. }