มีอัญมณีที่อัปโหลดไฟล์มากมายเช่น CarrierWave, Paperclip และ Dragonfly เป็นต้น พวกเขาทั้งหมดมีลักษณะเฉพาะของพวกเขา และคุณอาจเคยใช้อัญมณีเหล่านี้อย่างน้อยหนึ่งชิ้น
อย่างไรก็ตาม วันนี้ฉันอยากจะแนะนำวิธีการแก้ปัญหาที่ค่อนข้างใหม่แต่เจ๋งมากที่เรียกว่า Shrine ซึ่งสร้างโดย Janko Marohnić ตรงกันข้ามกับอัญมณีอื่นๆ ที่คล้ายคลึงกัน มันมีวิธีการแบบแยกส่วน หมายความว่าทุกฟีเจอร์ถูกบรรจุเป็นโมดูล (หรือ ปลั๊กอิน ในคำศัพท์ของศาลเจ้า) ต้องการสนับสนุนการตรวจสอบหรือไม่ เพิ่มปลั๊กอิน ต้องการประมวลผลไฟล์หรือไม่? เพิ่มปลั๊กอิน! ฉันชอบแนวทางนี้มากเพราะช่วยให้คุณควบคุมฟีเจอร์ที่จะใช้งานได้สำหรับรุ่นใดได้อย่างง่ายดาย
ในบทความนี้ผมจะแสดงวิธีการ:
- รวม Shrine เข้ากับแอปพลิเคชัน Rails
- กำหนดค่า (ทั่วโลกและต่อผู้อัปโหลด)
- เพิ่มความสามารถในการอัปโหลดไฟล์
- ประมวลผลไฟล์
- เพิ่มกฎการตรวจสอบ
- จัดเก็บข้อมูลเมตาเพิ่มเติมและใช้พื้นที่จัดเก็บไฟล์บนระบบคลาวด์ด้วย Amazon S3
ซอร์สโค้ดสำหรับบทความนี้มีอยู่ใน GitHub
สามารถดูการสาธิตการทำงานได้ที่นี่
บูรณาการศาลเจ้า
ในการเริ่มต้น ให้สร้างแอปพลิเคชัน Rails ใหม่โดยไม่มีชุดทดสอบเริ่มต้น:
เปิดตัว FileGuru -T ใหม่
ฉันจะใช้ Rails 5 สำหรับการสาธิตนี้ แต่แนวคิดส่วนใหญ่ใช้กับเวอร์ชัน 3 และ 4 ด้วยเช่นกัน
วางอัญมณีศาลเจ้าลงใน Gemfile ของคุณ:
อัญมณี "ศาลเจ้า"
จากนั้นเรียกใช้:
การติดตั้งมัด
ตอนนี้เราต้องการโมเดลที่จะเรียกว่า Photo
. Shrine เก็บข้อมูลที่เกี่ยวข้องกับไฟล์ทั้งหมดในคอลัมน์ข้อความพิเศษที่ลงท้ายด้วย _data
คำต่อท้าย สร้างและใช้การย้ายข้อมูลที่เกี่ยวข้อง:
rails g model ชื่อภาพ:string image_data:textrails db:migrate
โปรดทราบว่าสำหรับ Rails เวอร์ชันเก่า คำสั่งหลังควรเป็น:
rake db:migrate
ตัวเลือกการกำหนดค่าสำหรับ Shrine สามารถตั้งค่าได้ทั้งแบบสากลและแบบต่อรุ่น แน่นอนว่าการตั้งค่าส่วนกลางเสร็จสิ้นภายในไฟล์ตัวเริ่มต้น ฉันจะเชื่อมต่อไฟล์ที่จำเป็นและ ปลั๊กอิน . ปลั๊กอินถูกใช้ใน Shrine เพื่อแยกส่วนการทำงานออกเป็นโมดูลแยกกัน ทำให้คุณสามารถควบคุมคุณสมบัติทั้งหมดที่มีได้อย่างเต็มที่ ตัวอย่างเช่น มีปลั๊กอินสำหรับการตรวจสอบ การประมวลผลภาพ การแคชไฟล์แนบ และอื่นๆ อีกมากมาย
ในตอนนี้ ให้เพิ่มปลั๊กอินสองตัว:ตัวหนึ่งรองรับ ActiveRecord และอีกตัวสำหรับตั้งค่าการบันทึก พวกเขาจะรวมอยู่ในทั่วโลก ตั้งค่าที่เก็บข้อมูลระบบไฟล์ด้วย:
config/initializers/shrine.rb
require "shrine"require "shrine/storage/file_system"Shrine.plugin :activerecordShrine.plugin :logging, logger:Rails.loggerShrine.storages ={ แคช:Shrine::Storage::FileSystem.new("public", คำนำหน้า:"uploads/cache"), store:Shrine::Storage::FileSystem.new("public", prefix:"uploads/store"),}
Logger จะแสดงข้อมูลการดีบักบางอย่างภายในคอนโซลเพื่อให้คุณบอกว่าใช้เวลาประมวลผลไฟล์นานเท่าใด สิ่งนี้มีประโยชน์
2015-10-09T20:06:06.676Z #25602:STORE[แคช] ImageUploader[:avatar] ผู้ใช้[29543] 1 ไฟล์ (0.1 วินาที)2015-10-09T20:06:06.854Z #25602:กระบวนการ[ store]:ImageUploader[:avatar] User[29543] 1-3 files (0.22s)2015-10-09T20:06:07.133Z #25602:DELETE[destroyed]:ImageUploader[:avatar] User[29543] 3 ไฟล์ ( 0.07s)
ไฟล์ที่อัปโหลดทั้งหมดจะถูกเก็บไว้ใน สาธารณะ/อัปโหลด ไดเรกทอรี ฉันไม่ต้องการติดตามไฟล์เหล่านี้ใน Git ดังนั้นให้แยกโฟลเดอร์นี้:
.gitignore
สาธารณะ/อัปโหลด
ตอนนี้สร้างคลาส "ตัวอัปโหลด" พิเศษที่จะโฮสต์การตั้งค่าเฉพาะรุ่น สำหรับตอนนี้ คลาสนี้จะว่าง:
models/image_uploader.rb
คลาส ImageUploaderสุดท้าย รวมคลาสนี้ไว้ใน
Photo
รุ่น:รุ่น/photo.rb
รวม ImageUploader[:image]
[:image]
เพิ่มแอตทริบิวต์เสมือนที่จะใช้เมื่อสร้างแบบฟอร์ม บรรทัดด้านบนสามารถเขียนใหม่เป็น:รวม ImageUploader.attachment(:image) # หรือรวม ImageUploader::Attachment.new(:image)ดี! ตอนนี้โมเดลได้รับการติดตั้งฟังก์ชันของ Shrine แล้ว และเราสามารถไปยังขั้นตอนต่อไปได้
ตัวควบคุม มุมมอง และเส้นทาง
สำหรับจุดประสงค์ของการสาธิตนี้ เราจำเป็นต้องมีตัวควบคุมเพียงตัวเดียวในการจัดการรูปภาพ
index
หน้าจะทำหน้าที่เป็นรูท:pages_controller.rb
คลาส PhotosControllerมุมมอง:
views/photos/index.html.erb
รูปภาพ
<%=link_to 'เพิ่มรูปภาพ', new_photo_path %><%=render @photos %>เพื่อแสดงผล
@photos
อาร์เรย์ ต้องการบางส่วน:views/photos/_photo.html.erb
<% ถ้า photo.image_data? %> <%=image_tag photo.image_url %> <% สิ้นสุด %><%=photo.title %> | <%=link_to 'Edit', edit_photo_path(photo) %>
image_data?
เป็นวิธีการที่นำเสนอโดย ActiveRecord ที่ตรวจสอบว่าบันทึกมีภาพหรือไม่
image_url
เป็นวิธีการของ Shrine ที่คืนค่าเส้นทางไปยังภาพต้นฉบับ แน่นอน การแสดงภาพขนาดย่อเล็กๆ แทนจะดีกว่ามาก แต่เราจะดูแลในภายหลัง
เพิ่มเส้นทางที่จำเป็นทั้งหมด:
config/routes.rb
ทรัพยากร :photos เท่านั้น:[:new, :create, :index, :edit, :update] root 'photos#index'แค่นี้เอง รากฐานเสร็จแล้ว และเราสามารถไปยังส่วนที่น่าสนใจได้!
อัพโหลดไฟล์
ในส่วนนี้ ฉันจะแสดงวิธีเพิ่มฟังก์ชันการทำงานเพื่ออัปโหลดไฟล์จริง การทำงานของตัวควบคุมนั้นง่ายมาก:
photos_controller.rb
def new @photo =Photo.newenddef create @photo =Photo.new(photo_params) ถ้า @photo.save flash[:success] ='Photo added!' redirect_to photos_path อื่น ๆ ทำให้สิ้นสุด 'ใหม่'Gotcha เพียงอย่างเดียวคือสำหรับพารามิเตอร์ที่แข็งแกร่ง คุณต้องอนุญาต
image
แอตทริบิวต์เสมือน ไม่ใช่image_data
.photos_controller.rb
privatedef photo_params params.require(:photo).permit(:title, :image)endสร้าง
new
มุมมอง:views/photos/new.html.erb
เพิ่มรูปภาพ
<%=แสดง 'แบบฟอร์ม' %>บางส่วนของแบบฟอร์มก็ไม่สำคัญเช่นกัน:
views/photos/_form.html.erb
<%=form_for @photo do |f| %> <%=แสดงผล "แชร์/ข้อผิดพลาด" วัตถุ:@photo %> <%=f.label :title %> <%=f.text_field :title %> <%=f.label :image %> <% =f.file_field :image %> <%=f.submit %><% end %>ย้ำอีกครั้งว่าเรากำลังใช้
image
แอตทริบิวต์ ไม่ใช่image_data
.สุดท้าย เพิ่มอีกบางส่วนเพื่อแสดงข้อผิดพลาด:
views/shared/_errors.html.erb
<ก่อน><% ถ้า object.errors.any? %>พบข้อผิดพลาดต่อไปนี้:
<% object.errors.full_messages.each do |message| %>
<% สิ้นสุด %>- <%=ข้อความ %>
<% สิ้นสุด %>เท่านี้ก็เรียบร้อย—คุณสามารถเริ่มอัปโหลดภาพได้ทันที
การตรวจสอบความถูกต้อง
แน่นอนว่ายังต้องทำงานอีกมากเพื่อให้แอปสาธิตเสร็จสมบูรณ์ ปัญหาหลักคือผู้ใช้สามารถอัปโหลดไฟล์ประเภทใดก็ได้ที่มีขนาดใดก็ได้ ซึ่งไม่ได้ยอดเยี่ยมเป็นพิเศษ ดังนั้น เพิ่มปลั๊กอินอื่นเพื่อรองรับการตรวจสอบ:
config/inititalizers/shrine.rb
Shrine.plugin :validation_helpersตั้งค่าตรรกะการตรวจสอบสำหรับ
ImageUploader
:models/image_uploader.rb
Attacher.validate do validate_max_size 1.megabyte, message:" is too large (max is 1 MB)" validate_mime_type_inclusion ['image/jpg', 'image/jpeg', 'image/png']endฉันอนุญาตให้อัปโหลดเฉพาะรูปภาพ JPG และ PNG ที่น้อยกว่า 1MB ปรับกฎเหล่านี้ตามที่เห็นสมควร
ประเภท MIME
สิ่งสำคัญอีกประการที่ควรทราบคือโดยค่าเริ่มต้น Shrine จะกำหนดประเภท MIME ของไฟล์โดยใช้ส่วนหัว HTTP ประเภทเนื้อหา ส่วนหัวนี้ถูกส่งผ่านโดยเบราว์เซอร์และตั้งค่าตามนามสกุลของไฟล์เท่านั้น ซึ่งไม่เป็นที่ต้องการเสมอไป
หากคุณต้องการกำหนดประเภท MIME ตามเนื้อหาของไฟล์ ให้ใช้ปลั๊กอินที่เรียกว่า determine_mime_type ฉันจะรวมไว้ในคลาสตัวอัปโหลด เนื่องจากรุ่นอื่นๆ อาจไม่ต้องการฟังก์ชันนี้:
models/image_uploader.rb
ปลั๊กอิน :determine_mime_typeปลั๊กอินนี้จะใช้ยูทิลิตี้ไฟล์ของ Linux เป็นค่าเริ่มต้น
แคชรูปภาพที่แนบมา
ปัจจุบันเมื่อผู้ใช้ส่งแบบฟอร์มที่มีข้อมูลไม่ถูกต้อง แบบฟอร์มจะแสดงอีกครั้งโดยมีข้อผิดพลาดที่แสดงไว้ด้านบน อย่างไรก็ตาม ปัญหาคือ รูปภาพที่แนบมาจะสูญหาย และผู้ใช้จะต้องเลือกรูปภาพดังกล่าวอีกครั้ง ซึ่งแก้ไขได้ง่ายมากโดยใช้ปลั๊กอินอื่นที่เรียกว่า cached_attachment_data:
models/image_uploader.rb
ปลั๊กอิน :cached_attachment_dataเพียงเพิ่มฟิลด์ที่ซ่อนอยู่ในแบบฟอร์มของคุณ
views/photos/_form.html.erb
<%=f.hidden_field :image, ค่า:@photo.cached_image_data %><%=f.label :image %><%=f.file_field :image %>การแก้ไขรูปภาพ
ตอนนี้สามารถอัพโหลดรูปภาพได้ แต่ไม่มีวิธีแก้ไข ดังนั้นมาแก้ไขทันที การกระทำของผู้ควบคุมที่เกี่ยวข้องนั้นค่อนข้างเล็กน้อย:
photos_controller.rb
def edit @photo =Photo.find(params[:id])enddef update @photo =Photo.find(params[:id]) if @photo.update_attributes(photo_params) flash[:success] ='แก้ไขรูปภาพแล้ว !' redirect_to photos_path อื่น ๆ ทำให้ 'แก้ไข' สิ้นสุด
_form
เหมือนกัน บางส่วนจะถูกนำไปใช้:views/photos/edit.html.erb
แก้ไขรูปภาพ
<%=แสดง 'แบบฟอร์ม' %>ดีแต่ยังไม่พอ:ผู้ใช้ยังคงไม่สามารถลบภาพที่อัปโหลดได้ ในการอนุญาตนี้ เราจะต้อง—คาดเดาอะไร—ปลั๊กอินอื่น:
models/image_uploader.rb
ปลั๊กอิน :remove_attachmentใช้แอตทริบิวต์เสมือนที่เรียกว่า
:remove_image
ให้อนุญาตภายในคอนโทรลเลอร์:photos_controller.rb
def photo_params params.require(:photo).permit(:title, :image, :remove_image) สิ้นสุดตอนนี้เพียงแค่แสดงช่องทำเครื่องหมายเพื่อลบรูปภาพหากบันทึกมีสิ่งที่แนบมา:
views/photos/_form.html.erb
<% ถ้า @photo.image_data? %> ลบไฟล์แนบ:<%=f.check_box :remove_image %><% end %>การสร้างภาพขนาดย่อ
ขณะนี้เราแสดงภาพต้นฉบับซึ่งไม่ใช่วิธีที่ดีที่สุดสำหรับการแสดงตัวอย่าง:รูปภาพอาจมีขนาดใหญ่และใช้พื้นที่มากเกินไป แน่นอน คุณสามารถใช้ CSS
width
และheight
คุณลักษณะ แต่นั่นเป็นความคิดที่ไม่ดีเช่นกัน คุณเห็นไหมว่าแม้ว่ารูปภาพจะถูกตั้งค่าให้มีขนาดเล็กโดยใช้สไตล์ แต่ผู้ใช้ก็ยังต้องดาวน์โหลดไฟล์ต้นฉบับซึ่งอาจมีขนาดใหญ่มากดังนั้นจึงเป็นการดีกว่ามากที่จะสร้างภาพตัวอย่างขนาดเล็กบนฝั่งเซิร์ฟเวอร์ระหว่างการอัปโหลดครั้งแรก สิ่งนี้เกี่ยวข้องกับสองปลั๊กอินและสองอัญมณีเพิ่มเติม ประการแรก วางอัญมณี:
อัญมณี "image_processing" อัญมณี "mini_magick", ">=4.3.5"Image_processing เป็นอัญมณีพิเศษที่สร้างขึ้นโดยผู้เขียน Shrine นำเสนอวิธีการช่วยเหลือระดับสูงเพื่อจัดการรูปภาพ ในทางกลับกัน อัญมณีนี้อาศัย mini_magick ซึ่งเป็นเครื่องห่อหุ้ม Ruby สำหรับ ImageMagick อย่างที่คุณเดาได้ คุณจะต้องใช้ ImageMagick ในระบบของคุณเพื่อเรียกใช้การสาธิตนี้
ติดตั้งอัญมณีใหม่เหล่านี้:
การติดตั้งมัดตอนนี้รวมปลั๊กอินพร้อมกับการอ้างอิง:
models/image_uploader.rb
ต้องการ "image_processing/mini_magick" คลาส ImageUploaderการประมวลผลคือปลั๊กอินที่ช่วยให้เราจัดการรูปภาพได้ (เช่น ลดขนาด หมุน แปลงเป็นรูปแบบอื่น เป็นต้น) ในทางกลับกัน เวอร์ชันต่างๆ ช่วยให้เรามีรูปภาพในรูปแบบต่างๆ สำหรับการสาธิตนี้ สองเวอร์ชันจะถูกเก็บไว้:"ดั้งเดิม" และ "นิ้วหัวแม่มือ" (ปรับขนาดเป็น
300x300
)นี่คือรหัสสำหรับประมวลผลรูปภาพและจัดเก็บสองเวอร์ชัน:
รุ่น/image_uploader.rb
คลาส ImageUploader <กระบวนการ Shrine(:store) ทำ |io, บริบท| { ต้นฉบับ:io, thumb:resize_to_limit!(io.download, 300, 300) } สิ้นสุด
resize_to_limit!
เป็นวิธีการที่ให้ไว้โดย image_processing gem มันย่อขนาดรูปภาพให้เหลือ300x300
ถ้ามันใหญ่กว่าและไม่ทำอะไรเลยถ้ามันเล็กกว่า ยิ่งไปกว่านั้น ยังรักษาอัตราส่วนภาพตามต้นฉบับตอนนี้เมื่อแสดงรูปภาพ คุณเพียงแค่ใส่
:original
หรือ:thumb
อาร์กิวเมนต์ของimage_url
วิธีการ:views/photos/_photo.html.erb
<% ถ้า photo.image_data? %> <%=image_tag photo.image_url(:thumb) %> <% สิ้นสุด %><%=photo.title %> | <%=link_to 'Edit', edit_photo_path(photo) %>
เดียวกันสามารถทำได้ภายในแบบฟอร์ม:
views/photos/_form.html.erb
<% ถ้า @photo.image_data? %> <%=image_tag @photo.image_url(:thumb) %> ลบไฟล์แนบ:<%=f.check_box :remove_image %><% สิ้นสุด %>หากต้องการลบไฟล์ที่ประมวลผลโดยอัตโนมัติหลังจากอัปโหลดเสร็จแล้ว คุณสามารถเพิ่มปลั๊กอินชื่อ delete_raw:
models/image_uploader.rb
ปลั๊กอิน :delete_rawข้อมูลเมตาของรูปภาพ
นอกเหนือจากการแสดงภาพจริงแล้ว คุณยังสามารถดึงข้อมูลเมตาของภาพได้อีกด้วย ตัวอย่างเช่น ให้แสดงขนาดของภาพถ่ายต้นฉบับและประเภท MIME:
views/photos/_photo.html.erb
<% ถ้า photo.image_data? %> <%=image_tag photo.image_url(:thumb) %>ขนาด <%=photo.image[:original].size %> ไบต์
<% end %>
ประเภท MIME <%=photo.image[:original] mime_type %>
<%=photo.title %> | <%=link_to 'Edit', edit_photo_path(photo) %>
แล้วขนาดของมันล่ะ? น่าเสียดาย ที่ไม่ได้จัดเก็บไว้ตามค่าเริ่มต้น แต่เป็นไปได้ด้วยปลั๊กอินชื่อ store_dimensions
ขนาดของรูปภาพ
ปลั๊กอิน store_dimensions อาศัย fastimage gem ดังนั้นให้เชื่อมต่อทันที:
อัญมณี 'fastimage'อย่าลืมวิ่ง:
การติดตั้งมัดตอนนี้เพียงแค่รวมปลั๊กอิน:
models/image_uploader.rb
ปลั๊กอิน :store_dimensionsและแสดงขนาดโดยใช้
width
และheight
วิธีการ:views/photos/_photo.html.erb
<% ถ้า photo.image_data? %> <%=image_tag photo.image_url(:thumb) %>ขนาด <%=photo.image[:original].size %> ไบต์
<% สิ้นสุด %>
ประเภท MIME <%=photo.image[:original] mime_type %>
ขนาด <%="#{photo.image[:original].width}x#{photo.image[:original].height}" %><%=photo.title %> | <%=link_to 'Edit', edit_photo_path(photo) %>
นอกจากนี้ยังมี
dimensions
เมธอดที่ส่งคืนอาร์เรย์ที่มีความกว้างและความสูง (เช่น[500, 750]
)ย้ายไปยังคลาวด์
นักพัฒนามักเลือกบริการคลาวด์เพื่อโฮสต์ไฟล์ที่อัปโหลด และ Shrine ก็นำเสนอความเป็นไปได้ดังกล่าว ในส่วนนี้ ฉันจะแสดงวิธีอัปโหลดไฟล์ไปยัง Amazon S3
ในขั้นแรก ให้รวมอัญมณีอีกสองเม็ดไว้ใน Gemfile :
gem "aws-sdk", "~> 2.1"group :development do gem 'dotenv-rails'endต้องใช้ aws-sdk เพื่อทำงานกับ SDK ของ S3 ในขณะที่ dotenv-rails จะถูกใช้เพื่อจัดการตัวแปรสภาพแวดล้อมในการพัฒนา
การติดตั้งมัดก่อนดำเนินการต่อ คุณควรขอรับคู่คีย์เพื่อเข้าถึง S3 ผ่าน API ในการรับข้อมูล ให้ลงชื่อเข้าใช้ (หรือลงชื่อสมัครใช้) ไปที่ Amazon Web Services Console และไปที่ข้อมูลรับรองความปลอดภัย> ผู้ใช้ . สร้างผู้ใช้ที่มีสิทธิ์จัดการไฟล์บน S3 นี่คือนโยบายง่ายๆ ที่นำเสนอการเข้าถึง S3 อย่างเต็มรูปแบบ:
{ "เวอร์ชัน":"2016-11-14", "คำสั่ง":[ { "ผล":"อนุญาต", "การดำเนินการ":"s3:*", "ทรัพยากร":"*" } ]}ดาวน์โหลดคู่คีย์ของผู้ใช้ที่สร้างขึ้น หรือคุณอาจใช้คีย์การเข้าถึงรูท แต่ฉัน ไม่แนะนำอย่างยิ่ง คุณจากการทำเช่นนั้นเพราะมันไม่ปลอดภัยมาก
ถัดไป สร้างบัคเก็ต S3 เพื่อโฮสต์ไฟล์ของคุณและเพิ่มไฟล์ลงในรูทของโปรเจ็กต์เพื่อโฮสต์การกำหนดค่าของคุณ:
.env
S3_KEY=YOUR_KEYS3_SECRET=YOUR_SECRETS3_BUCKET=YOUR_BUCKETS3_REGION=YOUR_REGIONไม่เคยเปิดเผย ไฟล์นี้ต่อสาธารณะ และอย่าลืมยกเว้นจาก Git:
.gitignore
.envตอนนี้แก้ไขการกำหนดค่าส่วนกลางของ Shrine และแนะนำที่เก็บข้อมูลใหม่:
config/initializers/shrine.rb
require "shrine"require "shrine/storage/s3"s3_options ={ access_key_id:ENV['S3_KEY'], secret_access_key:ENV['S3_SECRET'], ภูมิภาค:ENV['S3_REGION'], ที่เก็บข้อมูล:ENV[' S3_BUCKET'],}Shrine.storages ={ แคช:Shrine::Storage::FileSystem.new("public" คำนำหน้า:"uploads/cache") ร้านค้า:Shrine::Storage::S3.new(prefix:" เก็บ", **s3_options),}แค่นั้นแหละ! ไม่ต้องทำการเปลี่ยนแปลงในส่วนอื่นๆ ของแอป และคุณสามารถทดสอบที่เก็บข้อมูลใหม่นี้ได้ทันที หากคุณได้รับข้อผิดพลาดจาก S3 ที่เกี่ยวข้องกับคีย์ที่ไม่ถูกต้อง ตรวจสอบให้แน่ใจว่าคุณได้คัดลอกคีย์และข้อมูลลับอย่างถูกต้อง โดยไม่มีช่องว่างต่อท้ายและสัญลักษณ์พิเศษที่มองไม่เห็น
บทสรุป
เรามาถึงจุดสิ้นสุดของบทความนี้แล้ว หวังว่าตอนนี้คุณจะรู้สึกมั่นใจมากในการใช้ Shrine และกระตือรือร้นที่จะใช้มันในโปรเจ็กต์ของคุณ เราได้พูดถึงคุณลักษณะหลายอย่างของอัญมณีนี้แล้ว แต่ยังมีอีกมากมาย เช่น ความสามารถในการจัดเก็บบริบทเพิ่มเติมพร้อมกับไฟล์และกลไกการอัปโหลดโดยตรง
ดังนั้น ให้เรียกดูเอกสารประกอบของ Shrine และเว็บไซต์อย่างเป็นทางการ ซึ่งอธิบายปลั๊กอินที่มีอยู่ทั้งหมดอย่างละเอียด หากคุณมีคำถามอื่นๆ เกี่ยวกับอัญมณีชิ้นนี้ อย่าลังเลที่จะโพสต์ไว้ ฉันขอขอบคุณที่อยู่กับฉัน แล้วพบกันใหม่!